[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