[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:
Igor Kudrin 2021-08-05 13:56:14 +07:00
parent ddbe812bcc
commit 2c14798ead
10 changed files with 156 additions and 12 deletions

View File

@ -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>>

View File

@ -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;
}

View File

@ -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";

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View 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

View 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

View File

@ -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.