diff options
author | Chris Lattner <sabre@nondot.org> | 2010-11-06 07:06:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-11-06 07:06:09 +0000 |
commit | 3f2c8e474b8775aa1f3c2c0cb817b7f9f564e068 (patch) | |
tree | 3f81fbbd09cc1993058fc7f5abb68b1c9a66ed16 /utils | |
parent | d0f225cafc76ee2d4982c207c6afb25aaf176d12 (diff) | |
download | external_llvm-3f2c8e474b8775aa1f3c2c0cb817b7f9f564e068.zip external_llvm-3f2c8e474b8775aa1f3c2c0cb817b7f9f564e068.tar.gz external_llvm-3f2c8e474b8775aa1f3c2c0cb817b7f9f564e068.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118328 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 45 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 14 |
2 files changed, 25 insertions, 34 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 093c46f..7e6c7b6 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/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/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index f1ba6f7..a2989b1 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/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())); |