Factor low reg checking into a helper function.

llvm-svn: 138344
This commit is contained in:
Jim Grosbach 2011-08-23 18:13:04 +00:00
parent 551ef45e85
commit 169b2be611
1 changed files with 32 additions and 26 deletions

View File

@ -3047,6 +3047,24 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
} }
// Validate context-sensitive operand constraints. // Validate context-sensitive operand constraints.
// return 'true' if register list contains non-low GPR registers,
// 'false' otherwise. If Reg is in the register list or is HiReg, set
// 'containsReg' to true.
static bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
unsigned HiReg, bool &containsReg) {
containsReg = false;
for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
unsigned OpReg = Inst.getOperand(i).getReg();
if (OpReg == Reg)
containsReg = true;
// Anything other than a low register isn't legal here.
if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
return true;
}
return false;
}
// FIXME: We would really like to be able to tablegen'erate this. // FIXME: We would really like to be able to tablegen'erate this.
bool ARMAsmParser:: bool ARMAsmParser::
validateInstruction(MCInst &Inst, validateInstruction(MCInst &Inst,
@ -3101,22 +3119,16 @@ validateInstruction(MCInst &Inst,
bool hasWritebackToken = bool hasWritebackToken =
(static_cast<ARMOperand*>(Operands[3])->isToken() && (static_cast<ARMOperand*>(Operands[3])->isToken() &&
static_cast<ARMOperand*>(Operands[3])->getToken() == "!"); static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
bool doesWriteback = true; bool listContainsBase;
for (unsigned i = 3; i < Inst.getNumOperands(); ++i) { if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase))
unsigned Reg = Inst.getOperand(i).getReg(); return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
if (Reg == Rn) "registers must be in range r0-r7");
doesWriteback = false;
// Anything other than a low register isn't legal here.
if (!isARMLowRegister(Reg))
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 we should have writeback, then there should be a '!' token.
if (doesWriteback && !hasWritebackToken) if (!listContainsBase && !hasWritebackToken)
return Error(Operands[2]->getStartLoc(), return Error(Operands[2]->getStartLoc(),
"writeback operator '!' expected"); "writeback operator '!' expected");
// Likewise, if we should not have writeback, there must not be a '!' // Likewise, if we should not have writeback, there must not be a '!'
if (!doesWriteback && hasWritebackToken) if (listContainsBase && hasWritebackToken)
return Error(Operands[3]->getStartLoc(), return Error(Operands[3]->getStartLoc(),
"writeback operator '!' not allowed when base register " "writeback operator '!' not allowed when base register "
"in register list"); "in register list");
@ -3124,23 +3136,17 @@ validateInstruction(MCInst &Inst,
break; break;
} }
case ARM::tPOP: { case ARM::tPOP: {
for (unsigned i = 2; i < Inst.getNumOperands(); ++i) { bool listContainsBase;
unsigned Reg = Inst.getOperand(i).getReg(); if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
// Anything other than a low register isn't legal here. return Error(Operands[2]->getStartLoc(),
if (!isARMLowRegister(Reg) && Reg != ARM::PC) "registers must be in range r0-r7 or pc");
return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or pc");
}
break; break;
} }
case ARM::tPUSH: { case ARM::tPUSH: {
for (unsigned i = 2; i < Inst.getNumOperands(); ++i) { bool listContainsBase;
unsigned Reg = Inst.getOperand(i).getReg(); if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
// Anything other than a low register isn't legal here. return Error(Operands[2]->getStartLoc(),
if (!isARMLowRegister(Reg) && Reg != ARM::LR) "registers must be in range r0-r7 or lr");
return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or lr");
}
break; break;
} }
} }