fix the asmmatcher generator to handle targets with no RegisterPrefix

(like ARM) correctly.  With this change, we can now match "bx lr"
because we recognize lr as a register.

llvm-svn: 117606
This commit is contained in:
Chris Lattner 2010-10-28 21:28:42 +00:00
parent 9487de6160
commit 1be0697ab9
2 changed files with 40 additions and 23 deletions

View File

@ -1,8 +1,13 @@
@ RUN: llvm-mc -triple arm-unknown-unknown %s | FileCheck %s
@ RUN: llvm-mc -triple arm-unknown-unknown -show-encoding %s | FileCheck %s
@ CHECK: nop
@ CHECK: encoding: [0x00,0xf0,0x20,0xe3]
nop
@ CHECK: nopeq
@ CHECK: encoding: [0x00,0xf0,0x20,0x03]
nopeq
@ CHECK: bx lr
@ CHECK: encoding: [0x1e,0xff,0x2f,0xe1]
bx lr

View File

@ -941,21 +941,25 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
continue;
// Collect singleton registers, if used.
if (!RegisterPrefix.empty()) {
for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
if (II->Tokens[i].startswith(RegisterPrefix)) {
StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
Record *Rec = getRegisterRecord(Target, RegName);
if (!Rec) {
std::string Err = "unable to find register for '" + RegName.str() +
"' (which matches register prefix)";
throw TGError(CGI.TheDef->getLoc(), Err);
}
SingletonRegisterNames.insert(RegName);
}
for (unsigned i = 0, e = II->Tokens.size(); i != e; ++i) {
if (!II->Tokens[i].startswith(RegisterPrefix))
continue;
StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
Record *Rec = getRegisterRecord(Target, RegName);
if (!Rec) {
// If there is no register prefix (i.e. "%" in "%eax"), then this may
// be some random non-register token, just ignore it.
if (RegisterPrefix.empty())
continue;
std::string Err = "unable to find register for '" + RegName.str() +
"' (which matches register prefix)";
throw TGError(CGI.TheDef->getLoc(), Err);
}
SingletonRegisterNames.insert(RegName);
}
// Compute the require features.
@ -1008,15 +1012,23 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
StringRef Token = II->Tokens[i];
// Check for singleton registers.
if (!RegisterPrefix.empty() && Token.startswith(RegisterPrefix)) {
if (Token.startswith(RegisterPrefix)) {
StringRef RegName = II->Tokens[i].substr(RegisterPrefix.size());
InstructionInfo::Operand Op;
Op.Class = RegisterClasses[getRegisterRecord(Target, RegName)];
Op.OperandInfo = 0;
assert(Op.Class && Op.Class->Registers.size() == 1 &&
"Unexpected class for singleton register");
II->Operands.push_back(Op);
continue;
if (Record *RegRecord = getRegisterRecord(Target, RegName)) {
InstructionInfo::Operand Op;
Op.Class = RegisterClasses[RegRecord];
Op.OperandInfo = 0;
assert(Op.Class && Op.Class->Registers.size() == 1 &&
"Unexpected class for singleton register");
II->Operands.push_back(Op);
continue;
}
if (!RegisterPrefix.empty()) {
std::string Err = "unable to find register for '" + RegName.str() +
"' (which matches register prefix)";
throw TGError(II->Instr->TheDef->getLoc(), Err);
}
}
// Check for simple tokens.