summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-11-15 23:23:02 +0000
committerChris Lattner <sabre@nondot.org>2006-11-15 23:23:02 +0000
commitf64f9a4b75d07819866bfcf918b922a76d3e1600 (patch)
treed3fdce7cae19e5acb2baa98bdff25c7b244a4945 /utils
parentfa326c709fdd73dcaa4802e35d65e519d6cc3b23 (diff)
Remove the isTwoAddress property from the CodeGenInstruction class. It should
not be used for anything other than backwards compat constraint handling. Add support for a new DisableEncoding property which contains a list of registers that should not be encoded by the generated code emitter. Convert the codeemitter generator to use this, fixing some PPC JIT regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31769 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp11
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp18
-rw-r--r--utils/TableGen/CodeGenInstruction.h25
-rw-r--r--utils/TableGen/CodeGenTarget.cpp18
4 files changed, 53 insertions, 19 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 6466b5fecd9..c8af097250d 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -220,16 +220,11 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
unsigned OpNo = CGI.getOperandNamed(VarName);
CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
- // If this is a two-address instruction, verify the second operand isn't
- // used.
- unsigned MIOp = OpInfo.MIOperandNo;
- if (CGI.isTwoAddress && MIOp == 1)
- throw "Should refer to operand #0 instead of #1 for two-address"
- " instruction '" + CGI.TheDef->getName() + "'!";
-
- if (CurVariant == Variant || CurVariant == ~0U)
+ if (CurVariant == Variant || CurVariant == ~0U) {
+ unsigned MIOp = OpInfo.MIOperandNo;
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
Modifier));
+ }
}
LastEmitted = VarEnd;
}
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index bc415fcc1db..c64b5f454d2 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -125,7 +125,8 @@ void CodeEmitterGen::run(std::ostream &o) {
BitsInit *BI = R->getValueAsBitsInit("Inst");
const std::vector<RecordVal> &Vals = R->getValues();
-
+ CodeGenInstruction &CGI = Target.getInstruction(InstName);
+
// Loop over all of the fields in the instruction, determining which are the
// operands to the instruction.
unsigned op = 0;
@@ -154,16 +155,15 @@ void CodeEmitterGen::run(std::ostream &o) {
}
if (!gotOp) {
+ /// If this operand is not supposed to be emitted by the generated
+ /// emitter, skip it.
+ while (CGI.isFlatOperandNotEmitted(op))
+ ++op;
+
Case += " // op: " + VarName + "\n"
+ " op = getMachineOpValue(MI, MI.getOperand("
- + utostr(op++)
- + "));\n";
+ + utostr(op++) + "));\n";
gotOp = true;
-
- // If this is a two-address instruction and we just got the dest
- // op, skip the src op.
- if (op == 1 && Target.getInstruction(InstName).isTwoAddress)
- ++op;
}
unsigned opMask = (1 << N) - 1;
@@ -185,7 +185,7 @@ void CodeEmitterGen::run(std::ostream &o) {
}
}
- std::vector<std::string> &InstList = CaseMap[Case];
+ std::vector<std::string> &InstList = CaseMap[Case];
InstList.push_back(InstName);
}
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index d99af1b67a3..e0d6b9837e4 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -57,6 +57,11 @@ namespace llvm {
unsigned MIOperandNo;
unsigned MINumOperands; // The number of operands.
+ /// DoNotEncode - Bools are set to true in this vector for each operand in
+ /// the DisableEncoding list. These should not be emitted by the code
+ /// emitter.
+ std::vector<bool> DoNotEncode;
+
/// MIOperandInfo - Default MI operand type. Note an operand may be made
/// up of multiple MI operands.
DagInit *MIOperandInfo;
@@ -82,7 +87,6 @@ namespace llvm {
bool isCall;
bool isLoad;
bool isStore;
- bool isTwoAddress;
bool isPredicated;
bool isConvertibleToThreeAddress;
bool isCommutable;
@@ -107,6 +111,25 @@ namespace llvm {
return OperandList[Op.first].MIOperandNo + Op.second;
}
+ /// getSubOperandNumber - Unflatten a operand number into an
+ /// operand/suboperand pair.
+ std::pair<unsigned,unsigned> getSubOperandNumber(unsigned Op) const {
+ for (unsigned i = 0; ; ++i) {
+ assert(i < OperandList.size() && "Invalid flat operand #");
+ if (OperandList[i].MIOperandNo+OperandList[i].MINumOperands > Op)
+ return std::make_pair(i, Op-OperandList[i].MIOperandNo);
+ }
+ }
+
+
+ /// isFlatOperandNotEmitted - Return true if the specified flat operand #
+ /// should not be emitted with the code emitter.
+ bool isFlatOperandNotEmitted(unsigned FlatOpNo) const {
+ std::pair<unsigned,unsigned> Op = getSubOperandNumber(FlatOpNo);
+ if (OperandList[Op.first].DoNotEncode.size() > Op.second)
+ return OperandList[Op.first].DoNotEncode[Op.second];
+ return false;
+ }
CodeGenInstruction(Record *R, const std::string &AsmStr);
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 2281519ad14..4613c1ba248 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -343,7 +343,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
isCall = R->getValueAsBit("isCall");
isLoad = R->getValueAsBit("isLoad");
isStore = R->getValueAsBit("isStore");
- isTwoAddress = R->getValueAsBit("isTwoAddress");
+ bool isTwoAddress = R->getValueAsBit("isTwoAddress");
isPredicated = false; // set below.
isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
isCommutable = R->getValueAsBit("isCommutable");
@@ -413,6 +413,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
MIOperandNo += NumOps;
}
+ // Parse Constraints.
ParseConstraints(R->getValueAsString("Constraints"), this);
// For backward compatibility: isTwoAddress means operand 1 is tied to
@@ -430,6 +431,21 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
if (OperandList[op].Constraints[j].empty())
OperandList[op].Constraints[j] = "0";
+
+ // Parse the DisableEncoding field.
+ std::string DisableEncoding = R->getValueAsString("DisableEncoding");
+ while (1) {
+ std::string OpName = getToken(DisableEncoding, " ,\t");
+ if (OpName.empty()) break;
+
+ // Figure out which operand this is.
+ std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
+
+ // Mark the operand as not-to-be encoded.
+ if (Op.second >= OperandList[Op.first].DoNotEncode.size())
+ OperandList[Op.first].DoNotEncode.resize(Op.second+1);
+ OperandList[Op.first].DoNotEncode[Op.second] = true;
+ }
}