Index: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6305,10 +6305,6 @@ 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 @@ 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 @@ // 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: Index: llvm/trunk/test/MC/ARM/arm-thumb-trustzone.s =================================================================== --- llvm/trunk/test/MC/ARM/arm-thumb-trustzone.s +++ llvm/trunk/test/MC/ARM/arm-thumb-trustzone.s @@ -16,11 +16,11 @@ @ 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] Index: llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s =================================================================== --- llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s +++ llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s @@ -3093,13 +3093,15 @@ @ 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] Index: llvm/trunk/test/MC/ARM/unpred-control-flow-in-it-block.s =================================================================== --- llvm/trunk/test/MC/ARM/unpred-control-flow-in-it-block.s +++ llvm/trunk/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