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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117606 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-10-28 21:28:42 +00:00
parent fa42fad8bf
commit 4e692ab5ee
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: nop
@ CHECK: encoding: [0x00,0xf0,0x20,0xe3]
nop nop
@ CHECK: nopeq @ CHECK: nopeq
@ CHECK: encoding: [0x00,0xf0,0x20,0x03]
nopeq nopeq
@ CHECK: bx lr
@ CHECK: encoding: [0x1e,0xff,0x2f,0xe1]
bx lr

View File

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