llvm.org GIT mirror llvm / c492675
[ARM] Diagnose PC-writing instructions in IT blocks In Thumb2, instructions which write to the PC are UNPREDICTABLE if they are in an IT block but not the last instruction in the block. Previously, we only diagnosed this for LDM instructions, this patch extends the diagnostic to cover all of the relevant instructions. Differential Revision: https://reviews.llvm.org/D30398 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296459 91177308-0d34-0410-b5e6-96231b3b80d8 Oliver Stannard 3 years ago
4 changed file(s) with 70 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
63046304 else if (ListContainsPC && ListContainsLR)
63056305 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
63066306 "PC and LR may not be in the register list simultaneously");
6307 else if (inITBlock() && !lastInITBlock() && ListContainsPC)
6308 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6309 "instruction must be outside of IT block or the last "
6310 "instruction in an IT block");
63116307 return false;
63126308 }
63136309
63676363 Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
63686364 ARMCC::AL) {
63696365 return Warning(Loc, "predicated instructions should be in IT block");
6366 }
6367
6368 // PC-setting instructions in an IT block, but not the last instruction of
6369 // the block, are UNPREDICTABLE.
6370 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
6371 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
63706372 }
63716373
63726374 const unsigned Opcode = Inst.getOpcode();
90129014 // operands. We only care about Thumb instructions here, as ARM instructions
90139015 // obviously can't be in an IT block.
90149016 switch (Inst.getOpcode()) {
9017 case ARM::tLDMIA:
90159018 case ARM::t2LDMIA:
90169019 case ARM::t2LDMIA_UPD:
90179020 case ARM::t2LDMDB:
1515 @ SMC
1616 @------------------------------------------------------------------------------
1717 smc #0xf
18 ite eq
18 it eq
1919 smceq #0
2020
2121 @ NOTZ-NOT: smc #15
2222 @ NOTZ-NOT: smceq #0
2323 @ TZ: smc #15 @ encoding: [0xff,0xf7,0x00,0x80]
24 @ TZ: ite eq @ encoding: [0x0c,0xbf]
24 @ TZ: it eq @ encoding: [0x08,0xbf]
2525 @ TZ: smceq #0 @ encoding: [0xf0,0xf7,0x00,0x80]
30923092 @ SVC
30933093 @------------------------------------------------------------------------------
30943094 svc #0
3095 ite eq
3095 it eq
30963096 svceq #255
3097 it ne
30973098 swine #33
30983099
30993100 @ CHECK: svc #0 @ encoding: [0x00,0xdf]
3100 @ CHECK: ite eq @ encoding: [0x0c,0xbf]
3101 @ CHECK: it eq @ encoding: [0x08,0xbf]
31013102 @ CHECK: svceq #255 @ encoding: [0xff,0xdf]
3103 @ CHECK: it ne @ encoding: [0x18,0xbf]
31023104 @ CHECK: svcne #33 @ encoding: [0x21,0xdf]
31033105
31043106
0 @ RUN: not llvm-mc -triple=thumbv7m--none-eabi < %s 2>&1 | FileCheck %s
1
2 @ These instructions all write to the PC, so are UNPREDICTABLE if they are in
3 @ an IT block, but not the last instruction in the block.
4
5 itttt eq
6 addeq pc, r0
7 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
8 addeq pc, sp, pc
9 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
10 beq.n #.+0x20
11 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
12 nopeq
13 itttt eq
14 beq.w #.+0x20
15 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
16 bleq sym
17 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
18 blxeq r0
19 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
20 nopeq
21 itttt eq
22 bxeq r0
23 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
24 ldmeq r0, {r8, pc}
25 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
26 ldmdbeq r0, {r8, pc}
27 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
28 nopeq
29 itttt eq
30 ldreq pc, [r0, #4]
31 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
32 ldreq pc, [r0, #-4]
33 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
34 ldreq pc, [pc, #4]
35 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
36 nopeq
37 itttt eq
38 ldreq pc, [r0, r1, LSL #1]
39 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
40 moveq pc, r0
41 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
42 popeq {r0, pc}
43 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
44 nopeq
45 itttt eq
46 popeq {r8, pc}
47 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
48 popeq {pc}
49 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
50 tbbeq [r0, r1]
51 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
52 nopeq
53 itt eq
54 tbheq [r0, r1, LSL #1]
55 @ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
56 nopeq