llvm.org GIT mirror llvm / 93c7c44
Fix the handling of edge cases in ARM shifted operands. This patch fixes load/store instructions to handle less common cases like "asr #32", "rrx" properly throughout the MC layer. Patch by Chris Lidbury. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164455 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 7 years ago
6 changed file(s) with 152 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
44434443 ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
44444444 ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
44454445 return Error(Loc, "immediate shift value out of range");
4446 // If #0, turn it into a no_shift.
4447 if (Imm == 0)
4448 St = ARM_AM::lsl;
4449 // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
4450 if (Imm == 32)
4451 Imm = 0;
44464452 Amount = Imm;
44474453 }
44484454
15221522 return MCDisassembler::Fail;
15231523 }
15241524 unsigned amt = fieldFromInstruction(Insn, 7, 5);
1525 if (Opc == ARM_AM::ror && amt == 0)
1526 Opc = ARM_AM::rrx;
15251527 unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
15261528
15271529 Inst.addOperand(MCOperand::CreateImm(imm));
15621564 ShOp = ARM_AM::ror;
15631565 break;
15641566 }
1567
1568 if (ShOp == ARM_AM::ror && imm == 0)
1569 ShOp = ARM_AM::rrx;
15651570
15661571 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
15671572 return MCDisassembler::Fail;
2828 ///
2929 /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
3030 static unsigned translateShiftImm(unsigned imm) {
31 // lsr #32 and asr #32 exist, but should be encoded as a 0.
32 assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
33
3134 if (imm == 0)
3235 return 32;
3336 return imm;
3437 }
3538
39 /// Prints the shift value with an immediate value.
40 static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
41 unsigned ShImm) {
42 if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
43 return;
44 O << ", ";
45
46 assert (!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
47 O << getShiftOpcStr(ShOpc);
48
49 if (ShOpc != ARM_AM::rrx)
50 O << " #" << translateShiftImm(ShImm);
51 }
3652
3753 ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI,
3854 const MCInstrInfo &MII,
318334 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
319335 << getRegisterName(MO2.getReg());
320336
321 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
322 O << ", "
323 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
324 << " #" << ShImm;
337 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
338 ARM_AM::getAM2Offset(MO3.getImm()));
325339 O << "]";
326340 }
327341
402416 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
403417 << getRegisterName(MO1.getReg());
404418
405 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
406 O << ", "
407 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
408 << " #" << ShImm;
419 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
420 ARM_AM::getAM2Offset(MO2.getImm()));
409421 }
410422
411423 //===--------------------------------------------------------------------===//
933933 ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
934934 unsigned SBits = getShiftOp(ShOp);
935935
936 // While "lsr #32" and "asr #32" exist, they are encoded with a 0 in the shift
937 // amount. However, it would be an easy mistake to make so check here.
938 assert((ShImm & ~0x1f) == 0 && "Out of range shift amount");
939
936940 // {16-13} = Rn
937941 // {12} = isAdd
938942 // {11-0} = shifter
0 @ RUN: llvm-mc -mcpu=cortex-a8 -triple armv7 -show-encoding < %s | FileCheck %s
1
2 ldr r0, [r0, r0]
3 ldr r0, [r0, r0, lsr #32]
4 ldr r0, [r0, r0, lsr #16]
5 ldr r0, [r0, r0, lsl #0]
6 ldr r0, [r0, r0, lsl #16]
7 ldr r0, [r0, r0, asr #32]
8 ldr r0, [r0, r0, asr #16]
9 ldr r0, [r0, r0, rrx]
10 ldr r0, [r0, r0, ror #16]
11
12 @ CHECK: ldr r0, [r0, r0] @ encoding: [0x00,0x00,0x90,0xe7]
13 @ CHECK: ldr r0, [r0, r0, lsr #32] @ encoding: [0x20,0x00,0x90,0xe7]
14 @ CHECK: ldr r0, [r0, r0, lsr #16] @ encoding: [0x20,0x08,0x90,0xe7]
15 @ CHECK: ldr r0, [r0, r0] @ encoding: [0x00,0x00,0x90,0xe7]
16 @ CHECK: ldr r0, [r0, r0, lsl #16] @ encoding: [0x00,0x08,0x90,0xe7]
17 @ CHECK: ldr r0, [r0, r0, asr #32] @ encoding: [0x40,0x00,0x90,0xe7]
18 @ CHECK: ldr r0, [r0, r0, asr #16] @ encoding: [0x40,0x08,0x90,0xe7]
19 @ CHECK: ldr r0, [r0, r0, rrx] @ encoding: [0x60,0x00,0x90,0xe7]
20 @ CHECK: ldr r0, [r0, r0, ror #16] @ encoding: [0x60,0x08,0x90,0xe7]
21
22 pld [r0, r0]
23 pld [r0, r0, lsr #32]
24 pld [r0, r0, lsr #16]
25 pld [r0, r0, lsl #0]
26 pld [r0, r0, lsl #16]
27 pld [r0, r0, asr #32]
28 pld [r0, r0, asr #16]
29 pld [r0, r0, rrx]
30 pld [r0, r0, ror #16]
31
32 @ CHECK: [r0, r0] @ encoding: [0x00,0xf0,0xd0,0xf7]
33 @ CHECK: [r0, r0, lsr #32] @ encoding: [0x20,0xf0,0xd0,0xf7]
34 @ CHECK: [r0, r0, lsr #16] @ encoding: [0x20,0xf8,0xd0,0xf7]
35 @ CHECK: [r0, r0] @ encoding: [0x00,0xf0,0xd0,0xf7]
36 @ CHECK: [r0, r0, lsl #16] @ encoding: [0x00,0xf8,0xd0,0xf7]
37 @ CHECK: [r0, r0, asr #32] @ encoding: [0x40,0xf0,0xd0,0xf7]
38 @ CHECK: [r0, r0, asr #16] @ encoding: [0x40,0xf8,0xd0,0xf7]
39 @ CHECK: [r0, r0, rrx] @ encoding: [0x60,0xf0,0xd0,0xf7]
40 @ CHECK: [r0, r0, ror #16] @ encoding: [0x60,0xf8,0xd0,0xf7]
41
42 str r0, [r0, r0]
43 str r0, [r0, r0, lsr #32]
44 str r0, [r0, r0, lsr #16]
45 str r0, [r0, r0, lsl #0]
46 str r0, [r0, r0, lsl #16]
47 str r0, [r0, r0, asr #32]
48 str r0, [r0, r0, asr #16]
49 str r0, [r0, r0, rrx]
50 str r0, [r0, r0, ror #16]
51
52 @ CHECK: str r0, [r0, r0] @ encoding: [0x00,0x00,0x80,0xe7]
53 @ CHECK: str r0, [r0, r0, lsr #32] @ encoding: [0x20,0x00,0x80,0xe7]
54 @ CHECK: str r0, [r0, r0, lsr #16] @ encoding: [0x20,0x08,0x80,0xe7]
55 @ CHECK: str r0, [r0, r0] @ encoding: [0x00,0x00,0x80,0xe7]
56 @ CHECK: str r0, [r0, r0, lsl #16] @ encoding: [0x00,0x08,0x80,0xe7]
57 @ CHECK: str r0, [r0, r0, asr #32] @ encoding: [0x40,0x00,0x80,0xe7]
58 @ CHECK: str r0, [r0, r0, asr #16] @ encoding: [0x40,0x08,0x80,0xe7]
59 @ CHECK: str r0, [r0, r0, rrx] @ encoding: [0x60,0x00,0x80,0xe7]
60 @ CHECK: str r0, [r0, r0, ror #16] @ encoding: [0x60,0x08,0x80,0xe7]
61
62 @ Uses printAddrMode2OffsetOperand(), used by LDRBT_POST_IMM LDRBT_POST_REG
63 @ LDRB_POST_IMM LDRB_POST_REG LDRT_POST_IMM LDRT_POST_REG LDR_POST_IMM
64 @ LDR_POST_REG STRBT_POST_IMM STRBT_POST_REG STRB_POST_IMM STRB_POST_REG
65 @ STRT_POST_IMM STRT_POST_REG STR_POST_IMM STR_POST_REG
66
67 ldr r0, [r1], r2, rrx
68 ldr r3, [r4], r5, ror #0
69 str r6, [r7], r8, lsl #0
70 str r9, [r10], r11
71
72 @ CHECK: ldr r0, [r1], r2, rrx @ encoding: [0x62,0x00,0x91,0xe6]
73 @ CHECK: ldr r3, [r4], r5 @ encoding: [0x05,0x30,0x94,0xe6]
74 @ CHECK: str r6, [r7], r8 @ encoding: [0x08,0x60,0x87,0xe6]
75 @ CHECK: str r9, [r10], r11 @ encoding: [0x0b,0x90,0x8a,0xe6]
4646 @ CHECK-ERRORS: error: immediate shift value out of range
4747 @ CHECK-ERRORS: adc r4, r5, r6, ror #32
4848
49
49 @ Out of range shift immediate values for load/store.
50 str r1, [r2, r3, lsl #invalid]
51 ldr r4, [r5], r6, lsl #-1
52 pld r4, [r5, r6, lsl #32]
53 str r4, [r5], r6, lsr #-1
54 ldr r4, [r5, r6, lsr #33]
55 pld r4, [r5, r6, asr #-1]
56 str r4, [r5, r6, asr #33]
57 ldr r4, [r5, r6, ror #-1]
58 pld r4, [r5, r6, ror #32]
59 pld r4, [r5, r6, rrx #0]
60
61 @ CHECK-ERRORS: error: shift amount must be an immediate
62 @ CHECK-ERRORS: str r1, [r2, r3, lsl #invalid]
63 @ CHECK-ERRORS: ^
64 @ CHECK-ERRORS: error: immediate shift value out of range
65 @ CHECK-ERRORS: ldr r4, [r5], r6, lsl #-1
66 @ CHECK-ERRORS: ^
67 @ CHECK-ERRORS: error: immediate shift value out of range
68 @ CHECK-ERRORS: pld r4, [r5, r6, lsl #32]
69 @ CHECK-ERRORS: ^
70 @ CHECK-ERRORS: error: immediate shift value out of range
71 @ CHECK-ERRORS: str r4, [r5], r6, lsr #-1
72 @ CHECK-ERRORS: ^
73 @ CHECK-ERRORS: error: immediate shift value out of range
74 @ CHECK-ERRORS: ldr r4, [r5, r6, lsr #33]
75 @ CHECK-ERRORS: ^
76 @ CHECK-ERRORS: error: immediate shift value out of range
77 @ CHECK-ERRORS: pld r4, [r5, r6, asr #-1]
78 @ CHECK-ERRORS: ^
79 @ CHECK-ERRORS: error: immediate shift value out of range
80 @ CHECK-ERRORS: str r4, [r5, r6, asr #33]
81 @ CHECK-ERRORS: ^
82 @ CHECK-ERRORS: error: immediate shift value out of range
83 @ CHECK-ERRORS: ldr r4, [r5, r6, ror #-1]
84 @ CHECK-ERRORS: ^
85 @ CHECK-ERRORS: error: immediate shift value out of range
86 @ CHECK-ERRORS: pld r4, [r5, r6, ror #32]
87 @ CHECK-ERRORS: error: ']' expected
88 @ CHECK-ERRORS: pld r4, [r5, r6, rrx #0]
89
5090 @ Out of range 16-bit immediate on BKPT
5191 bkpt #65536
5292