diff --git a/lib/Target/AArch64/AArch64InstrFormats.td b/lib/Target/AArch64/AArch64InstrFormats.td index 8839b610903..e1dcd1b7465 100644 --- a/lib/Target/AArch64/AArch64InstrFormats.td +++ b/lib/Target/AArch64/AArch64InstrFormats.td @@ -1244,6 +1244,7 @@ def am_brcond : Operand { let DecoderMethod = "DecodePCRelLabel19"; let PrintMethod = "printAlignedLabel"; let ParserMatchClass = PCRelLabel19Operand; + let OperandType = "OPERAND_PCREL"; } class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target), @@ -1299,6 +1300,7 @@ def am_tbrcond : Operand { let EncoderMethod = "getTestBranchTargetOpValue"; let PrintMethod = "printAlignedLabel"; let ParserMatchClass = BranchTarget14Operand; + let OperandType = "OPERAND_PCREL"; } // AsmOperand classes to emit (or not) special diagnostics @@ -1375,11 +1377,13 @@ def am_b_target : Operand { let EncoderMethod = "getBranchTargetOpValue"; let PrintMethod = "printAlignedLabel"; let ParserMatchClass = BranchTarget26Operand; + let OperandType = "OPERAND_PCREL"; } def am_bl_target : Operand { let EncoderMethod = "getBranchTargetOpValue"; let PrintMethod = "printAlignedLabel"; let ParserMatchClass = BranchTarget26Operand; + let OperandType = "OPERAND_PCREL"; } class BImm pattern> @@ -2667,6 +2671,7 @@ def am_ldrlit : Operand { let DecoderMethod = "DecodePCRelLabel19"; let PrintMethod = "printAlignedLabel"; let ParserMatchClass = PCRelLabel19Operand; + let OperandType = "OPERAND_PCREL"; } let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp index c3458d625b8..37257d8328c 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp @@ -131,8 +131,29 @@ createWinCOFFStreamer(MCContext &Ctx, std::unique_ptr &&TAB, IncrementalLinkerCompatible); } +namespace { + +class AArch64MCInstrAnalysis : public MCInstrAnalysis { +public: + AArch64MCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + if (Inst.getNumOperands() == 0 || + Info->get(Inst.getOpcode()).OpInfo[0].OperandType != + MCOI::OPERAND_PCREL) + return false; + + int64_t Imm = Inst.getOperand(0).getImm() * 4; + Target = Addr + Imm; + return true; + } +}; + +} // end anonymous namespace + static MCInstrAnalysis *createAArch64InstrAnalysis(const MCInstrInfo *Info) { - return new MCInstrAnalysis(Info); + return new AArch64MCInstrAnalysis(Info); } // Force static initialization. diff --git a/test/tools/llvm-objdump/AArch64/pc-rel-targets.test b/test/tools/llvm-objdump/AArch64/pc-rel-targets.test new file mode 100644 index 00000000000..329dd06998f --- /dev/null +++ b/test/tools/llvm-objdump/AArch64/pc-rel-targets.test @@ -0,0 +1,3 @@ +// RUN: llvm-objdump -d %p/Inputs/kextbundle.macho-aarch64 | FileCheck %s + +CHECK: 4008: 03 00 00 94 bl #12 <_bar.stub>