[llvm] r223363 - Revert "[Thumb/Thumb2] Added restrictions on PC, LR, SP in the register list for PUSH/POP/LDM/STM. <Differential Revision: http://reviews.llvm.org/D6090>"
Rafael Espindola
rafael.espindola at gmail.com
Thu Dec 4 06:10:20 PST 2014
Author: rafael
Date: Thu Dec 4 08:10:20 2014
New Revision: 223363
URL: http://llvm.org/viewvc/llvm-project?rev=223363&view=rev
Log:
Revert "[Thumb/Thumb2] Added restrictions on PC, LR, SP in the register list for PUSH/POP/LDM/STM. <Differential Revision: http://reviews.llvm.org/D6090>"
This reverts commit r223356.
It was failing check-all (MC/ARM/thumb.s in particular).
Modified:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/thumb-diagnostics.s
llvm/trunk/test/MC/ARM/thumb2-diagnostics.s
llvm/trunk/test/MC/ARM/v8_IT_manual.s
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=223363&r1=223362&r2=223363&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Dec 4 08:10:20 2014
@@ -174,11 +174,6 @@ class ARMAsmParser : public MCTargetAsmP
ITState.CurPosition = ~0U; // Done with the IT block after this.
}
- bool lastInITBlock() {
- unsigned TZ = countTrailingZeros(ITState.Mask);
- return (ITState.CurPosition == 4 - TZ);
- }
-
void Note(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = None) {
return getParser().Note(L, Msg, Ranges);
}
@@ -327,8 +322,6 @@ class ARMAsmParser : public MCTargetAsmP
bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
- bool validateRegListOperands(MCInst &Inst, const OperandVector &Operands,
- unsigned OpNo);
public:
enum ARMMatchResultTy {
@@ -5984,138 +5977,13 @@ static bool checkLowRegisterList(MCInst
return false;
}
-// Check if there are any special registers in the register list of the inst,
+// Check if the specified regisgter is in the register list of the inst,
// starting at the indicated operand number.
-static void findSpecialRegsInList(MCInst &Inst, unsigned OpNo, bool &SP,
- bool &PC, bool &LR, bool &BaseReg) {
- SP = PC = LR = BaseReg = false;
- unsigned Rn = Inst.getOperand(0).getReg();
+static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
unsigned OpReg = Inst.getOperand(i).getReg();
- if (OpReg == ARM::SP)
- SP = true;
- else if (OpReg == ARM::PC)
- PC = true;
- else if (OpReg == ARM::LR)
- LR = true;
- if (OpReg == Rn)
- BaseReg = true;
- }
-
- return;
-}
-
-bool ARMAsmParser::validateRegListOperands(MCInst &Inst,
- const OperandVector &Operands,
- unsigned OpNo) {
- bool SP, PC, LR, BaseReg, LowReg, listContainsBase = false;
- const unsigned Opcode = Inst.getOpcode();
- unsigned Rn = Inst.getOperand(0).getReg();
- findSpecialRegsInList(Inst, OpNo, SP, PC, LR, BaseReg);
- LowReg = checkLowRegisterList(Inst, OpNo, Rn, 0, listContainsBase);
-
- switch (Opcode) {
- case ARM::t2LDMIA_UPD:
- case ARM::t2LDMDB_UPD: {
- if (BaseReg)
- return Error(Operands.back()->getStartLoc(),
- "writeback register not allowed in register list");
- }
- case ARM::tLDMIA: {
- // If we're parsing Thumb2, the .w variant is available and handles
- // most cases that are normally illegal for a Thumb1 LDM instruction.
- // We'll make the transformation in processInstruction() if necessary.
- //
- // Thumb LDM instructions are writeback iff the base register is not
- // in the register list.
- bool HasWritebackToken =
- (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
- static_cast<ARMOperand &>(*Operands[3]).getToken() == "!");
-
- if (LowReg && !isThumbTwo())
- return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
- "registers must be in range r0-r7");
- // If we should have writeback, then there should be a '!' token.
- if (!BaseReg && !HasWritebackToken && !isThumbTwo())
- return Error(Operands[2]->getStartLoc(),
- "writeback operator '!' expected");
-
- // If we should not have writeback, there must not be a '!'. This is
- // true even for the 32-bit wide encodings.
- if (BaseReg && HasWritebackToken)
- return Error(Operands[3]->getStartLoc(),
- "writeback operator '!' not allowed when base register "
- "in register list");
- }
- case ARM::tPOP: {
- if (LowReg && !PC && !isThumbTwo())
- return Error(Operands[2]->getStartLoc(),
- "registers must be in range r0-r7 or pc");
- }
- case ARM::t2LDMIA:
- case ARM::t2LDMDB: {
- if (SP)
- return Error(Operands[OpNo]->getStartLoc(),
- "SP not allowed in register list");
- if (PC && LR)
- return Error(
- Operands[OpNo]->getStartLoc(),
- "LR not allowed in the list, when PC is in the register list");
- if (PC && inITBlock() && !lastInITBlock())
- return Error(Operands[OpNo]->getStartLoc(),
- "Instruction should be outside an IT block or last in IT "
- "block, when PC is in the register list");
- break;
- }
- case ARM::t2STMIA_UPD:
- case ARM::t2STMDB_UPD: {
- if (BaseReg)
- return Error(Operands.back()->getStartLoc(),
- "writeback register not allowed in register list");
- }
- case ARM::tSTMIA_UPD: {
- if (LowReg && !isThumbTwo())
- return Error(Operands[4]->getStartLoc(),
- "registers must be in range r0-r7");
-
- // This would be converted to a 32-bit stm, but that's not valid if the
- // writeback register is in the list.
- if (LowReg && BaseReg)
- return Error(Operands[4]->getStartLoc(),
- "writeback operator '!' not allowed when base register "
- "in register list");
- }
- case ARM::tPUSH: {
- if (LowReg && !LR && !isThumbTwo())
- return Error(Operands[2]->getStartLoc(),
- "registers must be in range r0-r7 or lr");
- }
- case ARM::t2STMIA:
- case ARM::t2STMDB: {
- if (SP || PC)
- return Error(Operands[OpNo]->getStartLoc(),
- "SP, PC not allowed in register list");
- break;
- }
- case ARM::LDMIA_UPD:
- case ARM::LDMDB_UPD:
- case ARM::LDMIB_UPD:
- case ARM::LDMDA_UPD: {
- if (BaseReg)
- return Error(Operands.back()->getStartLoc(),
- "writeback register not allowed in register list");
- break;
- }
- case ARM::sysLDMIA_UPD:
- case ARM::sysLDMDA_UPD:
- case ARM::sysLDMDB_UPD:
- case ARM::sysLDMIB_UPD: {
- if (!PC)
- return Error(Operands[4]->getStartLoc(),
- "writeback register only allowed on system LDM "
- "if PC in register-list");
- break;
- }
+ if (OpReg == Reg)
+ return true;
}
return false;
}
@@ -6287,6 +6155,37 @@ bool ARMAsmParser::validateInstruction(M
"bitfield width must be in range [1,32-lsb]");
return false;
}
+ // Notionally handles ARM::tLDMIA_UPD too.
+ case ARM::tLDMIA: {
+ // If we're parsing Thumb2, the .w variant is available and handles
+ // most cases that are normally illegal for a Thumb1 LDM instruction.
+ // We'll make the transformation in processInstruction() if necessary.
+ //
+ // Thumb LDM instructions are writeback iff the base register is not
+ // in the register list.
+ unsigned Rn = Inst.getOperand(0).getReg();
+ bool HasWritebackToken =
+ (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
+ static_cast<ARMOperand &>(*Operands[3]).getToken() == "!");
+ bool ListContainsBase;
+ if (checkLowRegisterList(Inst, 3, Rn, 0, ListContainsBase) && !isThumbTwo())
+ return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
+ "registers must be in range r0-r7");
+ // If we should have writeback, then there should be a '!' token.
+ if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
+ return Error(Operands[2]->getStartLoc(),
+ "writeback operator '!' expected");
+ // If we should not have writeback, there must not be a '!'. This is
+ // true even for the 32-bit wide encodings.
+ if (ListContainsBase && HasWritebackToken)
+ return Error(Operands[3]->getStartLoc(),
+ "writeback operator '!' not allowed when base register "
+ "in register list");
+ if (listContainsReg(Inst, 3 + HasWritebackToken, ARM::SP))
+ return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
+ "SP not allowed in register list");
+ break;
+ }
case ARM::LDMIA_UPD:
case ARM::LDMDB_UPD:
case ARM::LDMIB_UPD:
@@ -6295,22 +6194,41 @@ bool ARMAsmParser::validateInstruction(M
// UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
if (!hasV7Ops())
break;
- case ARM::tLDMIA: // Notionally handles ARM::tLDMIA_UPD too.
+ if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
+ return Error(Operands.back()->getStartLoc(),
+ "writeback register not allowed in register list");
+ break;
case ARM::t2LDMIA:
case ARM::t2LDMDB:
case ARM::t2STMIA:
- case ARM::t2STMDB:
+ case ARM::t2STMDB: {
+ if (listContainsReg(Inst, 3, ARM::SP))
+ return Error(Operands.back()->getStartLoc(),
+ "SP not allowed in register list");
+ break;
+ }
case ARM::t2LDMIA_UPD:
case ARM::t2LDMDB_UPD:
case ARM::t2STMIA_UPD:
- case ARM::t2STMDB_UPD:
+ case ARM::t2STMDB_UPD: {
+ if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
+ return Error(Operands.back()->getStartLoc(),
+ "writeback register not allowed in register list");
+
+ if (listContainsReg(Inst, 4, ARM::SP))
+ return Error(Operands.back()->getStartLoc(),
+ "SP not allowed in register list");
+ break;
+ }
case ARM::sysLDMIA_UPD:
case ARM::sysLDMDA_UPD:
case ARM::sysLDMDB_UPD:
- case ARM::sysLDMIB_UPD: {
- validateRegListOperands(Inst, Operands, 3);
+ case ARM::sysLDMIB_UPD:
+ if (!listContainsReg(Inst, 3, ARM::PC))
+ return Error(Operands[4]->getStartLoc(),
+ "writeback register only allowed on system LDM "
+ "if PC in register-list");
break;
- }
case ARM::sysSTMIA_UPD:
case ARM::sysSTMDA_UPD:
case ARM::sysSTMDB_UPD:
@@ -6338,13 +6256,39 @@ bool ARMAsmParser::validateInstruction(M
// Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
// so only issue a diagnostic for thumb1. The instructions will be
// switched to the t2 encodings in processInstruction() if necessary.
- case ARM::tPOP:
+ case ARM::tPOP: {
+ bool ListContainsBase;
+ if (checkLowRegisterList(Inst, 2, 0, ARM::PC, ListContainsBase) &&
+ !isThumbTwo())
+ return Error(Operands[2]->getStartLoc(),
+ "registers must be in range r0-r7 or pc");
+ break;
+ }
case ARM::tPUSH: {
- validateRegListOperands(Inst, Operands, 2);
+ bool ListContainsBase;
+ if (checkLowRegisterList(Inst, 2, 0, ARM::LR, ListContainsBase) &&
+ !isThumbTwo())
+ return Error(Operands[2]->getStartLoc(),
+ "registers must be in range r0-r7 or lr");
break;
}
case ARM::tSTMIA_UPD: {
- validateRegListOperands(Inst, Operands, 4);
+ bool ListContainsBase, InvalidLowList;
+ InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
+ 0, ListContainsBase);
+ if (InvalidLowList && !isThumbTwo())
+ return Error(Operands[4]->getStartLoc(),
+ "registers must be in range r0-r7");
+
+ // This would be converted to a 32-bit stm, but that's not valid if the
+ // writeback register is in the list.
+ if (InvalidLowList && ListContainsBase)
+ return Error(Operands[4]->getStartLoc(),
+ "writeback operator '!' not allowed when base register "
+ "in register list");
+ if (listContainsReg(Inst, 4, ARM::SP) && !inITBlock())
+ return Error(Operands.back()->getStartLoc(),
+ "SP not allowed in register list");
break;
}
case ARM::tADDrSP: {
Modified: llvm/trunk/test/MC/ARM/thumb-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-diagnostics.s?rev=223363&r1=223362&r2=223363&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s Thu Dec 4 08:10:20 2014
@@ -68,7 +68,6 @@ error: invalid operand for instruction
ldmfd r2!, {r1, r3-r6, sp}
ldmdb r1, {r2, r3, sp}
ldmdb r1!, {r2, r3, sp}
- ldm r2, {r5, lr, pc}
@ CHECK-ERRORS: error: registers must be in range r0-r7
@ CHECK-ERRORS: ldm r2!, {r5, r8}
@ CHECK-ERRORS: ^
@@ -105,31 +104,16 @@ error: invalid operand for instruction
@ CHECK-ERRORS-V7M: error: SP not allowed in register list
@ CHECK-ERRORS-V7M: ldmdb r1!, {r2, r3, sp}
@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: LR not allowed in the list, when PC is in the register list
-@ CHECK-ERRORS-V7M: ldm r2, {r5, lr, pc}
-@ CHECK-ERRORS-V7M: ^
@ Invalid writeback and register lists for PUSH/POP
pop {r1, r2, r10}
- pop {r1, r2, lr, pc}
push {r8, r9}
- push {r8, r9, sp}
- push {r8, r9, pc}
@ CHECK-ERRORS: error: registers must be in range r0-r7 or pc
@ CHECK-ERRORS: pop {r1, r2, r10}
@ CHECK-ERRORS: ^
-@ CHECK-ERRORS-V7M: error: LR not allowed in the list, when PC is in the register list
-@ CHECK-ERRORS-V7M: pop {r1, r2, lr, pc}
-@ CHECK-ERRORS-V7M: ^
@ CHECK-ERRORS: error: registers must be in range r0-r7 or lr
@ CHECK-ERRORS: push {r8, r9}
@ CHECK-ERRORS: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
-@ CHECK-ERRORS-V7M: push {r8, r9, sp}
-@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
-@ CHECK-ERRORS-V7M: push {r8, r9, pc}
-@ CHECK-ERRORS-V7M: ^
@ Invalid writeback and register lists for STM
@@ -141,8 +125,6 @@ error: invalid operand for instruction
stmia r4!, {r0-r3, sp}
stmdb r1, {r2, r3, sp}
stmdb r1!, {r2, r3, sp}
- stmia r4, {r2, sp, pc}
- stmdb r1!, {r2, r3, pc}
@ CHECK-ERRORS: error: instruction requires: thumb2
@ CHECK-ERRORS: stm r1, {r2, r6}
@ CHECK-ERRORS: ^
@@ -155,24 +137,18 @@ error: invalid operand for instruction
@ CHECK-ERRORS-V8: error: writeback register not allowed in register list
@ CHECK-ERRORS-V8: stmdb r2!, {r0, r2}
@ CHECK-ERRORS-V8: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
+@ CHECK-ERRORS-V7M: error: SP not allowed in register list
@ CHECK-ERRORS-V7M: stm r1!, {r2, sp}
@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
+@ CHECK-ERRORS-V7M: error: SP not allowed in register list
@ CHECK-ERRORS-V7M: stmia r4!, {r0-r3, sp}
@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
+@ CHECK-ERRORS-V7M: error: SP not allowed in register list
@ CHECK-ERRORS-V7M: stmdb r1, {r2, r3, sp}
@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
+@ CHECK-ERRORS-V7M: error: SP not allowed in register list
@ CHECK-ERRORS-V7M: stmdb r1!, {r2, r3, sp}
@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
-@ CHECK-ERRORS-V7M: stmia r4, {r2, sp, pc}
-@ CHECK-ERRORS-V7M: ^
-@ CHECK-ERRORS-V7M: error: SP, PC not allowed in register list
-@ CHECK-ERRORS-V7M: stmdb r1!, {r2, r3, pc}
-@ CHECK-ERRORS-V7M: ^
@ Out of range immediates for LSL instruction.
lsls r4, r5, #-1
Modified: llvm/trunk/test/MC/ARM/thumb2-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb2-diagnostics.s?rev=223363&r1=223362&r2=223363&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb2-diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/thumb2-diagnostics.s Thu Dec 4 08:10:20 2014
@@ -9,9 +9,6 @@
iteeee gt
ittfe le
nopeq
- ite eq
- ldmiaeq sp!, {r4, pc}
- movne r0, #0
@ CHECK-ERRORS: error: incorrect condition in IT block; got 'le', but expected 'eq'
@ CHECK-ERRORS: addle r0, r1, r2
@@ -31,9 +28,6 @@
@ CHECK-ERRORS: error: predicated instructions must be in IT block
@ CHECK-ERRORS: nopeq
@ CHECK-ERRORS: ^
-@ CHECK-ERRORS: error: Instruction should be outside an IT block or last in IT block, when PC is in the register list
-@ CHECK-ERRORS: ldmiaeq sp!, {r4, pc}
-@ CHECK-ERRORS: ^
@ Out of range immediates for MRC/MRC2/MRRC/MRRC2
mrc p14, #8, r1, c1, c2, #4
Modified: llvm/trunk/test/MC/ARM/v8_IT_manual.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/v8_IT_manual.s?rev=223363&r1=223362&r2=223363&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/v8_IT_manual.s (original)
+++ llvm/trunk/test/MC/ARM/v8_IT_manual.s Thu Dec 4 08:10:20 2014
@@ -554,11 +554,11 @@ pushge {r1, r3, r7}
@ PUSH, encoding T2 (32-bit)
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
it ge
-pushge {r1, r3, r7}
+pushge {r1, r13, r7}
@ PUSH, encoding T3 (32-bit)
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
it ge
-pushge {r3}
+pushge {r13}
@ REV, encoding T1
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
@@ -614,10 +614,9 @@ stmge r1!, {r2, r3}
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
it ge
stmge r1, {r2, r3}
-@ STM, encoding T3 (32-bit)
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
it ge
-stmge r1!, {r2}
+stmge r1!, {r2, r13}
@ LDM, encoding T1
@ CHECK: [[@LINE+2]]:1: warning: deprecated instruction in IT block
More information about the llvm-commits
mailing list