forked from OSchip/llvm-project
[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
This commit is contained in:
parent
00809c8889
commit
ddbe812bcc
|
@ -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>;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -441,8 +441,173 @@ public:
|
|||
}
|
||||
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) {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue