diff options
author | Fangrui Song <maskray@google.com> | 2020-03-22 12:32:27 -0700 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2020-03-26 08:21:15 -0700 |
commit | 5fad05e80dd05ac267c0d5d753a5b95b6201bac9 (patch) | |
tree | 431d363dcad6d1aaa9e4e94c3706f2ae8b9f4ca1 /llvm | |
parent | b9943d68d3c7b354f40a618ece2bf7906688b057 (diff) | |
download | llvm-5fad05e80dd05ac267c0d5d753a5b95b6201bac9.zip llvm-5fad05e80dd05ac267c0d5d753a5b95b6201bac9.tar.gz llvm-5fad05e80dd05ac267c0d5d753a5b95b6201bac9.tar.bz2 |
[MCInstPrinter] Pass `Address` parameter to MCOI::OPERAND_PCREL typed operands. NFC
Follow-up of D72172 and D72180
This patch passes `uint64_t Address` to print methods of PC-relative
operands so that subsequent target specific patches can change
`*InstPrinter::print{Operand,PCRelImm,...}` to customize the output.
Add MCInstPrinter::PrintBranchImmAsAddress which is set to true by
llvm-objdump.
```
// Current llvm-objdump -d output
aarch64: 20000: bl #0
ppc: 20000: bl .+4
x86: 20000: callq 0
// Ideal output
aarch64: 20000: bl 0x20000
ppc: 20000: bl 0x20004
x86: 20000: callq 0x20005
// GNU objdump -d. The lack of 0x is not ideal because the result cannot be re-assembled
aarch64: 20000: bl 20000
ppc: 20000: bl 0x20004
x86: 20000: callq 20005
```
In `lib/Target/X86/X86GenAsmWriter1.inc` (generated by `llvm-tblgen -gen-asm-writer`):
```
case 12:
// CALL64pcrel32, CALLpcrel16, CALLpcrel32, EH_SjLj_Setup, JCXZ, JECXZ, J...
- printPCRelImm(MI, 0, O);
+ printPCRelImm(MI, Address, 0, O);
return;
```
Some targets have 2 `printOperand` overloads, one without `Address` and
one with `Address`. They should annotate derived `Operand` properly with
`let OperandType = "OPERAND_PCREL"`.
Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D76574
Diffstat (limited to 'llvm')
17 files changed, 80 insertions, 17 deletions
diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h index 0df658a..d466749 100644 --- a/llvm/include/llvm/MC/MCInstPrinter.h +++ b/llvm/include/llvm/MC/MCInstPrinter.h @@ -58,6 +58,11 @@ protected: /// Which style to use for printing hexadecimal values. HexStyle::Style PrintHexStyle = HexStyle::C; + /// If true, a branch immediate (e.g. bl 4) will be printed as a hexadecimal + /// address (e.g. bl 0x20004). This is useful for a stream disassembler + /// (llvm-objdump -d). + bool PrintBranchImmAsAddress = false; + /// Utility function for printing annotations. void printAnnotation(raw_ostream &OS, StringRef Annot); @@ -100,6 +105,10 @@ public: void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; } + void setPrintBranchImmAsAddress(bool Value) { + PrintBranchImmAsAddress = Value; + } + /// Utility function to print immediates in decimal or hex. format_object<int64_t> formatImm(int64_t Value) const { return PrintImmHex ? formatHex(Value) : formatDec(Value); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp index 06dfbaa..80d989f 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1347,7 +1347,8 @@ void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, O << "[" << MI->getOperand(OpNum).getImm() << "]"; } -void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, unsigned OpNum, +void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address, + unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); @@ -1362,10 +1363,9 @@ void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, unsigned OpNum, // If the branch target is simply an address then print it in hex. const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(MI->getOperand(OpNum).getExpr()); - int64_t Address; - if (BranchTarget && BranchTarget->evaluateAsAbsolute(Address)) { - O << "0x"; - O.write_hex(Address); + int64_t TargetAddress; + if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) { + O << formatHex(TargetAddress); } else { // Otherwise, just print the expression. MI->getOperand(OpNum).getExpr()->print(O, &MAI); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h index 62613e9..faba09f 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -100,7 +100,7 @@ protected: const MCSubtargetInfo &STI, raw_ostream &O); void printInverseCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); - void printAlignedLabel(const MCInst *MI, unsigned OpNum, + void printAlignedLabel(const MCInst *MI, uint64_t Address, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); void printUImm12Offset(const MCInst *MI, unsigned OpNum, unsigned Scale, raw_ostream &O); diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h index 90a78a9..be61e3b 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h @@ -115,6 +115,10 @@ private: raw_ostream &O); void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { + printOperand(MI, OpNum, STI, O); + } void printOperandAndFPInputMods(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printOperandAndIntInputMods(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h index 53ca406..266f2de 100644 --- a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h @@ -36,6 +36,10 @@ public: private: void printMemOperandRI(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, + raw_ostream &O) { + printOperand(MI, OpNum, O); + } void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h index eba57a8..053f232 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h @@ -43,6 +43,10 @@ public: void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O) { + printOperand(MI, OpNum, STI, O); + } void printSORegRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); @@ -109,6 +113,12 @@ public: template <unsigned scale> void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template <unsigned scale> + void printAdrLabelOperand(const MCInst *MI, uint64_t /*Address*/, + unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { + printAdrLabelOperand<scale>(MI, OpNum, STI, O); + } void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); void printThumbSRImm(const MCInst *MI, unsigned OpNum, @@ -206,6 +216,11 @@ public: const MCSubtargetInfo &STI, raw_ostream &O); void printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printThumbLdrLabelOperand(const MCInst *MI, uint64_t /*Address*/, + unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O) { + printThumbLdrLabelOperand(MI, OpNum, STI, O); + } void printFBits16(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); void printFBits32(const MCInst *MI, unsigned OpNum, diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h index 247e9fc..96c64f1 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h @@ -38,6 +38,10 @@ private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPCRelImm(const MCInst *MI, uint64_t /*Address*/, unsigned OpNo, + raw_ostream &O) { + printPCRelImm(MI, OpNo, O); + } void printMemri(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by TableGen. diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h index 0b1ee80..f267146 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h @@ -92,6 +92,10 @@ public: private: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, + raw_ostream &O) { + printOperand(MI, OpNum, O); + } template <unsigned Bits, unsigned Offset = 0> void printUImm(const MCInst *MI, int opNum, raw_ostream &O); void printMemOperand(const MCInst *MI, int opNum, raw_ostream &O); diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h index 15d9c70..93ac2ce 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -65,6 +65,10 @@ public: void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printImmZeroOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printBranchOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNo, + raw_ostream &O) { + printBranchOperand(MI, OpNo, O); + } void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp index 5893b22..fac363c 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp @@ -155,7 +155,8 @@ void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum, MO.getExpr()->print(O, &MAI); } -void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum, +void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, + uint64_t Address, int OpNum, raw_ostream &O) { // Output the PC-relative operand. printPCRelOperand(MI, OpNum, O); diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h index 5628e92..cfe1bd8 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h @@ -46,6 +46,10 @@ public: private: // Print various types of operand. void printOperand(const MCInst *MI, int OpNum, raw_ostream &O); + void printOperand(const MCInst *MI, uint64_t /*Address*/, unsigned OpNum, + raw_ostream &O) { + printOperand(MI, OpNum, O); + } void printBDAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printBDXAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printBDLAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O); @@ -65,7 +69,12 @@ private: void printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printU48ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printPCRelOperand(const MCInst *MI, int OpNum, raw_ostream &O); - void printPCRelTLSOperand(const MCInst *MI, int OpNum, raw_ostream &O); + void printPCRelOperand(const MCInst *MI, uint64_t /*Address*/, int OpNum, + raw_ostream &O) { + printPCRelOperand(MI, OpNum, O); + } + void printPCRelTLSOperand(const MCInst *MI, uint64_t Address, int OpNum, + raw_ostream &O); // Print the mnemonic for a condition-code mask ("ne", "lh", etc.) // This forms part of the instruction name rather than the operand list. diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp index 675a9c3..79bb1db 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp @@ -56,7 +56,7 @@ void X86ATTInstPrinter::printInst(const MCInst *MI, uint64_t Address, if (MI->getOpcode() == X86::CALLpcrel32 && (STI.getFeatureBits()[X86::Mode64Bit])) { OS << "\tcallq\t"; - printPCRelImm(MI, 0, OS); + printPCRelImm(MI, Address, 0, OS); } // data16 and data32 both have the same encoding of 0x66. While data32 is // valid only in 16 bit systems, data16 is valid in the rest. diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp index a215550..6f27808 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp @@ -291,8 +291,8 @@ void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op, /// being encoded as a pc-relative value (e.g. for jumps and calls). In /// Intel-style these print slightly differently than normal immediates. /// for example, a $ is not emitted. -void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, unsigned OpNo, - raw_ostream &O) { +void X86InstPrinterCommon::printPCRelImm(const MCInst *MI, uint64_t Address, + unsigned OpNo, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNo); if (Op.isImm()) O << formatImm(Op.getImm()); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.h b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.h index 8e28f24..bb12ede 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.h @@ -29,7 +29,9 @@ public: void printVPCMPMnemonic(const MCInst *MI, raw_ostream &OS); void printCMPMnemonic(const MCInst *MI, bool IsVCmp, raw_ostream &OS); void printRoundingControl(const MCInst *MI, unsigned Op, raw_ostream &O); - void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printPCRelImm(const MCInst *MI, uint64_t Address, unsigned OpNo, + raw_ostream &O); + protected: void printInstFlags(const MCInst *MI, raw_ostream &O); void printOptionalSegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp index 768ddfe..e9cd34e 100644 --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1635,6 +1635,7 @@ static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) { reportError(Obj->getFileName(), "no instruction printer for target " + TripleName); IP->setPrintImmHex(PrintImmHex); + IP->setPrintBranchImmAsAddress(true); PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); SourcePrinter SP(Obj, TheTarget->getName()); diff --git a/llvm/utils/TableGen/AsmWriterInst.cpp b/llvm/utils/TableGen/AsmWriterInst.cpp index c26e0e4..24d29ff 100644 --- a/llvm/utils/TableGen/AsmWriterInst.cpp +++ b/llvm/utils/TableGen/AsmWriterInst.cpp @@ -36,6 +36,8 @@ std::string AsmWriterOperand::getCode(bool PassSubtarget) const { return Str; std::string Result = Str + "(MI"; + if (PCRel) + Result += ", Address"; if (MIOpNo != ~0U) Result += ", " + utostr(MIOpNo); if (PassSubtarget) @@ -179,7 +181,9 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned CGIIndex, CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo]; unsigned MIOp = OpInfo.MIOperandNo; - Operands.emplace_back(OpInfo.PrinterMethodName, MIOp, Modifier); + Operands.emplace_back(OpInfo.PrinterMethodName, MIOp, Modifier, + AsmWriterOperand::isMachineInstrOperand, + OpInfo.OperandType == "MCOI::OPERAND_PCREL"); } LastEmitted = VarEnd; } diff --git a/llvm/utils/TableGen/AsmWriterInst.h b/llvm/utils/TableGen/AsmWriterInst.h index a59112e..366c9ec 100644 --- a/llvm/utils/TableGen/AsmWriterInst.h +++ b/llvm/utils/TableGen/AsmWriterInst.h @@ -48,6 +48,8 @@ namespace llvm { /// an operand, specified with syntax like ${opname:modifier}. std::string MiModifier; + bool PCRel = false; + // To make VS STL happy AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {} @@ -55,11 +57,11 @@ namespace llvm { OpType op = isLiteralTextOperand) : OperandType(op), Str(LitStr) {} - AsmWriterOperand(const std::string &Printer, - unsigned _MIOpNo, + AsmWriterOperand(const std::string &Printer, unsigned _MIOpNo, const std::string &Modifier, - OpType op = isMachineInstrOperand) - : OperandType(op), MIOpNo(_MIOpNo), Str(Printer), MiModifier(Modifier) {} + OpType op = isMachineInstrOperand, bool PCRel = false) + : OperandType(op), MIOpNo(_MIOpNo), Str(Printer), MiModifier(Modifier), + PCRel(PCRel) {} bool operator!=(const AsmWriterOperand &Other) const { if (OperandType != Other.OperandType || Str != Other.Str) return true; |