aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-10-28 21:28:42 +0000
committerChris Lattner <sabre@nondot.org>2010-10-28 21:28:42 +0000
commit4e692ab5eeb6cf49dbb9ec9ade21cd91b081ba10 (patch)
treefe7c195a93343943e456252835d91cd4ea9f8a50
parentfa42fad8bf7b0058ba031a275e1e8ce53b2cb1ad (diff)
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
-rw-r--r--test/MC/ARM/arm_instructions.s7
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp56
2 files changed, 40 insertions, 23 deletions
diff --git a/test/MC/ARM/arm_instructions.s b/test/MC/ARM/arm_instructions.s
index 8632cb0cef..5335c16e85 100644
--- a/test/MC/ARM/arm_instructions.s
+++ b/test/MC/ARM/arm_instructions.s
@@ -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
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 052e43d839..236c5720b5 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -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.