[llvm] ddbe812 - [ARM][llvm-objdump] Annotate PC-relative memory operands
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 5 00:12:30 PDT 2021
Author: Igor Kudrin
Date: 2021-08-05T14:11:11+07:00
New Revision: ddbe812bccba947c95027c4af7aebf79e7274b83
URL: https://github.com/llvm/llvm-project/commit/ddbe812bccba947c95027c4af7aebf79e7274b83
DIFF: https://github.com/llvm/llvm-project/commit/ddbe812bccba947c95027c4af7aebf79e7274b83.diff
LOG: [ARM][llvm-objdump] Annotate PC-relative memory operands
This implements `MCInstrAnalysis::evaluateMemoryOperandAddress()` for
Arm so that the disassembler can print the target address of memory
operands that use PC+immediate addressing.
Differential Revision: https://reviews.llvm.org/D105979
Added:
llvm/test/tools/llvm-objdump/ELF/ARM/literal-arm.s
llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb.s
llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb2.s
Modified:
llvm/lib/Target/ARM/ARMInstrFormats.td
llvm/lib/Target/ARM/ARMInstrInfo.td
llvm/lib/Target/ARM/ARMInstrThumb.td
llvm/lib/Target/ARM/ARMInstrThumb2.td
llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td b/llvm/lib/Target/ARM/ARMInstrFormats.td
index 85da7c5a535e9..a881a59d62817 100644
--- a/llvm/lib/Target/ARM/ARMInstrFormats.td
+++ b/llvm/lib/Target/ARM/ARMInstrFormats.td
@@ -1385,8 +1385,8 @@ class ThumbXI<dag oops, dag iops, AddrMode am, int sz,
}
class T2I<dag oops, dag iops, InstrItinClass itin,
- string opc, string asm, list<dag> pattern>
- : Thumb2I<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
+ string opc, string asm, list<dag> pattern, AddrMode am = AddrModeNone>
+ : Thumb2I<oops, iops, am, 4, itin, opc, asm, "", pattern>;
class T2Ii12<dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: Thumb2I<oops, iops, AddrModeT2_i12, 4, itin, opc, asm, "",pattern>;
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 7466cecb9b33b..eeab4ce6d3ebd 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -5391,14 +5391,16 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1,
}
class ACI<dag oops, dag iops, string opc, string asm,
- list<dag> pattern, IndexMode im = IndexModeNone>
- : I<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
+ list<dag> pattern, IndexMode im = IndexModeNone,
+ AddrMode am = AddrModeNone>
+ : I<oops, iops, am, 4, im, BrFrm, NoItinerary,
opc, asm, "", pattern> {
let Inst{27-25} = 0b110;
}
class ACInoP<dag oops, dag iops, string opc, string asm,
- list<dag> pattern, IndexMode im = IndexModeNone>
- : InoP<oops, iops, AddrModeNone, 4, im, BrFrm, NoItinerary,
+ list<dag> pattern, IndexMode im = IndexModeNone,
+ AddrMode am = AddrModeNone>
+ : InoP<oops, iops, am, 4, im, BrFrm, NoItinerary,
opc, asm, "", pattern> {
let Inst{31-28} = 0b1111;
let Inst{27-25} = 0b110;
@@ -5407,7 +5409,8 @@ class ACInoP<dag oops, dag iops, string opc, string asm,
let DecoderNamespace = "CoProc" in {
multiclass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> {
def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
- asm, "\t$cop, $CRd, $addr", pattern> {
+ asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone,
+ AddrMode5> {
bits<13> addr;
bits<4> cop;
bits<4> CRd;
@@ -5478,7 +5481,8 @@ multiclass LdStCop<bit load, bit Dbit, string asm, list<dag> pattern> {
}
multiclass LdSt2Cop<bit load, bit Dbit, string asm, list<dag> pattern> {
def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
- asm, "\t$cop, $CRd, $addr", pattern> {
+ asm, "\t$cop, $CRd, $addr", pattern, IndexModeNone,
+ AddrMode5> {
bits<13> addr;
bits<4> cop;
bits<4> CRd;
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index ef07b2839bc93..0305d13c61c59 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -168,6 +168,7 @@ def thumb_cb_target : Operand<OtherVT> {
let EncoderMethod = "getThumbCBTargetOpValue";
let DecoderMethod = "DecodeThumbCmpBROperand";
}
+} // OperandType = "OPERAND_PCREL"
// t_addrmode_pc := <label> => pc + imm8 * 4
//
@@ -177,7 +178,6 @@ def t_addrmode_pc : MemOperand {
let PrintMethod = "printThumbLdrLabelOperand";
let ParserMatchClass = ThumbMemPC;
}
-}
// t_addrmode_rr := reg + reg
//
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index e7eed2a0bbb1a..0cb58b8318bd9 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -200,7 +200,7 @@ def t2addrmode_imm12 : MemOperand,
}
// t2ldrlabel := imm12
-def t2ldrlabel : Operand<i32> {
+def t2ldrlabel : MemOperand {
let EncoderMethod = "getAddrModeImm12OpValue";
let PrintMethod = "printThumbLdrLabelOperand";
}
@@ -1927,7 +1927,7 @@ def : InstAlias<"pli${p}.w\t$addr",
// pci variant is very similar to i12, but supports negative offsets
// from the PC. Only PLD and PLI have pci variants (not PLDW)
-class T2Iplpci<bits<1> inst, string opc> : T2Iso<(outs), (ins t2ldrlabel:$addr),
+class T2Iplpci<bits<1> inst, string opc> : T2Ipc<(outs), (ins t2ldrlabel:$addr),
IIC_Preload, opc, "\t$addr",
[(ARMPreload (ARMWrapper tconstpool:$addr),
(i32 0), (i32 inst))]>, Sched<[WritePreLd]> {
@@ -4274,8 +4274,9 @@ def t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src),
//===----------------------------------------------------------------------===//
// Coprocessor load/store -- for disassembly only
//
-class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm, list<dag> pattern>
- : T2I<oops, iops, NoItinerary, opc, asm, pattern> {
+class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm,
+ list<dag> pattern, AddrMode am = AddrModeNone>
+ : T2I<oops, iops, NoItinerary, opc, asm, pattern, am> {
let Inst{31-28} = op31_28;
let Inst{27-25} = 0b110;
}
@@ -4283,7 +4284,7 @@ class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm, list<dag
multiclass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm, list<dag> pattern> {
def _OFFSET : T2CI<op31_28,
(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr),
- asm, "\t$cop, $CRd, $addr", pattern> {
+ asm, "\t$cop, $CRd, $addr", pattern, AddrMode5> {
bits<13> addr;
bits<4> cop;
bits<4> CRd;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index 87cce08b1ce4f..3522639676096 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -441,8 +441,173 @@ class ARMMCInstrAnalysis : public MCInstrAnalysis {
}
return false;
}
+
+ Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
+ uint64_t Addr,
+ uint64_t Size) const override;
};
+} // namespace
+
+static Optional<uint64_t>
+// NOLINTNEXTLINE(readability-identifier-naming)
+evaluateMemOpAddrForAddrMode_i12(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;
+
+ int32_t OffImm = (int32_t)MO2.getImm();
+ // Special value for #-0. All others are normal.
+ if (OffImm == INT32_MIN)
+ OffImm = 0;
+ return Addr + OffImm;
+}
+
+static Optional<uint64_t> evaluateMemOpAddrForAddrMode3(const MCInst &Inst,
+ const MCInstrDesc &Desc,
+ unsigned MemOpIndex,
+ uint64_t Addr) {
+ if (MemOpIndex + 2 >= Desc.getNumOperands())
+ return None;
+
+ const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
+ const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
+ const MCOperand &MO3 = Inst.getOperand(MemOpIndex + 2);
+ if (!MO1.isReg() || MO1.getReg() != ARM::PC || MO2.getReg() || !MO3.isImm())
+ return None;
+
+ unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
+ ARM_AM::AddrOpc Op = ARM_AM::getAM3Op(MO3.getImm());
+
+ if (Op == ARM_AM::sub)
+ return Addr - ImmOffs;
+ return Addr + ImmOffs;
+}
+
+static Optional<uint64_t> evaluateMemOpAddrForAddrMode5(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::getAM5Offset(MO2.getImm());
+ ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
+
+ if (Op == ARM_AM::sub)
+ return Addr - ImmOffs * 4;
+ return Addr + ImmOffs * 4;
+}
+
+static Optional<uint64_t>
+// NOLINTNEXTLINE(readability-identifier-naming)
+evaluateMemOpAddrForAddrModeT2_i8s4(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;
+
+ int32_t OffImm = (int32_t)MO2.getImm();
+ assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
+
+ // Special value for #-0. All others are normal.
+ if (OffImm == INT32_MIN)
+ OffImm = 0;
+ return Addr + OffImm;
+}
+
+static Optional<uint64_t>
+// NOLINTNEXTLINE(readability-identifier-naming)
+evaluateMemOpAddrForAddrModeT2_pc(const MCInst &Inst, const MCInstrDesc &Desc,
+ unsigned MemOpIndex, uint64_t Addr) {
+ const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
+ if (!MO1.isImm())
+ return None;
+
+ int32_t OffImm = (int32_t)MO1.getImm();
+
+ // Special value for #-0. All others are normal.
+ if (OffImm == INT32_MIN)
+ OffImm = 0;
+ return Addr + OffImm;
+}
+
+static Optional<uint64_t>
+// NOLINTNEXTLINE(readability-identifier-naming)
+evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
+ unsigned MemOpIndex, uint64_t Addr) {
+ return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, MemOpIndex, Addr);
+}
+
+Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
+ const MCInst &Inst, uint64_t Addr, uint64_t Size) const {
+ const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
+
+ // Only load instructions can have PC-relative memory addressing.
+ if (!Desc.mayLoad())
+ return None;
+
+ // PC-relative addressing does not update the base register.
+ uint64_t TSFlags = Desc.TSFlags;
+ unsigned IndexMode =
+ (TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift;
+ if (IndexMode != ARMII::IndexModeNone)
+ return None;
+
+ // Find the memory addressing operand in the instruction.
+ unsigned OpIndex = Desc.NumDefs;
+ while (OpIndex < Desc.getNumOperands() &&
+ Desc.OpInfo[OpIndex].OperandType != MCOI::OPERAND_MEMORY)
+ ++OpIndex;
+ if (OpIndex == Desc.getNumOperands())
+ return None;
+
+ // Base address for PC-relative addressing is always 32-bit aligned.
+ Addr &= ~0x3;
+
+ // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it
+ // is 4 bytes.
+ switch (Desc.TSFlags & ARMII::FormMask) {
+ default:
+ Addr += 8;
+ break;
+ case ARMII::ThumbFrm:
+ Addr += 4;
+ break;
+ }
+
+ // Eveluate the address depending on the addressing mode
+ unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
+ switch (AddrMode) {
+ default:
+ return None;
+ case ARMII::AddrMode_i12:
+ return evaluateMemOpAddrForAddrMode_i12(Inst, Desc, OpIndex, Addr);
+ case ARMII::AddrMode3:
+ return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr);
+ case ARMII::AddrMode5:
+ return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr);
+ case ARMII::AddrModeT2_i8s4:
+ return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr);
+ case ARMII::AddrModeT2_pc:
+ return evaluateMemOpAddrForAddrModeT2_pc(Inst, Desc, OpIndex, Addr);
+ case ARMII::AddrModeT1_s:
+ return evaluateMemOpAddrForAddrModeT1_s(Inst, Desc, OpIndex, Addr);
+ }
}
static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
diff --git a/llvm/test/tools/llvm-objdump/ELF/ARM/literal-arm.s b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-arm.s
new file mode 100644
index 0000000000000..1768fdf42bfae
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-arm.s
@@ -0,0 +1,66 @@
+@@ Check that PC-relative memory addressing is annotated
+
+@ RUN: llvm-mc %s -triple=armv7 -filetype=obj | \
+@ RUN: llvm-objdump -d --no-show-raw-insn --triple=armv7 - | \
+@ RUN: FileCheck %s
+
+.text
+foo:
+@ CHECK: 00000000 <foo>:
+ .word 0x01020304
+
+_start:
+@ CHECK: 00000004 <_start>:
+
+@@ Check a special case immediate for AddrMode_i12
+ ldr r1, [pc, #-0]
+@ CHECK-NEXT: 4: ldr r1, [pc, #-0] @ 0xc <_start+0x8>
+
+@@ Check AddrMode_i12 instructions, with positive and negative immediates
+ ldr r0, foo
+ ldrb r0, bar
+ pli _start
+ pld bar
+@ CHECK-NEXT: 8: ldr r0, [pc, #-16] @ 0x0 <foo>
+@ CHECK-NEXT: c: ldrb r0, [pc, #48] @ 0x44 <bar>
+@ CHECK-NEXT: 10: pli [pc, #-20] @ 0x4 <_start>
+@ CHECK-NEXT: 14: pld [pc, #40] @ 0x44 <bar>
+
+@@ Check that AddrMode_i12 instructions that do not use PC-relative addressing
+@@ are not annotated
+ ldr r0, [r1, #8]
+@ CHECK-NEXT: 18: ldr r0, [r1, #8]{{$}}
+
+@@ Check AddrMode3 instructions, with positive and negative immediates
+ ldrd r0, r1, foo
+ ldrh r0, bar
+@ CHECK-NEXT: 1c: ldrd r0, r1, [pc, #-36] @ 0x0 <foo>
+@ CHECK-NEXT: 20: ldrh r0, [pc, #28] @ 0x44 <bar>
+
+@@ Check that AddrMode3 instruction that do not use PC+imm addressing are not
+@@ annotated
+ ldrh r0, [r1, #8]
+ ldrh r0, [pc, r2]
+@ CHECK-NEXT: 24: ldrh r0, [r1, #8]{{$}}
+@ CHECK-NEXT: 28: ldrh r0, [pc, r2]{{$}}
+
+@@ Check AddrMode5 instructions, with positive and negative immediates
+ ldc p14, c5, foo
+ ldcl p6, c4, bar
+ ldc2 p5, c2, foo
+ ldc2l p3, c1, bar
+@ CHECK-NEXT: 2c: ldc p14, c5, [pc, #-52] @ 0x0 <foo>
+@ CHECK-NEXT: 30: ldcl p6, c4, [pc, #12] @ 0x44 <bar>
+@ CHECK-NEXT: 34: ldc2 p5, c2, [pc, #-60] @ 0x0 <foo>
+@ CHECK-NEXT: 38: ldc2l p3, c1, [pc, #4] @ 0x44 <bar>
+
+@@ Check that AddrMode5 instruction that do not use PC+imm addressing are not
+@@ annotated
+ ldc p14, c5, [r1, #8]
+ ldc p14, c5, [pc], {16}
+@ CHECK-NEXT: 3c: ldc p14, c5, [r1, #8]{{$}}
+@ CHECK-NEXT: 40: ldc p14, c5, [pc], {16}{{$}}
+
+bar:
+@ CHECK: 00000044 <bar>:
+ .word 0x01020304
diff --git a/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb.s b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb.s
new file mode 100644
index 0000000000000..6d7c685be361a
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb.s
@@ -0,0 +1,24 @@
+@@ Check that PC-relative memory addressing is annotated
+
+@ RUN: llvm-mc %s -triple=thumbv6m -filetype=obj | \
+@ RUN: llvm-objdump -d --no-show-raw-insn --triple=thumbv6m - | \
+@ RUN: FileCheck %s
+
+.text
+_start:
+@ CHECK: 00000000 <_start>:
+
+@@ Check AddrModeT1_s instruction, with 4-byte and 2-byte alignment
+ ldr r0, bar
+ ldr r1, bar
+ ldr r2, bar
+ ldr r3, bar
+@ CHECK-NEXT: 0: ldr r0, [pc, #4] @ 0x8 <bar>
+@ CHECK-NEXT: 2: ldr r1, [pc, #4] @ 0x8 <bar>
+@ CHECK-NEXT: 4: ldr r2, [pc, #0] @ 0x8 <bar>
+@ CHECK-NEXT: 6: ldr r3, [pc, #0] @ 0x8 <bar>
+
+ .balign 4
+bar:
+@ CHECK: 00000008 <bar>:
+ .word 0x01020304
diff --git a/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb2.s b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb2.s
new file mode 100644
index 0000000000000..15efff9603ddc
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-thumb2.s
@@ -0,0 +1,116 @@
+@@ Check that PC-relative memory addressing is annotated
+
+@ RUN: llvm-mc %s -triple=thumbv7 -filetype=obj | \
+@ RUN: llvm-objdump -d --no-show-raw-insn --triple=thumbv7 - | \
+@ RUN: FileCheck %s
+
+.text
+foo:
+@ CHECK: 00000000 <foo>:
+ .word 0x01020304
+
+_start:
+@ CHECK: 00000004 <_start>:
+
+@@ Check a special case immediate for AddrModeT2_pc
+ .balign 4
+ ldr r0, [pc, #-0]
+@ CHECK: 4: ldr.w r0, [pc, #-0] @ 0x8 <_start+0x4>
+
+@@ Same instruction, but the address is not 4-byte aligned
+ nop
+ ldr r0, [pc, #-0]
+@ CHECK: a: ldr.w r0, [pc, #-0] @ 0xc <_start+0x8>
+
+@@ Check a special case immediate for AddrModeT2_i8s4
+ .balign 4
+ ldrd r0, r1, [pc, #-0]
+@ CHECK: 10: ldrd r0, r1, [pc, #-0] @ 0x14 <_start+0x10>
+
+@@ Same instruction, but the address is not 4-byte aligned
+ nop
+ ldrd r0, r1, [pc, #-0]
+@ CHECK: 16: ldrd r0, r1, [pc, #-0] @ 0x18 <_start+0x14>
+
+@@ Check AddrModeT2_pc instructions, with positive and negative immediates
+ .balign 4
+ ldr r0, foo
+ ldrb r0, bar
+ ldrsb r0, foo
+ ldrsh r0, bar
+ pli _start
+ pld bar
+@ CHECK: 1c: ldr.w r0, [pc, #-32] @ 0x0 <foo>
+@ CHECK-NEXT: 20: ldrb.w r0, [pc, #112] @ 0x94 <bar>
+@ CHECK-NEXT: 24: ldrsb.w r0, [pc, #-40] @ 0x0 <foo>
+@ CHECK-NEXT: 28: ldrsh.w r0, [pc, #104] @ 0x94 <bar>
+@ CHECK-NEXT: 2c: pli [pc, #-44] @ 0x4 <_start>
+@ CHECK-NEXT: 30: pld [pc, #96] @ 0x94 <bar>
+
+@@ Same instructions, but the addresses are not 4-byte aligned
+ nop
+ ldr r0, foo
+ ldrb r0, bar
+ ldrsb r0, foo
+ ldrsh r0, bar
+ pli _start
+ pld bar
+@ CHECK: 36: ldr.w r0, [pc, #-56] @ 0x0 <foo>
+@ CHECK-NEXT: 3a: ldrb.w r0, [pc, #88] @ 0x94 <bar>
+@ CHECK-NEXT: 3e: ldrsb.w r0, [pc, #-64] @ 0x0 <foo>
+@ CHECK-NEXT: 42: ldrsh.w r0, [pc, #80] @ 0x94 <bar>
+@ CHECK-NEXT: 46: pli [pc, #-68] @ 0x4 <_start>
+@ CHECK-NEXT: 4a: pld [pc, #72] @ 0x94 <bar>
+
+@@ Check AddrModeT2_i8s4 instructions, with positive and negative immediates
+ .balign 4
+ ldrd r0, r1, foo
+ ldrd r0, r1, bar
+@ CHECK: 50: ldrd r0, r1, [pc, #-84] @ 0x0 <foo>
+@ CHECK-NEXT: 54: ldrd r0, r1, [pc, #60] @ 0x94 <bar>
+
+@@ Same instructions, but the addresses are not 4-byte aligned
+ nop
+ ldrd r0, r1, foo
+ ldrd r0, r1, bar
+@ CHECK: 5a: ldrd r0, r1, [pc, #-92] @ 0x0 <foo>
+@ CHECK-NEXT: 5e: ldrd r0, r1, [pc, #52] @ 0x94 <bar>
+
+@@ Check that AddrModeT2_i8s4 instructions that do not use PC-relative
+@@ addressingare not annotated
+ ldrd r0, r1, [r2, #8]
+@ CHECK: 62: ldrd r0, r1, [r2, #8]{{$}}
+
+@@ Check AddrMode5 instructions, with positive and negative immediates
+ .balign 4
+ ldc p14, c5, foo
+ ldcl p6, c4, bar
+ ldc2 p5, c2, foo
+ ldc2l p3, c1, bar
+@ CHECK: 68: ldc p14, c5, [pc, #-108] @ 0x0 <foo>
+@ CHECK-NEXT: 6c: ldcl p6, c4, [pc, #36] @ 0x94 <bar>
+@ CHECK-NEXT: 70: ldc2 p5, c2, [pc, #-116] @ 0x0 <foo>
+@ CHECK-NEXT: 74: ldc2l p3, c1, [pc, #28] @ 0x94 <bar>
+
+@@ Same instructions, but the addresses are not 4-byte aligned
+ nop
+ ldc p14, c5, foo
+ ldcl p6, c4, bar
+ ldc2 p5, c2, foo
+ ldc2l p3, c1, bar
+@ CHECK: 7a: ldc p14, c5, [pc, #-124] @ 0x0 <foo>
+@ CHECK-NEXT: 7e: ldcl p6, c4, [pc, #20] @ 0x94 <bar>
+@ CHECK-NEXT: 82: ldc2 p5, c2, [pc, #-132] @ 0x0 <foo>
+@ CHECK-NEXT: 86: ldc2l p3, c1, [pc, #12] @ 0x94 <bar>
+
+@@ Check that AddrMode5 instruction that do not use PC+imm addressing are not
+@@ annotated
+ ldc p14, c5, [r1, #8]
+ ldc p14, c5, [pc], {16}
+@ CHECK: 8a: ldc p14, c5, [r1, #8]{{$}}
+@ CHECK-NEXT: 8e: ldc p14, c5, [pc], {16}{{$}}
+
+ .balign 4
+bar:
+@ CHECK: 00000094 <bar>:
+ .word 0x01020304
More information about the llvm-commits
mailing list