Fix #13035, a bug around Thumb instruction LDRD/STRD with negative #0 offset index issue.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161162 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jiangning Liu
2012-08-02 08:29:50 +00:00
parent c1b7ca5ba2
commit fd652df8b3
5 changed files with 52 additions and 17 deletions

View File

@ -1040,7 +1040,8 @@ public:
// Immediate offset a multiple of 4 in range [-1020, 1020]. // Immediate offset a multiple of 4 in range [-1020, 1020].
if (!Memory.OffsetImm) return true; if (!Memory.OffsetImm) return true;
int64_t Val = Memory.OffsetImm->getValue(); int64_t Val = Memory.OffsetImm->getValue();
return Val >= -1020 && Val <= 1020 && (Val & 3) == 0; // Special case, #-0 is INT32_MIN.
return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN;
} }
bool isMemImm0_1020s4Offset() const { bool isMemImm0_1020s4Offset() const {
if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0) if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)

View File

@ -3151,9 +3151,14 @@ static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) { uint64_t Address, const void *Decoder) {
int imm = Val & 0xFF; if (Val == 0)
if (!(Val & 0x100)) imm *= -1; Inst.addOperand(MCOperand::CreateImm(INT32_MIN));
Inst.addOperand(MCOperand::CreateImm(imm << 2)); else {
int imm = Val & 0xFF;
if (!(Val & 0x100)) imm *= -1;
Inst.addOperand(MCOperand::CreateImm(imm << 2));
}
return MCDisassembler::Success; return MCDisassembler::Success;
} }

View File

@ -972,12 +972,17 @@ void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
O << "[" << getRegisterName(MO1.getReg()); O << "[" << getRegisterName(MO1.getReg());
int32_t OffImm = (int32_t)MO2.getImm() / 4; int32_t OffImm = (int32_t)MO2.getImm();
assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
// Don't print +0. // Don't print +0.
if (OffImm < 0) if (OffImm == INT32_MIN)
O << ", #-" << -OffImm * 4; O << ", #-0";
else if (OffImm < 0)
O << ", #-" << -OffImm;
else if (OffImm > 0) else if (OffImm > 0)
O << ", #" << OffImm * 4; O << ", #" << OffImm;
O << "]"; O << "]";
} }
@ -1009,15 +1014,17 @@ void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
unsigned OpNum, unsigned OpNum,
raw_ostream &O) { raw_ostream &O) {
const MCOperand &MO1 = MI->getOperand(OpNum); const MCOperand &MO1 = MI->getOperand(OpNum);
int32_t OffImm = (int32_t)MO1.getImm() / 4; int32_t OffImm = (int32_t)MO1.getImm();
assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
// Don't print +0. // Don't print +0.
if (OffImm != 0) { if (OffImm == INT32_MIN)
O << ", "; O << ", #-0";
if (OffImm < 0) else if (OffImm < 0)
O << "#-" << -OffImm * 4; O << ", #-" << -OffImm;
else if (OffImm > 0) else if (OffImm > 0)
O << "#" << OffImm * 4; O << ", #" << OffImm;
}
} }
void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,

View File

