summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp11
-rw-r--r--llvm/test/MC/ARM/arm-thumb-trustzone.s4
-rw-r--r--llvm/test/MC/ARM/basic-thumb2-instructions.s6
-rw-r--r--llvm/test/MC/ARM/unpred-control-flow-in-it-block.s57
4 files changed, 70 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 03e1d447b66..dae8618fa07 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6305,10 +6305,6 @@ bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
else if (ListContainsPC && ListContainsLR)
return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
"PC and LR may not be in the register list simultaneously");
- else if (inITBlock() && !lastInITBlock() && ListContainsPC)
- return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
- "instruction must be outside of IT block or the last "
- "instruction in an IT block");
return false;
}
@@ -6370,6 +6366,12 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
return Warning(Loc, "predicated instructions should be in IT block");
}
+ // PC-setting instructions in an IT block, but not the last instruction of
+ // the block, are UNPREDICTABLE.
+ if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
+ return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
+ }
+
const unsigned Opcode = Inst.getOpcode();
switch (Opcode) {
case ARM::LDRD:
@@ -9013,6 +9015,7 @@ bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
// operands. We only care about Thumb instructions here, as ARM instructions
// obviously can't be in an IT block.
switch (Inst.getOpcode()) {
+ case ARM::tLDMIA:
case ARM::t2LDMIA:
case ARM::t2LDMIA_UPD:
case ARM::t2LDMDB:
diff --git a/llvm/test/MC/ARM/arm-thumb-trustzone.s b/llvm/test/MC/ARM/arm-thumb-trustzone.s
index 4fec4b7e982..de38c7f15e0 100644
--- a/llvm/test/MC/ARM/arm-thumb-trustzone.s
+++ b/llvm/test/MC/ARM/arm-thumb-trustzone.s
@@ -16,11 +16,11 @@ _func:
@ SMC
@------------------------------------------------------------------------------
smc #0xf
- ite eq
+ it eq
smceq #0
@ NOTZ-NOT: smc #15
@ NOTZ-NOT: smceq #0
@ TZ: smc #15 @ encoding: [0xff,0xf7,0x00,0x80]
-@ TZ: ite eq @ encoding: [0x0c,0xbf]
+@ TZ: it eq @ encoding: [0x08,0xbf]
@ TZ: smceq #0 @ encoding: [0xf0,0xf7,0x00,0x80]
diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s
index 1ef0d8eb11b..af1b6289755 100644
--- a/llvm/test/MC/ARM/basic-thumb2-instructions.s
+++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s
@@ -3093,13 +3093,15 @@ _func:
@ SVC
@------------------------------------------------------------------------------
svc #0
- ite eq
+ it eq
svceq #255
+ it ne
swine #33
@ CHECK: svc #0 @ encoding: [0x00,0xdf]
-@ CHECK: ite eq @ encoding: [0x0c,0xbf]
+@ CHECK: it eq @ encoding: [0x08,0xbf]
@ CHECK: svceq #255 @ encoding: [0xff,0xdf]
+@ CHECK: it ne @ encoding: [0x18,0xbf]
@ CHECK: svcne #33 @ encoding: [0x21,0xdf]
diff --git a/llvm/test/MC/ARM/unpred-control-flow-in-it-block.s b/llvm/test/MC/ARM/unpred-control-flow-in-it-block.s
new file mode 100644
index 00000000000..885d158d83d
--- /dev/null
+++ b/llvm/test/MC/ARM/unpred-control-flow-in-it-block.s
@@ -0,0 +1,57 @@
+@ RUN: not llvm-mc -triple=thumbv7m--none-eabi < %s 2>&1 | FileCheck %s
+
+@ These instructions all write to the PC, so are UNPREDICTABLE if they are in
+@ an IT block, but not the last instruction in the block.
+
+ itttt eq
+ addeq pc, r0
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ addeq pc, sp, pc
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ beq.n #.+0x20
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itttt eq
+ beq.w #.+0x20
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ bleq sym
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ blxeq r0
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itttt eq
+ bxeq r0
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ ldmeq r0, {r8, pc}
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ ldmdbeq r0, {r8, pc}
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itttt eq
+ ldreq pc, [r0, #4]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ ldreq pc, [r0, #-4]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ ldreq pc, [pc, #4]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itttt eq
+ ldreq pc, [r0, r1, LSL #1]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ moveq pc, r0
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ popeq {r0, pc}
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itttt eq
+ popeq {r8, pc}
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ popeq {pc}
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ tbbeq [r0, r1]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
+ itt eq
+ tbheq [r0, r1, LSL #1]
+@ CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction must be outside of IT block or the last instruction in an IT block
+ nopeq
OpenPOWER on IntegriCloud