[llvm-branch-commits] [llvm] 34385c2 - [Xtensa] Add basic Xtensa instruction printer.
Andrei Safronov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 11 15:40:15 PDT 2020
Author: Andrei Safronov
Date: 2020-07-21T13:25:50+03:00
New Revision: 34385c2abb851926b88160a10cf05792c255e20a
URL: https://github.com/llvm/llvm-project/commit/34385c2abb851926b88160a10cf05792c255e20a
DIFF: https://github.com/llvm/llvm-project/commit/34385c2abb851926b88160a10cf05792c255e20a.diff
LOG: [Xtensa] Add basic Xtensa instruction printer.
Add instruction printer and basic tests of the
Xtensa instructions.
Added:
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
llvm/test/MC/Xtensa/elf-header.s
llvm/test/MC/Xtensa/lit.local.cfg
llvm/test/MC/Xtensa/xtensa-invalid.s
llvm/test/MC/Xtensa/xtensa-valid.s
Modified:
llvm/lib/Target/Xtensa/CMakeLists.txt
llvm/lib/Target/Xtensa/LLVMBuild.txt
llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
llvm/lib/Target/Xtensa/Xtensa.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 67b79b18ba38..d2bdea4cb0f9 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_TARGET_DEFINITIONS Xtensa.td)
tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
+tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM XtensaGenRegisterInfo.inc -gen-register-info)
diff --git a/llvm/lib/Target/Xtensa/LLVMBuild.txt b/llvm/lib/Target/Xtensa/LLVMBuild.txt
index e1577083ca01..360a01479840 100644
--- a/llvm/lib/Target/Xtensa/LLVMBuild.txt
+++ b/llvm/lib/Target/Xtensa/LLVMBuild.txt
@@ -22,10 +22,11 @@ type = TargetGroup
name = Xtensa
parent = Target
has_asmparser = 1
+has_asmprinter = 1
[component_1]
type = Library
name = XtensaCodeGen
parent = Xtensa
-required_libraries = CodeGen Core XtensaInfo Support Target
+required_libraries = AsmPrinter CodeGen Core MC XtensaDesc XtensaInfo Support Target
add_to_library_groups = Xtensa
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
index ee905f70136a..c1a06f35f6b7 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMXtensaDesc
XtensaAsmBackend.cpp
XtensaELFObjectWriter.cpp
+ XtensaInstPrinter.cpp
XtensaMCAsmInfo.cpp
XtensaMCCodeEmitter.cpp
XtensaMCTargetDesc.cpp
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
new file mode 100644
index 000000000000..7cd363ac4314
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -0,0 +1,105 @@
+//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints an Xtensa MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XtensaInstPrinter.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "asm-printer"
+
+#include "XtensaGenAsmWriter.inc"
+
+static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
+ int Offset = 0;
+ const MCSymbolRefExpr *SRE;
+
+ if (!(SRE = dyn_cast<MCSymbolRefExpr>(Expr)))
+ assert(false && "Unexpected MCExpr type.");
+
+ MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
+
+ switch (Kind) {
+ case MCSymbolRefExpr::VK_None:
+ break;
+ // TODO
+ default:
+ llvm_unreachable("Invalid kind!");
+ }
+
+ OS << SRE->getSymbol();
+
+ if (Offset) {
+ if (Offset > 0)
+ OS << '+';
+ OS << Offset;
+ }
+
+ if (Kind != MCSymbolRefExpr::VK_None)
+ OS << ')';
+}
+
+void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) {
+ if (MC.isReg())
+ O << getRegisterName(MC.getReg());
+ else if (MC.isImm())
+ O << MC.getImm();
+ else if (MC.isExpr())
+ printExpr(MC.getExpr(), O);
+ else
+ llvm_unreachable("Invalid operand");
+}
+
+void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ printInstruction(MI, Address, O);
+ printAnnotation(O, Annot);
+}
+
+void XtensaInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
+ O << getRegisterName(RegNo);
+}
+
+void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ printOperand(MI->getOperand(OpNum), O);
+}
+
+void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+ assert((Value >= -128 && Value <= 127) &&
+ "Invalid argument, value must be in ranges [-128,127]");
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
+
+void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+ assert((Value >= -32768 && Value <= 32512 && ((Value & 0xFF) == 0)) &&
+ "Invalid argument, value must be multiples of 256 in range "
+ "[-32768,32512]");
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
new file mode 100644
index 000000000000..8c6cb677734c
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -0,0 +1,51 @@
+//===- XtensaInstPrinter.h - Convert Xtensa MCInst to asm syntax -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints an Xtensa MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H
+#define LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H
+
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+class MCOperand;
+
+class XtensaInstPrinter : public MCInstPrinter {
+public:
+ XtensaInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI)
+ : MCInstPrinter(MAI, MII, MRI) {}
+
+ // Automatically generated by tblgen.
+ void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
+ static const char *getRegisterName(unsigned RegNo);
+
+ // Print the given operand.
+ static void printOperand(const MCOperand &MO, raw_ostream &O);
+
+ // Override MCInstPrinter.
+ void printRegName(raw_ostream &O, unsigned RegNo) const override;
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &O) override;
+
+private:
+ // Print various types of operand.
+ void printOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+
+ void printImm8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+};
+} // end namespace llvm
+
+#endif /* LLVM_LIB_TARGET_XTENSA_MCTARGETDESC_XTENSAINSTPRINTER_H */
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 4a9dd130cce2..3f4982a7ef84 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -8,6 +8,7 @@
//
//===----------------------------------------------------------------------===//
#include "XtensaMCTargetDesc.h"
+#include "XtensaInstPrinter.h"
#include "XtensaMCAsmInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -24,6 +25,9 @@
#define GET_REGINFO_MC_DESC
#include "XtensaGenRegisterInfo.inc"
+#define GET_SUBTARGETINFO_MC_DESC
+#include "XtensaGenSubtargetInfo.inc"
+
using namespace llvm;
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
@@ -39,12 +43,25 @@ static MCInstrInfo *createXtensaMCInstrInfo() {
return X;
}
+static MCInstPrinter *createXtensaMCInstPrinter(const Triple &TT,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ return new XtensaInstPrinter(MAI, MII, MRI);
+}
+
static MCRegisterInfo *createXtensaMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitXtensaMCRegisterInfo(X, Xtensa::SP);
return X;
}
+static MCSubtargetInfo *
+createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+ return createXtensaMCSubtargetInfoImpl(TT, CPU, FS);
+}
+
extern "C" void LLVMInitializeXtensaTargetMC() {
// Register the MCAsmInfo.
TargetRegistry::RegisterMCAsmInfo(TheXtensaTarget, createXtensaMCAsmInfo);
@@ -56,10 +73,18 @@ extern "C" void LLVMInitializeXtensaTargetMC() {
// Register the MCInstrInfo.
TargetRegistry::RegisterMCInstrInfo(TheXtensaTarget, createXtensaMCInstrInfo);
+ // Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(TheXtensaTarget,
+ createXtensaMCInstPrinter);
+
// Register the MCRegisterInfo.
TargetRegistry::RegisterMCRegInfo(TheXtensaTarget,
createXtensaMCRegisterInfo);
+ // Register the MCSubtargetInfo.
+ TargetRegistry::RegisterMCSubtargetInfo(TheXtensaTarget,
+ createXtensaMCSubtargetInfo);
+
// Register the MCAsmBackend.
TargetRegistry::RegisterMCAsmBackend(TheXtensaTarget,
createXtensaMCAsmBackend);
diff --git a/llvm/lib/Target/Xtensa/Xtensa.td b/llvm/lib/Target/Xtensa/Xtensa.td
index f6891531362a..65d2945d1f90 100644
--- a/llvm/lib/Target/Xtensa/Xtensa.td
+++ b/llvm/lib/Target/Xtensa/Xtensa.td
@@ -51,8 +51,16 @@ def XtensaAsmParser : AsmParser {
let ShouldEmitMatchRegisterAltName = 1;
}
+def XtensaInstPrinter : AsmWriter
+{
+ string AsmWriterClassName = "InstPrinter";
+ bit isMCAsmWriter = 1;
+}
+
def Xtensa : Target
{
let InstructionSet = XtensaInstrInfo;
+ let AssemblyWriters = [XtensaInstPrinter];
let AssemblyParsers = [XtensaAsmParser];
}
+
diff --git a/llvm/test/MC/Xtensa/elf-header.s b/llvm/test/MC/Xtensa/elf-header.s
new file mode 100644
index 000000000000..18d6cc0ebe95
--- /dev/null
+++ b/llvm/test/MC/Xtensa/elf-header.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc %s -filetype=obj -triple=xtensa | llvm-readobj -h \
+# RUN: | FileCheck -check-prefix=Xtensa %s
+
+# Xtensa: Format: ELF32-Xtensa
+# Xtensa: Arch: xtensa
+# Xtensa: AddressSize: 32bit
+# Xtensa: ElfHeader {
+# Xtensa: Ident {
+# Xtensa: Magic: (7F 45 4C 46)
+# Xtensa: Class: 32-bit (0x1)
+# Xtensa: DataEncoding: LittleEndian (0x1)
+# Xtensa: FileVersion: 1
+# Xtensa: OS/ABI: SystemV (0x0)
+# Xtensa: ABIVersion: 0
+# Xtensa: Unused: (00 00 00 00 00 00 00)
+# Xtensa: }
+# Xtensa: Type: Relocatable (0x1)
+# Xtensa: Machine: EM_XTENSA (0x5E)
+# Xtensa: Version: 1
+# Xtensa: Entry: 0x0
+# Xtensa: ProgramHeaderOffset: 0x0
+# Xtensa: SectionHeaderOffset: 0x5C
+# Xtensa: Flags [ (0x0)
+# Xtensa: ]
+# Xtensa: HeaderSize: 52
+# Xtensa: ProgramHeaderEntrySize: 0
+# Xtensa: ProgramHeaderCount: 0
+# Xtensa: SectionHeaderEntrySize: 40
+# Xtensa: SectionHeaderCount: 4
+# Xtensa: StringTableSectionIndex: 1
+# Xtensa: }
diff --git a/llvm/test/MC/Xtensa/lit.local.cfg b/llvm/test/MC/Xtensa/lit.local.cfg
new file mode 100644
index 000000000000..9e0be9979305
--- /dev/null
+++ b/llvm/test/MC/Xtensa/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'Xtensa' in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/test/MC/Xtensa/xtensa-invalid.s b/llvm/test/MC/Xtensa/xtensa-invalid.s
new file mode 100644
index 000000000000..86f4ff2e4c4b
--- /dev/null
+++ b/llvm/test/MC/Xtensa/xtensa-invalid.s
@@ -0,0 +1,31 @@
+# RUN: not llvm-mc -triple xtensa < %s 2>&1 | FileCheck %s
+
+# Out of range immediates
+
+LBL0:
+
+# imm8
+addi a1, a2, 300
+# CHECK: error: expected immediate in range [-128, 127]
+
+addi a1, a2, -129
+# CHECK: error: expected immediate in range [-128, 127]
+
+# imm8_sh8
+addmi a1, a2, 33
+# CHECK: error: expected immediate in range [-32768, 32512], first 8 bits should be zero
+
+# Invalid number of operands
+addi a1, a2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
+addi a1, a2, 4, 4 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction
+
+# Invalid mnemonics
+aaa a10, a12 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
+
+# Invalid register names
+addi a101, sp, 10 # CHECK: :[[@LINE]]:6: error: invalid operand for instruction
+or r2, sp, a3 # CHECK: :[[@LINE]]:4: error: invalid operand for instruction
+
+# Invalid operand types
+and sp, a2, 10 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
+addi sp, a1, a2 # CHECK: :[[@LINE]]:14: error: expected immediate in range [-128, 127]
diff --git a/llvm/test/MC/Xtensa/xtensa-valid.s b/llvm/test/MC/Xtensa/xtensa-valid.s
new file mode 100644
index 000000000000..e50ad17babd0
--- /dev/null
+++ b/llvm/test/MC/Xtensa/xtensa-valid.s
@@ -0,0 +1,104 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+
+.align 4
+LBL0:
+
+# CHECK-INST: abs a5, a6
+# CHECK: encoding: [0x60,0x51,0x60]
+ abs a5, a6
+
+# CHECK-INST: add a3, a9, a4
+# CHECK: encoding: [0x40,0x39,0x80]
+ add a3, a9, a4
+# CHECK-INST: add a15, a9, a1
+# CHECK: encoding: [0x10,0xf9,0x80]
+ add a15, a9, sp
+
+# CHECK-INST: addi a8, a1, -128
+# CHECK: encoding: [0x82,0xc1,0x80]
+ addi a8, sp, -128
+# CHECK-INST: addi a8, a1, -12
+# CHECK: encoding: [0x82,0xc1,0xf4]
+ addi a8, a1, -12
+
+# CHECK-INST: addmi a1, a2, 32512
+# CHECK: encoding: [0x12,0xd2,0x7f]
+ addmi a1, a2, 32512
+
+# CHECK-INST: addx2 a2, a1, a5
+# CHECK: encoding: [0x50,0x21,0x90]
+ addx2 a2, sp, a5
+# CHECK-INST: addx4 a3, a1, a6
+# CHECK: encoding: [0x60,0x31,0xa0]
+ addx4 a3, sp, a6
+# CHECK-INST: addx8 a4, a1, a7
+# CHECK: encoding: [0x70,0x41,0xb0]
+ addx8 a4, sp, a7
+
+# CHECK-INST: dsync
+# CHECK: encoding: [0x30,0x20,0x00]
+ dsync
+# CHECK-INST: esync
+# CHECK: encoding: [0x20,0x20,0x00]
+ esync
+
+# CHECK-INST: extw
+# CHECK: encoding: [0xd0,0x20,0x00]
+ extw
+
+# CHECK-INST: isync
+# CHECK: encoding: [0x00,0x20,0x00]
+ isync
+
+# CHECK-INST: memw
+# CHECK: encoding: [0xc0,0x20,0x00]
+ memw
+
+# CHECK-INST: moveqz a2, a3, a4
+# CHECK: encoding: [0x40,0x23,0x83]
+ moveqz a2,a3,a4
+# CHECK-INST: movgez a3, a11, a12
+# CHECK: encoding: [0xc0,0x3b,0xb3]
+ movgez a3,a11,a12
+
+# CHECK-INST: movltz a7, a8, a9
+# CHECK: encoding: [0x90,0x78,0xa3]
+ movltz a7, a8, a9
+# CHECK-INST: movnez a10, a11, a12
+# CHECK: encoding: [0xc0,0xab,0x93]
+ movnez a10,a11, a12
+
+# CHECK-INST: neg a1, a3
+# CHECK: encoding: [0x30,0x10,0x60]
+ neg a1, a3
+
+# CHECK-INST: nop
+# CHECK: encoding: [0xf0,0x20,0x00]
+ nop
+
+# CHECK-INST: or a4, a5, a6
+# CHECK: encoding: [0x60,0x45,0x20]
+ or a4, a5, a6
+
+# CHECK-INST: rsync
+# CHECK: encoding: [0x10,0x20,0x00]
+ rsync
+
+# CHECK-INST: sub a8, a2, a1
+# CHECK: encoding: [0x10,0x82,0xc0]
+ sub a8, a2, a1
+# CHECK-INST: subx2 a2, a1, a5
+# CHECK: encoding: [0x50,0x21,0xd0]
+ subx2 a2, sp, a5
+# CHECK-INST: subx4 a3, a1, a6
+# CHECK: encoding: [0x60,0x31,0xe0]
+ subx4 a3, sp, a6
+# CHECK-INST: subx8 a4, a1, a7
+# CHECK: encoding: [0x70,0x41,0xf0]
+ subx8 a4, sp, a7
+
+# CHECK-INST: xor a6, a4, a5
+# CHECK: encoding: [0x50,0x64,0x30]
+ xor a6, a4, a5
More information about the llvm-branch-commits
mailing list