@ -852,6 +852,9 @@ _func:
ldrd r3, r5, [r6], #-8 ldrd r3, r5, [r6], #-8
ldrd r3, r5, [r6] ldrd r3, r5, [r6]
ldrd r8, r1, [r3, #0] ldrd r8, r1, [r3, #0]
ldrd r0, r1, [r2, #-0]
ldrd r0, r1, [r2, #-0]!
ldrd r0, r1, [r2], #-0
@ CHECK: ldrd r3, r5, [r6, #24] @ encoding: [0xd6,0xe9,0x06,0x35] @ CHECK: ldrd r3, r5, [r6, #24] @ encoding: [0xd6,0xe9,0x06,0x35]
@ CHECK: ldrd r3, r5, [r6, #24]! @ encoding: [0xf6,0xe9,0x06,0x35] @ CHECK: ldrd r3, r5, [r6, #24]! @ encoding: [0xf6,0xe9,0x06,0x35]
@ -859,6 +862,9 @@ _func:
@ CHECK: ldrd r3, r5, [r6], #-8 @ encoding: [0x76,0xe8,0x02,0x35] @ CHECK: ldrd r3, r5, [r6], #-8 @ encoding: [0x76,0xe8,0x02,0x35]
@ CHECK: ldrd r3, r5, [r6] @ encoding: [0xd6,0xe9,0x00,0x35] @ CHECK: ldrd r3, r5, [r6] @ encoding: [0xd6,0xe9,0x00,0x35]
@ CHECK: ldrd r8, r1, [r3] @ encoding: [0xd3,0xe9,0x00,0x81] @ CHECK: ldrd r8, r1, [r3] @ encoding: [0xd3,0xe9,0x00,0x81]
@ CHECK: ldrd r0, r1, [r2, #-0] @ encoding: [0x52,0xe9,0x00,0x01]
@ CHECK: ldrd r0, r1, [r2, #-0]! @ encoding: [0x72,0xe9,0x00,0x01]
@ CHECK: ldrd r0, r1, [r2], #-0 @ encoding: [0x72,0xe8,0x00,0x01]
@------------------------------------------------------------------------------ @------------------------------------------------------------------------------
@ -2636,6 +2642,9 @@ _func:
strd r3, r5, [r6], #-8 strd r3, r5, [r6], #-8
strd r3, r5, [r6] strd r3, r5, [r6]
strd r8, r1, [r3, #0] strd r8, r1, [r3, #0]
strd r0, r1, [r2, #-0]
strd r0, r1, [r2, #-0]!
strd r0, r1, [r2], #-0
@ CHECK: strd r3, r5, [r6, #24] @ encoding: [0xc6,0xe9,0x06,0x35] @ CHECK: strd r3, r5, [r6, #24] @ encoding: [0xc6,0xe9,0x06,0x35]
@ CHECK: strd r3, r5, [r6, #24]! @ encoding: [0xe6,0xe9,0x06,0x35] @ CHECK: strd r3, r5, [r6, #24]! @ encoding: [0xe6,0xe9,0x06,0x35]
@ -2643,6 +2652,9 @@ _func:
@ CHECK: strd r3, r5, [r6], #-8 @ encoding: [0x66,0xe8,0x02,0x35] @ CHECK: strd r3, r5, [r6], #-8 @ encoding: [0x66,0xe8,0x02,0x35]
@ CHECK: strd r3, r5, [r6] @ encoding: [0xc6,0xe9,0x00,0x35] @ CHECK: strd r3, r5, [r6] @ encoding: [0xc6,0xe9,0x00,0x35]
@ CHECK: strd r8, r1, [r3] @ encoding: [0xc3,0xe9,0x00,0x81] @ CHECK: strd r8, r1, [r3] @ encoding: [0xc3,0xe9,0x00,0x81]
@ CHECK: strd r0, r1, [r2, #-0] @ encoding: [0x42,0xe9,0x00,0x01]
@ CHECK: strd r0, r1, [r2, #-0]! @ encoding: [0x62,0xe9,0x00,0x01]
@ CHECK: strd r0, r1, [r2], #-0 @ encoding: [0x62,0xe8,0x00,0x01]
@------------------------------------------------------------------------------ @------------------------------------------------------------------------------

View File

@ -641,6 +641,9 @@
# CHECK: ldrd r3, r5, [r6], #-8 # CHECK: ldrd r3, r5, [r6], #-8
# CHECK: ldrd r3, r5, [r6] # CHECK: ldrd r3, r5, [r6]
# CHECK: ldrd r8, r1, [r3] # CHECK: ldrd r8, r1, [r3]
# CHECK: ldrd r0, r1, [r2], #-0
# CHECK: ldrd r0, r1, [r2, #-0]!
# CHECK: ldrd r0, r1, [r2, #-0]
0xd6 0xe9 0x06 0x35 0xd6 0xe9 0x06 0x35
0xf6 0xe9 0x06 0x35 0xf6 0xe9 0x06 0x35
@ -648,6 +651,9 @@
0x76 0xe8 0x02 0x35 0x76 0xe8 0x02 0x35
0xd6 0xe9 0x00 0x35 0xd6 0xe9 0x00 0x35
0xd3 0xe9 0x00 0x81 0xd3 0xe9 0x00 0x81
0x72 0xe8 0x00 0x01
0x72 0xe9 0x00 0x01
0x52 0xe9 0x00 0x01
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -1822,12 +1828,16 @@
# STRD (immediate) # STRD (immediate)
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# CHECK: strd r6, r3, [r5], #-8 # CHECK: strd r6, r3, [r5], #-8
# CHECK: strd r8, r5, [r5]{{$}} # CHECK: strd r8, r5, [r5], #-0
# CHECK: strd r7, r4, [r5], #-4 # CHECK: strd r7, r4, [r5], #-4
# CHECK: strd r0, r1, [r2, #-0]!
# CHECK: strd r0, r1, [r2, #-0]
0x65 0xe8 0x02 0x63 0x65 0xe8 0x02 0x63
0x65 0xe8 0x00 0x85 0x65 0xe8 0x00 0x85
0x65 0xe8 0x01 0x74 0x65 0xe8 0x01 0x74
0x62 0xe9 0x00 0x01
0x42 0xe9 0x00 0x01
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# STREX/STREXB/STREXH/STREXD # STREX/STREXB/STREXH/STREXD