Skip to content

Commit 2c14798

Browse files
committed
[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
1 parent ddbe812 commit 2c14798

File tree

10 files changed

+156
-12
lines changed

10 files changed

+156
-12
lines changed

llvm/include/llvm/MC/MCInstrAnalysis.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ class MCInstrAnalysis {
154154

155155
/// Given an instruction tries to get the address of a memory operand. Returns
156156
/// the address on success.
157-
virtual Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
158-
uint64_t Addr,
159-
uint64_t Size) const;
157+
virtual Optional<uint64_t>
158+
evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI,
159+
uint64_t Addr, uint64_t Size) const;
160160

161161
/// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
162162
virtual std::vector<std::pair<uint64_t, uint64_t>>

llvm/lib/MC/MCInstrAnalysis.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ bool MCInstrAnalysis::evaluateBranch(const MCInst & /*Inst*/, uint64_t /*Addr*/,
2929
return false;
3030
}
3131

32-
Optional<uint64_t>
33-
MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr,
34-
uint64_t Size) const {
32+
Optional<uint64_t> MCInstrAnalysis::evaluateMemoryOperandAddress(
33+
const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
34+
uint64_t Size) const {
3535
return None;
3636
}

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ def addrmode5_pre : AddrMode5 {
12521252
// addrmode5fp16 := reg +/- imm8*2
12531253
//
12541254
def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; }
1255-
class AddrMode5FP16 : Operand<i32>,
1255+
class AddrMode5FP16 : MemOperand,
12561256
ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> {
12571257
let EncoderMethod = "getAddrMode5FP16OpValue";
12581258
let DecoderMethod = "DecodeAddrMode5FP16Operand";

llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ class ARMMCInstrAnalysis : public MCInstrAnalysis {
443443
}
444444

445445
Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
446+
const MCSubtargetInfo *STI,
446447
uint64_t Addr,
447448
uint64_t Size) const override;
448449
};
@@ -509,6 +510,25 @@ static Optional<uint64_t> evaluateMemOpAddrForAddrMode5(const MCInst &Inst,
509510
return Addr + ImmOffs * 4;
510511
}
511512

513+
static Optional<uint64_t>
514+
evaluateMemOpAddrForAddrMode5FP16(const MCInst &Inst, const MCInstrDesc &Desc,
515+
unsigned MemOpIndex, uint64_t Addr) {
516+
if (MemOpIndex + 1 >= Desc.getNumOperands())
517+
return None;
518+
519+
const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
520+
const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
521+
if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
522+
return None;
523+
524+
unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
525+
ARM_AM::AddrOpc Op = ARM_AM::getAM5FP16Op(MO2.getImm());
526+
527+
if (Op == ARM_AM::sub)
528+
return Addr - ImmOffs * 2;
529+
return Addr + ImmOffs * 2;
530+
}
531+
512532
static Optional<uint64_t>
513533
// NOLINTNEXTLINE(readability-identifier-naming)
514534
evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc,
@@ -554,7 +574,8 @@ evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
554574
}
555575

556576
Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
557-
const MCInst &Inst, uint64_t Addr, uint64_t Size) const {
577+
const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
578+
uint64_t Size) const {
558579
const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
559580

560581
// Only load instructions can have PC-relative memory addressing.
@@ -588,6 +609,11 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
588609
case ARMII::ThumbFrm:
589610
Addr += 4;
590611
break;
612+
// VLDR* instructions share the same opcode (and thus the same form) for Arm
613+
// and Thumb. Use a bit longer route through STI in that case.
614+
case ARMII::VFPLdStFrm:
615+
Addr += STI->getFeatureBits()[ARM::ModeThumb] ? 4 : 8;
616+
break;
591617
}
592618

593619
// Eveluate the address depending on the addressing mode
@@ -601,6 +627,8 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
601627
return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr);
602628
case ARMII::AddrMode5:
603629
return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr);
630+
case ARMII::AddrMode5FP16:
631+
return evaluateMemOpAddrForAddrMode5FP16(Inst, Desc, OpIndex, Addr);
604632
case ARMII::AddrModeT2_i8s4:
605633
return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr);
606634
case ARMII::AddrModeT2_pc:

llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
391391
uint64_t Target;
392392
if (MIA->evaluateBranch(*MI, 0, 0, Target))
393393
return;
394-
if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
394+
if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0))
395395
return;
396396
}
397397

llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
349349
uint64_t Target;
350350
if (MIA->evaluateBranch(*MI, 0, 0, Target))
351351
return;
352-
if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
352+
if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0))
353353
return;
354354
}
355355
const MCOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg);

llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ class X86MCInstrAnalysis : public MCInstrAnalysis {
405405
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
406406
uint64_t &Target) const override;
407407
Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
408+
const MCSubtargetInfo *STI,
408409
uint64_t Addr,
409410
uint64_t Size) const override;
410411
};
@@ -532,7 +533,8 @@ bool X86MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
532533
}
533534

534535
Optional<uint64_t> X86MCInstrAnalysis::evaluateMemoryOperandAddress(
535-
const MCInst &Inst, uint64_t Addr, uint64_t Size) const {
536+
const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
537+
uint64_t Size) const {
536538
const MCInstrDesc &MCID = Info->get(Inst.getOpcode());
537539
int MemOpStart = X86II::getMemoryOperandNo(MCID.TSFlags);
538540
if (MemOpStart == -1)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
@@ Check that PC-relative memory addressing is annotated
2+
3+
@ RUN: llvm-mc %s -triple=armv8a --mattr=+fullfp16 -filetype=obj | \
4+
@ RUN: llvm-objdump -d --no-show-raw-insn --triple=armv8a --mattr=+fullfp16 - | \
5+
@ RUN: FileCheck %s
6+
7+
.text
8+
foo:
9+
@ CHECK: 00000000 <foo>:
10+
.short 0x0102
11+
foo2:
12+
@ CHECK: 00000002 <foo2>:
13+
.short 0x0304
14+
15+
_start:
16+
@ CHECK: 00000004 <_start>:
17+
@@ Check AddrMode5 instructions, with positive and negative immediates
18+
vldr d0, foo
19+
vldr s0, bar
20+
@ CHECK-NEXT: 4: vldr d0, [pc, #-12] @ 0x0 <foo>
21+
@ CHECK-NEXT: 8: vldr s0, [pc, #20] @ 0x24 <bar>
22+
23+
@@ Check that AddrMode5 instructions which do not use PC-relative addressing are
24+
@@ not annotated
25+
vldr d0, [r1, #8]
26+
@ CHECK-NEXT: c: vldr d0, [r1, #8]{{$}}
27+
28+
@@ Check AddrMode5FP16 instructions, with positive and negative immediates
29+
vldr.16 s0, foo
30+
vldr.16 s0, foo2
31+
vldr.16 s1, bar
32+
vldr.16 s1, bar2
33+
@ CHECK-NEXT: 10: vldr.16 s0, [pc, #-24] @ 0x0 <foo>
34+
@ CHECK-NEXT: 14: vldr.16 s0, [pc, #-26] @ 0x2 <foo2>
35+
@ CHECK-NEXT: 18: vldr.16 s1, [pc, #4] @ 0x24 <bar>
36+
@ CHECK-NEXT: 1c: vldr.16 s1, [pc, #2] @ 0x26 <bar2>
37+
38+
@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing
39+
@@ are not annotated
40+
vldr.16 s0, [r1, #8]
41+
@ CHECK-NEXT: 20: vldr.16 s0, [r1, #8]{{$}}
42+
43+
bar:
44+
@ CHECK: 00000024 <bar>:
45+
.short 0x0102
46+
bar2:
47+
@ CHECK: 00000026 <bar2>:
48+
.short 0x0304
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
@@ Check that PC-relative memory addressing is annotated
2+
3+
@ RUN: llvm-mc %s -triple=thumbv8a --mattr=+fullfp16 -filetype=obj | \
4+
@ RUN: llvm-objdump -d --no-show-raw-insn --triple=thumbv8a --mattr=+fullfp16 - | \
5+
@ RUN: FileCheck %s
6+
7+
.text
8+
foo:
9+
@ CHECK: 00000000 <foo>:
10+
.short 0x0102
11+
foo2:
12+
@ CHECK: 00000002 <foo2>:
13+
.short 0x0304
14+
15+
_start:
16+
@@ Check AddrMode5 instructions, with positive and negative immediates
17+
.balign 4
18+
vldr d0, foo
19+
vldr s0, bar
20+
@ CHECK: 4: vldr d0, [pc, #-8] @ 0x0 <foo>
21+
@ CHECK-NEXT: 8: vldr s0, [pc, #56] @ 0x44 <bar>
22+
23+
@@ Same instructions, but the addresses are not 4-byte aligned
24+
nop
25+
vldr d0, foo
26+
vldr s0, bar
27+
@ CHECK: e: vldr d0, [pc, #-16] @ 0x0 <foo>
28+
@ CHECK-NEXT: 12: vldr s0, [pc, #48] @ 0x44 <bar>
29+
30+
@@ Check that AddrMode5 instructions which do not use PC-relative addressing are not annotated
31+
vldr d0, [r1, #8]
32+
@ CHECK: 16: vldr d0, [r1, #8]{{$}}
33+
34+
@@ Check AddrMode5FP16 instructions, with positive and negative immediates
35+
.balign 4
36+
vldr.16 s0, foo
37+
vldr.16 s0, foo2
38+
vldr.16 s1, bar
39+
vldr.16 s1, bar2
40+
@ CHECK: 1c: vldr.16 s0, [pc, #-32] @ 0x0 <foo>
41+
@ CHECK-NEXT: 20: vldr.16 s0, [pc, #-34] @ 0x2 <foo2>
42+
@ CHECK-NEXT: 24: vldr.16 s1, [pc, #28] @ 0x44 <bar>
43+
@ CHECK-NEXT: 28: vldr.16 s1, [pc, #26] @ 0x46 <bar2>
44+
45+
@@ Same instructions, but the addresses are not 4-byte aligned
46+
nop
47+
vldr.16 s0, foo
48+
vldr.16 s0, foo2
49+
vldr.16 s1, bar
50+
vldr.16 s1, bar2
51+
@ CHECK: 2e: vldr.16 s0, [pc, #-48] @ 0x0 <foo>
52+
@ CHECK-NEXT: 32: vldr.16 s0, [pc, #-50] @ 0x2 <foo2>
53+
@ CHECK-NEXT: 36: vldr.16 s1, [pc, #12] @ 0x44 <bar>
54+
@ CHECK-NEXT: 3a: vldr.16 s1, [pc, #10] @ 0x46 <bar2>
55+
56+
@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing are not annotated
57+
vldr.16 s0, [r1, #8]
58+
@ CHECK: 3e: vldr.16 s0, [r1, #8]{{$}}
59+
60+
.balign 4
61+
bar:
62+
@ CHECK: 00000044 <bar>:
63+
.short 0x0102
64+
bar2:
65+
@ CHECK: 00000046 <bar2>:
66+
.short 0x0304

llvm/tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,7 +1480,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
14801480
if (!PrintTarget)
14811481
if (Optional<uint64_t> MaybeTarget =
14821482
MIA->evaluateMemoryOperandAddress(
1483-
Inst, SectionAddr + Index, Size)) {
1483+
Inst, STI, SectionAddr + Index, Size)) {
14841484
Target = *MaybeTarget;
14851485
PrintTarget = true;
14861486
// Do not print real address when symbolizing.

0 commit comments

Comments
 (0)