From 2d3faad706c81814abc5e4080df38c4bccde1d48 Mon Sep 17 00:00:00 2001 From: Igor Kudrin Date: Tue, 26 Feb 2019 12:15:14 +0000 Subject: [PATCH] [llvm-objdump] Implement -Mreg-names-raw/-std options. The --disassembler-options, or -M, are used to customize the disassembler and affect its output. The two implemented options allow selecting register names on ARM: * With -Mreg-names-raw, the disassembler uses rNN for all registers. * With -Mreg-names-std it prints sp, lr and pc for r13, r14 and r15, which is the default behavior of llvm-objdump. Differential Revision: https://reviews.llvm.org/D57680 llvm-svn: 354870 --- llvm/include/llvm/MC/MCInstPrinter.h | 4 ++++ llvm/include/llvm/Target/Target.td | 4 ++++ llvm/lib/Target/ARM/ARMRegisterInfo.td | 16 ++++++++++++---- llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 14 +++++++++++++- llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 9 ++++++++- llvm/test/tools/llvm-objdump/ARM/reg-names.s | 18 ++++++++++++++++++ llvm/tools/llvm-objdump/llvm-objdump.cpp | 13 +++++++++++++ llvm/utils/TableGen/AsmWriterEmitter.cpp | 19 ++++++++++++++----- 8 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/ARM/reg-names.s diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h index 916aa89..6bbc4bc 100644 --- a/llvm/include/llvm/MC/MCInstPrinter.h +++ b/llvm/include/llvm/MC/MCInstPrinter.h @@ -64,6 +64,10 @@ public: virtual ~MCInstPrinter(); + /// Customize the printer according to a command line option. + /// @return true if the option is recognized and applied. + virtual bool applyTargetSpecificCLOption(StringRef Opt) { return false; } + /// Specify a stream to emit comments to. void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index cbc97d6..f256f61 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -121,6 +121,10 @@ class ComposedSubRegIndex // this register class when printing. class RegAltNameIndex { string Namespace = ""; + + // A set to be used if the name for a register is not defined in this set. + // This allows creating name sets with only a few alternative names. + RegAltNameIndex FallbackRegAltNameIndex = ?; } def NoRegAltName : RegAltNameIndex; diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td index 668d374..d6ac723 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.td +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td @@ -13,7 +13,8 @@ include "ARMSystemRegister.td" //===----------------------------------------------------------------------===// // Registers are identified with 4-bit ID numbers. -class ARMReg Enc, string n, list subregs = []> : Register { +class ARMReg Enc, string n, list subregs = [], + list altNames = []> : Register { let HWEncoding = Enc; let Namespace = "ARM"; let SubRegs = subregs; @@ -26,6 +27,11 @@ class ARMFReg Enc, string n> : Register { let Namespace = "ARM"; } +let Namespace = "ARM", + FallbackRegAltNameIndex = NoRegAltName in { + def RegNamesRaw : RegAltNameIndex; +} + // Subregister indices. let Namespace = "ARM" in { def qqsub_0 : SubRegIndex<256>; @@ -83,9 +89,11 @@ def R9 : ARMReg< 9, "r9">, DwarfRegNum<[9]>; def R10 : ARMReg<10, "r10">, DwarfRegNum<[10]>; def R11 : ARMReg<11, "r11">, DwarfRegNum<[11]>; def R12 : ARMReg<12, "r12">, DwarfRegNum<[12]>; -def SP : ARMReg<13, "sp">, DwarfRegNum<[13]>; -def LR : ARMReg<14, "lr">, DwarfRegNum<[14]>; -def PC : ARMReg<15, "pc">, DwarfRegNum<[15]>; +let RegAltNameIndices = [RegNamesRaw] in { +def SP : ARMReg<13, "sp", [], ["r13"]>, DwarfRegNum<[13]>; +def LR : ARMReg<14, "lr", [], ["r14"]>, DwarfRegNum<[14]>; +def PC : ARMReg<15, "pc", [], ["r15"]>, DwarfRegNum<[15]>; +} } // Float registers diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index ee909f4..ec5fd16 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -72,8 +72,20 @@ ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) : MCInstPrinter(MAI, MII, MRI) {} +bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { + if (Opt == "reg-names-std") { + DefaultAltIdx = ARM::NoRegAltName; + return true; + } + if (Opt == "reg-names-raw") { + DefaultAltIdx = ARM::RegNamesRaw; + return true; + } + return false; +} + void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { - OS << markup(""); + OS << markup(""); } void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index b226633..bddcb8a 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -13,6 +13,7 @@ #ifndef LLVM_LIB_TARGET_ARM_INSTPRINTER_ARMINSTPRINTER_H #define LLVM_LIB_TARGET_ARM_INSTPRINTER_ARMINSTPRINTER_H +#include "MCTargetDesc/ARMMCTargetDesc.h" #include "llvm/MC/MCInstPrinter.h" namespace llvm { @@ -22,6 +23,8 @@ public: ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI); + bool applyTargetSpecificCLOption(StringRef Opt) override; + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override; void printRegName(raw_ostream &OS, unsigned RegNo) const override; @@ -35,7 +38,8 @@ public: unsigned PrintMethodIdx, const MCSubtargetInfo &STI, raw_ostream &O); - static const char *getRegisterName(unsigned RegNo); + static const char *getRegisterName(unsigned RegNo, + unsigned AltIdx = ARM::NoRegAltName); void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); @@ -235,6 +239,9 @@ public: template void printComplexRotationOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + +private: + unsigned DefaultAltIdx = ARM::NoRegAltName; }; } // end namespace llvm diff --git a/llvm/test/tools/llvm-objdump/ARM/reg-names.s b/llvm/test/tools/llvm-objdump/ARM/reg-names.s new file mode 100644 index 0000000..51f3dc33 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ARM/reg-names.s @@ -0,0 +1,18 @@ +@ RUN: llvm-mc %s -triple armv5-unknown-linux -filetype=obj -o %t +@ RUN: llvm-objdump -d %t | FileCheck -check-prefix=STD %s +@ RUN: llvm-objdump -d -Mreg-names-std %t \ +@ RUN: | FileCheck -check-prefix=STD %s +@ RUN: llvm-objdump -d --disassembler-options=reg-names-raw %t \ +@ RUN: | FileCheck -check-prefix=RAW %s +@ RUN: llvm-objdump -d -Mreg-names-raw,reg-names-std %t \ +@ RUN: | FileCheck -check-prefix=STD %s +@ RUN: llvm-objdump -d -Mreg-names-std,reg-names-raw %t \ +@ RUN: | FileCheck -check-prefix=RAW %s +@ RUN: not llvm-objdump -d -Munknown %t 2>&1 \ +@ RUN: | FileCheck -check-prefix=ERR %s +@ ERR: Unrecognized disassembler option: unknown + +.text + add r13, r14, r15 +@ STD: add sp, lr, pc +@ RAW: add r13, r14, r15 diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index e9d1545..914789f 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -293,6 +293,15 @@ cl::alias DisassembleZeroesShort("z", cl::NotHidden, cl::Grouping, cl::aliasopt(DisassembleZeroes)); +static cl::list + DisassemblerOptions("disassembler-options", + cl::desc("Pass target specific disassembler options"), + cl::value_desc("options"), cl::CommaSeparated); +static cl::alias + DisassemblerOptionsShort("M", cl::desc("Alias for --disassembler-options"), + cl::NotHidden, cl::Prefix, cl::CommaSeparated, + cl::aliasopt(DisassemblerOptions)); + static StringRef ToolName; typedef std::vector> SectionSymbolsTy; @@ -1473,6 +1482,10 @@ static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) { PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); SourcePrinter SP(Obj, TheTarget->getName()); + for (StringRef Opt : DisassemblerOptions) + if (!IP->applyTargetSpecificCLOption(Opt)) + error("Unrecognized disassembler option: " + Opt); + disassembleObject(TheTarget, Obj, Ctx, DisAsm.get(), MIA.get(), IP.get(), STI.get(), PIP, SP, InlineRelocs); } diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index 24e16f9..05d81f1 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -585,11 +585,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { O << " case "; if (!Namespace.empty()) O << Namespace << "::"; - O << AltName << ":\n" - << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName - << "[RegNo-1]) &&\n" - << " \"Invalid alt name index for register!\");\n" - << " return AsmStrs" << AltName << "+RegAsmOffset" << AltName + O << AltName << ":\n"; + if (R->isValueUnset("FallbackRegAltNameIndex")) + O << " assert(*(AsmStrs" << AltName << "+RegAsmOffset" << AltName + << "[RegNo-1]) &&\n" + << " \"Invalid alt name index for register!\");\n"; + else { + O << " if (!*(AsmStrs" << AltName << "+RegAsmOffset" << AltName + << "[RegNo-1]))\n" + << " return getRegisterName(RegNo, "; + if (!Namespace.empty()) + O << Namespace << "::"; + O << R->getValueAsDef("FallbackRegAltNameIndex")->getName() << ");\n"; + } + O << " return AsmStrs" << AltName << "+RegAsmOffset" << AltName << "[RegNo-1];\n"; } O << " }\n"; -- 2.7.4