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
This commit is contained in:
Jim Grosbach 2010-10-11 18:25:51 +00:00
parent 40ef4fe82a
commit 01855071e2
3 changed files with 38 additions and 9 deletions

View File

@ -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;
}

View File

@ -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<unsigned,unsigned>
CodeGenInstruction::ParseOperandName(const std::string &Op,
bool AllowWholeOp) {

View File

@ -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.