From: Jim Grosbach Date: Mon, 11 Oct 2010 18:25:51 +0000 (+0000) Subject: When figuring out which operands match which encoding fields in an instruction, X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=01855071e24e0e3e75306b82267d3ad0b13a0c15;p=oota-llvm.git When figuring out which operands match which encoding fields in an instruction, try to match them by name first. If there is no by-name match, fall back to assuming they are in order (this was the previous behavior). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116211 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index a039e0b1e35..1a967e9742c 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -128,7 +128,7 @@ void CodeEmitterGen::run(raw_ostream &o) { // Loop over all of the fields in the instruction, determining which are the // operands to the instruction. - unsigned op = 0; + unsigned NumberedOp = 0; for (unsigned i = 0, e = Vals.size(); i != e; ++i) { if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) { // Is the operand continuous? If so, we can just mask and OR it in @@ -154,14 +154,25 @@ void CodeEmitterGen::run(raw_ostream &o) { } if (!gotOp) { - /// If this operand is not supposed to be emitted by the generated - /// emitter, skip it. - while (CGI.isFlatOperandNotEmitted(op)) - ++op; + + // If the operand matches by name, reference according to that + // operand number. Non-matching operands are assumed to be in + // order. + unsigned OpIdx; + if (CGI.hasOperandNamed(VarName, OpIdx)) { + assert (!CGI.isFlatOperandNotEmitted(OpIdx) && + "Explicitly used operand also marked as not emitted!"); + } else { + /// If this operand is not supposed to be emitted by the + /// generated emitter, skip it. + while (CGI.isFlatOperandNotEmitted(NumberedOp)) + ++NumberedOp; + OpIdx = NumberedOp++; + } Case += " // op: " + VarName + "\n" + " op = getMachineOpValue(MI, MI.getOperand(" - + utostr(op++) + "));\n"; + + utostr(OpIdx) + "));\n"; gotOp = true; } diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 01a1fe11f53..722ae53ed50 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -234,13 +234,26 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) /// specified name, throw an exception. /// unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { - assert(!Name.empty() && "Cannot search for operand with no name!"); - for (unsigned i = 0, e = OperandList.size(); i != e; ++i) - if (OperandList[i].Name == Name) return i; + unsigned OpIdx; + if (hasOperandNamed(Name, OpIdx)) return OpIdx; throw "Instruction '" + TheDef->getName() + "' does not have an operand named '$" + Name + "'!"; } +/// hasOperandNamed - Query whether the instruction has an operand of the +/// given name. If so, return true and set OpIdx to the index of the +/// operand. Otherwise, return false. +bool CodeGenInstruction::hasOperandNamed(const std::string &Name, + unsigned &OpIdx) const { + assert(!Name.empty() && "Cannot search for operand with no name!"); + for (unsigned i = 0, e = OperandList.size(); i != e; ++i) + if (OperandList[i].Name == Name) { + OpIdx = i; + return true; + } + return false; +} + std::pair CodeGenInstruction::ParseOperandName(const std::string &Op, bool AllowWholeOp) { diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 254cfed073f..049e694006a 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -186,6 +186,11 @@ namespace llvm { /// specified name, throw an exception. unsigned getOperandNamed(const std::string &Name) const; + /// hasOperandNamed - Query whether the instruction has an operand of the + /// given name. If so, return true and set OpIdx to the index of the + /// operand. Otherwise, return false. + bool hasOperandNamed(const std::string &Name, unsigned &OpIdx) const; + /// HasOneImplicitDefWithKnownVT - If the instruction has at least one /// implicit def and it has a known VT, return the VT, otherwise return /// MVT::Other.