summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-10-11 18:25:51 +0000
committerJim Grosbach <grosbach@apple.com>2010-10-11 18:25:51 +0000
commit01855071e24e0e3e75306b82267d3ad0b13a0c15 (patch)
treec2b81646a2418a8740b3bd98825f1e4f2c759af8 /utils
parent40ef4fe82aefc3333f2cdeffb6ad28d9dfaccb8c (diff)
downloadllvm-01855071e24e0e3e75306b82267d3ad0b13a0c15.tar.gz
llvm-01855071e24e0e3e75306b82267d3ad0b13a0c15.tar.bz2
llvm-01855071e24e0e3e75306b82267d3ad0b13a0c15.tar.xz
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
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp23
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp19
-rw-r--r--utils/TableGen/CodeGenInstruction.h5
3 files changed, 38 insertions, 9 deletions
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index a039e0b1e3..1a967e9742 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 01a1fe11f5..722ae53ed5 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<unsigned,unsigned>
CodeGenInstruction::ParseOperandName(const std::string &Op,
bool AllowWholeOp) {
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index 254cfed073..049e694006 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.