From 3f2c8e474b8775aa1f3c2c0cb817b7f9f564e068 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 6 Nov 2010 07:06:09 +0000 Subject: [PATCH] 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 --- utils/TableGen/AsmMatcherEmitter.cpp | 45 +++++++-------------------- 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 093c46fabd1..7e6c7b6b8b5 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(); - - // 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 f1ba6f7200f..a2989b116d8 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 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 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())); -- 2.34.1