summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-06 07:06:09 +0000
committerChris Lattner <sabre@nondot.org>2010-11-06 07:06:09 +0000
commitb625dd2d8725234496fa1b1a785f6f9ec98ed58c (patch)
tree27cc545dcdfeac17cecb6e5c2a7589b3908e0a17
parent7603052d4928f550e59ebca8c225a77c3fa42cfa (diff)
downloadbcm5719-llvm-b625dd2d8725234496fa1b1a785f6f9ec98ed58c.tar.gz
bcm5719-llvm-b625dd2d8725234496fa1b1a785f6f9ec98ed58c.zip
implement more checking to reject things like:
(someinst GR16:$foo, GR32:$foo) Reimplement BuildAliasOperandReference to be correctly based on the names of operands in the result pattern, instead of on the instruction operand definitions. llvm-svn: 118328
-rw-r--r--llvm/utils/TableGen/AsmMatcherEmitter.cpp45
-rw-r--r--llvm/utils/TableGen/CodeGenInstruction.cpp14
2 files changed, 25 insertions, 34 deletions
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 093c46fabd1..7e6c7b6b8b5 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -1160,47 +1160,24 @@ BuildInstructionOperandReference(MatchableInfo *II,
Op.SrcOpName = OperandName;
}
+/// BuildAliasOperandReference - When parsing an operand reference out of the
+/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
+/// operand reference is by looking it up in the result pattern definition.
void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
StringRef OperandName,
MatchableInfo::AsmOperand &Op) {
const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
-
- // FIXME: This is a total hack, it should not be a copy of
- // BuildInstructionOperandReference
-
- const CGIOperandList &Operands = CGA.Operands;
-
- // Map this token to an operand. FIXME: Move elsewhere.
- unsigned Idx;
- if (!Operands.hasOperandNamed(OperandName, Idx))
- throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
- OperandName.str() + "'");
-
// Set up the operand class.
- Op.Class = getOperandClass(Operands[Idx]);
-
- // If the named operand is tied, canonicalize it to the untied operand.
- // For example, something like:
- // (outs GPR:$dst), (ins GPR:$src)
- // with an asmstring of
- // "inc $src"
- // we want to canonicalize to:
- // "inc $dst"
- // so that we know how to provide the $dst operand when filling in the result.
- int OITied = Operands[Idx].getTiedRegister();
- if (OITied != -1) {
- // The tied operand index is an MIOperand index, find the operand that
- // contains it.
- for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
- if (Operands[i].MIOperandNo == unsigned(OITied)) {
- OperandName = Operands[i].Name;
- break;
- }
+ for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
+ if (CGA.ResultOperands[i].Name == OperandName) {
+ Op.Class = getOperandClass(CGA.ResultInst->Operands[i]);
+ Op.SrcOpName = OperandName;
+ return;
}
- }
-
- Op.SrcOpName = OperandName;
+
+ throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+ OperandName.str() + "'");
}
void MatchableInfo::BuildResultOperands() {
diff --git a/llvm/utils/TableGen/CodeGenInstruction.cpp b/llvm/utils/TableGen/CodeGenInstruction.cpp
index f1ba6f7200f..a2989b116d8 100644
--- a/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -15,6 +15,7 @@
#include "CodeGenTarget.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
#include <set>
using namespace llvm;
@@ -407,6 +408,10 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
" arguments, but " + ResultInst->TheDef->getName() +
" instruction expects " + utostr(ResultInst->Operands.size())+
" operands!");
+
+ // NameClass - If argument names are repeated, we need to verify they have
+ // the same class.
+ StringMap<Record*> NameClass;
// Decode and validate the arguments of the result.
for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
@@ -425,6 +430,15 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
", instruction operand is class " +
ResultInst->Operands[i].Rec->getName());
+ // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
+ // $foo can exist multiple times in the result list, but it must have the
+ // same type.
+ Record *&Entry = NameClass[Result->getArgName(i)];
+ if (Entry && Entry != ADI->getDef())
+ throw TGError(R->getLoc(), "result value $" + Result->getArgName(i) +
+ " is both " + Entry->getName() + " and " +
+ ADI->getDef()->getName() + "!");
+
// Now that it is validated, add it.
ResultOperands.push_back(ResultOperand(Result->getArgName(i),
ADI->getDef()));
OpenPOWER on IntegriCloud