[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