Index: llvm/include/llvm/MC/MCInstrAnalysis.h =================================================================== --- llvm/include/llvm/MC/MCInstrAnalysis.h +++ llvm/include/llvm/MC/MCInstrAnalysis.h @@ -154,9 +154,9 @@ /// Given an instruction tries to get the address of a memory operand. Returns /// the address on success. - virtual Optional evaluateMemoryOperandAddress(const MCInst &Inst, - uint64_t Addr, - uint64_t Size) const; + virtual Optional + evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI, + uint64_t Addr, uint64_t Size) const; /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries. virtual std::vector> Index: llvm/lib/MC/MCInstrAnalysis.cpp =================================================================== --- llvm/lib/MC/MCInstrAnalysis.cpp +++ llvm/lib/MC/MCInstrAnalysis.cpp @@ -29,8 +29,8 @@ return false; } -Optional -MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr, - uint64_t Size) const { +Optional MCInstrAnalysis::evaluateMemoryOperandAddress( + const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr, + uint64_t Size) const { return None; } Index: llvm/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrInfo.td +++ llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1252,7 +1252,7 @@ // addrmode5fp16 := reg +/- imm8*2 // def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; } -class AddrMode5FP16 : Operand, +class AddrMode5FP16 : MemOperand, ComplexPattern { let EncoderMethod = "getAddrMode5FP16OpValue"; let DecoderMethod = "DecodeAddrMode5FP16Operand"; Index: llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp =================================================================== --- llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -443,6 +443,7 @@ } Optional evaluateMemoryOperandAddress(const MCInst &Inst, + const MCSubtargetInfo *STI, uint64_t Addr, uint64_t Size) const override; }; @@ -509,6 +510,26 @@ return Addr + ImmOffs * 4; } +static Optional +evaluateMemOpAddrForAddrMode5FP16(const MCInst &Inst, const MCInstrDesc &Desc, + unsigned MemOpIndex, uint64_t Addr) { + if (MemOpIndex + 1 >= Desc.getNumOperands()) + return None; + + const MCOperand &MO1 = Inst.getOperand(MemOpIndex); + const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1); + if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm()) + return None; + + unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm()); + ARM_AM::AddrOpc Op = ARM_AM::getAM5FP16Op(MO2.getImm()); + + if (Op == ARM_AM::sub) + return Addr - ImmOffs * 2; + else + return Addr + ImmOffs * 2; +} + static Optional evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc, unsigned MemOpIndex, uint64_t Addr) { @@ -551,7 +572,8 @@ } Optional ARMMCInstrAnalysis::evaluateMemoryOperandAddress( - const MCInst &Inst, uint64_t Addr, uint64_t Size) const { + const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr, + uint64_t Size) const { const MCInstrDesc &Desc = Info->get(Inst.getOpcode()); // Only load instructions can have PC-relative memory addressing. @@ -585,6 +607,11 @@ case ARMII::ThumbFrm: Addr += 4; break; + // VLDR* instructions share the same opcode (and thus the same form) for Arm + // and Thumb. Use a bit longer route through STI in that case. + case ARMII::VFPLdStFrm: + Addr += STI->getFeatureBits()[ARM::ModeThumb] ? 4 : 8; + break; } // Eveluate the address depending on the addressing mode @@ -598,6 +625,8 @@ return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr); case ARMII::AddrMode5: return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr); + case ARMII::AddrMode5FP16: + return evaluateMemOpAddrForAddrMode5FP16(Inst, Desc, OpIndex, Addr); case ARMII::AddrModeT2_i8s4: return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr); case ARMII::AddrModeT2_pc: Index: llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp @@ -391,7 +391,7 @@ uint64_t Target; if (MIA->evaluateBranch(*MI, 0, 0, Target)) return; - if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0)) + if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0)) return; } Index: llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp @@ -349,7 +349,7 @@ uint64_t Target; if (MIA->evaluateBranch(*MI, 0, 0, Target)) return; - if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0)) + if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0)) return; } const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); Index: llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -405,6 +405,7 @@ bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, uint64_t &Target) const override; Optional evaluateMemoryOperandAddress(const MCInst &Inst, + const MCSubtargetInfo *STI, uint64_t Addr, uint64_t Size) const override; }; @@ -532,7 +533,8 @@ } Optional X86MCInstrAnalysis::evaluateMemoryOperandAddress( - const MCInst &Inst, uint64_t Addr, uint64_t Size) const { + const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr, + uint64_t Size) const { const MCInstrDesc &MCID = Info->get(Inst.getOpcode()); int MemOpStart = X86II::getMemoryOperandNo(MCID.TSFlags); if (MemOpStart == -1) Index: llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s @@ -0,0 +1,48 @@ +@@ Check that PC-relative memory addressing is annotated + +@ RUN: llvm-mc %s -triple=armv8a --mattr=+fullfp16 -filetype=obj | \ +@ RUN: llvm-objdump -d --no-show-raw-insn --triple=armv8a --mattr=+fullfp16 - | \ +@ RUN: FileCheck %s + +.text +foo: +@ CHECK: 00000000 : + .short 0x0102 +foo2: +@ CHECK: 00000002 : + .short 0x0304 + +_start: +@ CHECK: 00000004 <_start>: +@@ Check AddrMode5 instructions, with positive and negative immediates + vldr d0, foo + vldr s0, bar +@ CHECK-NEXT: 4: vldr d0, [pc, #-12] @ 0x0 +@ CHECK-NEXT: 8: vldr s0, [pc, #20] @ 0x24 + +@@ Check that AddrMode5 instructions which do not use PC-relative addressing are +@@ not annotated + vldr d0, [r1, #8] +@ CHECK-NEXT: c: vldr d0, [r1, #8]{{$}} + +@@ Check AddrMode5FP16 instructions, with positive and negative immediates + vldr.16 s0, foo + vldr.16 s0, foo2 + vldr.16 s1, bar + vldr.16 s1, bar2 +@ CHECK-NEXT: 10: vldr.16 s0, [pc, #-24] @ 0x0 +@ CHECK-NEXT: 14: vldr.16 s0, [pc, #-26] @ 0x2 +@ CHECK-NEXT: 18: vldr.16 s1, [pc, #4] @ 0x24 +@ CHECK-NEXT: 1c: vldr.16 s1, [pc, #2] @ 0x26 + +@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing +@@ are not annotated + vldr.16 s0, [r1, #8] +@ CHECK-NEXT: 20: vldr.16 s0, [r1, #8]{{$}} + +bar: +@ CHECK: 00000024 : + .short 0x0102 +bar2: +@ CHECK: 00000026 : + .short 0x0304 Index: llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s @@ -0,0 +1,66 @@ +@@ Check that PC-relative memory addressing is annotated + +@ RUN: llvm-mc %s -triple=thumbv8a --mattr=+fullfp16 -filetype=obj | \ +@ RUN: llvm-objdump -d --no-show-raw-insn --triple=thumbv8a --mattr=+fullfp16 - | \ +@ RUN: FileCheck %s + +.text +foo: +@ CHECK: 00000000 : + .short 0x0102 +foo2: +@ CHECK: 00000002 : + .short 0x0304 + +_start: +@@ Check AddrMode5 instructions, with positive and negative immediates + .balign 4 + vldr d0, foo + vldr s0, bar +@ CHECK: 4: vldr d0, [pc, #-8] @ 0x0 +@ CHECK-NEXT: 8: vldr s0, [pc, #56] @ 0x44 + +@@ Same instructions, but the addresses are not 4-byte aligned + nop + vldr d0, foo + vldr s0, bar +@ CHECK: e: vldr d0, [pc, #-16] @ 0x0 +@ CHECK-NEXT: 12: vldr s0, [pc, #48] @ 0x44 + +@@ Check that AddrMode5 instructions which do not use PC-relative addressing are not annotated + vldr d0, [r1, #8] +@ CHECK: 16: vldr d0, [r1, #8]{{$}} + +@@ Check AddrMode5FP16 instructions, with positive and negative immediates + .balign 4 + vldr.16 s0, foo + vldr.16 s0, foo2 + vldr.16 s1, bar + vldr.16 s1, bar2 +@ CHECK: 1c: vldr.16 s0, [pc, #-32] @ 0x0 +@ CHECK-NEXT: 20: vldr.16 s0, [pc, #-34] @ 0x2 +@ CHECK-NEXT: 24: vldr.16 s1, [pc, #28] @ 0x44 +@ CHECK-NEXT: 28: vldr.16 s1, [pc, #26] @ 0x46 + +@@ Same instructions, but the addresses are not 4-byte aligned + nop + vldr.16 s0, foo + vldr.16 s0, foo2 + vldr.16 s1, bar + vldr.16 s1, bar2 +@ CHECK: 2e: vldr.16 s0, [pc, #-48] @ 0x0 +@ CHECK-NEXT: 32: vldr.16 s0, [pc, #-50] @ 0x2 +@ CHECK-NEXT: 36: vldr.16 s1, [pc, #12] @ 0x44 +@ CHECK-NEXT: 3a: vldr.16 s1, [pc, #10] @ 0x46 + +@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing are not annotated + vldr.16 s0, [r1, #8] +@ CHECK: 3e: vldr.16 s0, [r1, #8]{{$}} + + .balign 4 +bar: +@ CHECK: 00000044 : + .short 0x0102 +bar2: +@ CHECK: 00000046 : + .short 0x0304 Index: llvm/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1441,7 +1441,7 @@ if (!PrintTarget) if (Optional MaybeTarget = MIA->evaluateMemoryOperandAddress( - Inst, SectionAddr + Index, Size)) { + Inst, STI, SectionAddr + Index, Size)) { Target = *MaybeTarget; PrintTarget = true; // Do not print real address when symbolizing.