[ARM][llvm-objdump] Annotate PC-relative memory operands of VLDR instructions
This extends D105979 and adds support for VLDR instructions. Differential Revision: https://reviews.llvm.org/D105980
This commit is contained in:
parent
ddbe812bcc
commit
2c14798ead
@ -154,9 +154,9 @@ public:
|
||||
|
||||
/// Given an instruction tries to get the address of a memory operand. Returns
|
||||
/// the address on success.
|
||||
virtual Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
|
||||
uint64_t Addr,
|
||||
uint64_t Size) const;
|
||||
virtual Optional<uint64_t>
|
||||
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<std::pair<uint64_t, uint64_t>>
|
||||
|
||||
@ -29,8 +29,8 @@ bool MCInstrAnalysis::evaluateBranch(const MCInst & /*Inst*/, uint64_t /*Addr*/,
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<uint64_t>
|
||||
MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr,
|
||||
uint64_t Size) const {
|
||||
Optional<uint64_t> MCInstrAnalysis::evaluateMemoryOperandAddress(
|
||||
const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
|
||||
uint64_t Size) const {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -1252,7 +1252,7 @@ def addrmode5_pre : AddrMode5 {
|
||||
// addrmode5fp16 := reg +/- imm8*2
|
||||
//
|
||||
def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; }
|
||||
class AddrMode5FP16 : Operand<i32>,
|
||||
class AddrMode5FP16 : MemOperand,
|
||||
ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> {
|
||||
let EncoderMethod = "getAddrMode5FP16OpValue";
|
||||
let DecoderMethod = "DecodeAddrMode5FP16Operand";
|
||||
|
||||
@ -443,6 +443,7 @@ public:
|
||||
}
|
||||
|
||||
Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
|
||||
const MCSubtargetInfo *STI,
|
||||
uint64_t Addr,
|
||||
uint64_t Size) const override;
|
||||
};
|
||||
@ -509,6 +510,25 @@ static Optional<uint64_t> evaluateMemOpAddrForAddrMode5(const MCInst &Inst,
|
||||
return Addr + ImmOffs * 4;
|
||||
}
|
||||
|
||||
static Optional<uint64_t>
|
||||
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;
|
||||
return Addr + ImmOffs * 2;
|
||||
}
|
||||
|
||||
static Optional<uint64_t>
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc,
|
||||
@ -554,7 +574,8 @@ evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
|
||||
}
|
||||
|
||||
Optional<uint64_t> 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.
|
||||
@ -588,6 +609,11 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
|
||||
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
|
||||
@ -601,6 +627,8 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
|
||||
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:
|
||||
|
||||
@ -391,7 +391,7 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -349,7 +349,7 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
|
||||
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);
|
||||
|
||||
@ -405,6 +405,7 @@ public:
|
||||
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
|
||||
uint64_t &Target) const override;
|
||||
Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
|
||||
const MCSubtargetInfo *STI,
|
||||
uint64_t Addr,
|
||||
uint64_t Size) const override;
|
||||
};
|
||||
@ -532,7 +533,8 @@ bool X86MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
|
||||
}
|
||||
|
||||
Optional<uint64_t> 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)
|
||||
|
||||
48
llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s
Normal file
48
llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s
Normal file
@ -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 <foo>:
|
||||
.short 0x0102
|
||||
foo2:
|
||||
@ CHECK: 00000002 <foo2>:
|
||||
.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 <foo>
|
||||
@ CHECK-NEXT: 8: vldr s0, [pc, #20] @ 0x24 <bar>
|
||||
|
||||
@@ 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 <foo>
|
||||
@ CHECK-NEXT: 14: vldr.16 s0, [pc, #-26] @ 0x2 <foo2>
|
||||
@ CHECK-NEXT: 18: vldr.16 s1, [pc, #4] @ 0x24 <bar>
|
||||
@ CHECK-NEXT: 1c: vldr.16 s1, [pc, #2] @ 0x26 <bar2>
|
||||
|
||||
@@ 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 <bar>:
|
||||
.short 0x0102
|
||||
bar2:
|
||||
@ CHECK: 00000026 <bar2>:
|
||||
.short 0x0304
|
||||
66
llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s
Normal file
66
llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s
Normal file
@ -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 <foo>:
|
||||
.short 0x0102
|
||||
foo2:
|
||||
@ CHECK: 00000002 <foo2>:
|
||||
.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 <foo>
|
||||
@ CHECK-NEXT: 8: vldr s0, [pc, #56] @ 0x44 <bar>
|
||||
|
||||
@@ Same instructions, but the addresses are not 4-byte aligned
|
||||
nop
|
||||
vldr d0, foo
|
||||
vldr s0, bar
|
||||
@ CHECK: e: vldr d0, [pc, #-16] @ 0x0 <foo>
|
||||
@ CHECK-NEXT: 12: vldr s0, [pc, #48] @ 0x44 <bar>
|
||||
|
||||
@@ 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 <foo>
|
||||
@ CHECK-NEXT: 20: vldr.16 s0, [pc, #-34] @ 0x2 <foo2>
|
||||
@ CHECK-NEXT: 24: vldr.16 s1, [pc, #28] @ 0x44 <bar>
|
||||
@ CHECK-NEXT: 28: vldr.16 s1, [pc, #26] @ 0x46 <bar2>
|
||||
|
||||
@@ 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 <foo>
|
||||
@ CHECK-NEXT: 32: vldr.16 s0, [pc, #-50] @ 0x2 <foo2>
|
||||
@ CHECK-NEXT: 36: vldr.16 s1, [pc, #12] @ 0x44 <bar>
|
||||
@ CHECK-NEXT: 3a: vldr.16 s1, [pc, #10] @ 0x46 <bar2>
|
||||
|
||||
@@ 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 <bar>:
|
||||
.short 0x0102
|
||||
bar2:
|
||||
@ CHECK: 00000046 <bar2>:
|
||||
.short 0x0304
|
||||
@ -1480,7 +1480,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
|
||||
if (!PrintTarget)
|
||||
if (Optional<uint64_t> MaybeTarget =
|
||||
MIA->evaluateMemoryOperandAddress(
|
||||
Inst, SectionAddr + Index, Size)) {
|
||||
Inst, STI, SectionAddr + Index, Size)) {
|
||||
Target = *MaybeTarget;
|
||||
PrintTarget = true;
|
||||
// Do not print real address when symbolizing.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user