aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-01 04:03:32 +0000
committerChris Lattner <sabre@nondot.org>2010-11-01 04:03:32 +0000
commitc240bb0ede0541426254d0e0dc81d891beda4b22 (patch)
treefb12b77d1960864bcec0d5c0e82e0f99f26541cd
parent79b3cddfa2eeb9ed7f93daf8e4f3c3d87779c3ab (diff)
downloadexternal_llvm-c240bb0ede0541426254d0e0dc81d891beda4b22.zip
external_llvm-c240bb0ede0541426254d0e0dc81d891beda4b22.tar.gz
external_llvm-c240bb0ede0541426254d0e0dc81d891beda4b22.tar.bz2
factor the operand list (and related fields/operations) out of
CodeGenInstruction into its own helper class. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117893 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/ARMDecoderEmitter.cpp4
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp31
-rw-r--r--utils/TableGen/AsmWriterInst.cpp4
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp13
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp34
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp330
-rw-r--r--utils/TableGen/CodeGenInstruction.h160
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp4
-rw-r--r--utils/TableGen/EDEmitter.cpp16
-rw-r--r--utils/TableGen/FastISelEmitter.cpp4
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp32
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp6
-rw-r--r--utils/TableGen/X86RecognizableInstr.h3
13 files changed, 340 insertions, 301 deletions
diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp
index 89b3b83..533fca0 100644
--- a/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/utils/TableGen/ARMDecoderEmitter.cpp
@@ -1763,8 +1763,8 @@ bool ARMDecoderEmitter::ARMDEBackend::populateInstruction(
errs() << '\n';
// Dumps the list of operand info.
- for (unsigned i = 0, e = CGI.OperandList.size(); i != e; ++i) {
- CodeGenInstruction::OperandInfo Info = CGI.OperandList[i];
+ for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) {
+ const CGIOperandList::OperandInfo &Info = CGI.Operands[i];
const std::string &OperandName = Info.Name;
const Record &OperandDef = *Info.Rec;
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index 3f4594c..254a719 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -386,7 +386,7 @@ struct InstructionInfo {
ClassInfo *Class;
/// The original operand this corresponds to, if any.
- const CodeGenInstruction::OperandInfo *OperandInfo;
+ const CGIOperandList::OperandInfo *OperandInfo;
};
/// InstrName - The target name for this instruction.
@@ -536,7 +536,7 @@ private:
/// getOperandClass - Lookup or create the class for the given operand.
ClassInfo *getOperandClass(StringRef Token,
- const CodeGenInstruction::OperandInfo &OI);
+ const CGIOperandList::OperandInfo &OI);
/// BuildRegisterClasses - Build the ClassInfo* instances for register
/// classes.
@@ -587,7 +587,7 @@ void InstructionInfo::dump() {
continue;
}
- const CodeGenInstruction::OperandInfo &OI = *Op.OperandInfo;
+ const CGIOperandList::OperandInfo &OI = *Op.OperandInfo;
errs() << OI.Name << " " << OI.Rec->getName()
<< " (" << OI.MIOperandNo << ", " << OI.MINumOperands << ")\n";
}
@@ -665,7 +665,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
ClassInfo *
AsmMatcherInfo::getOperandClass(StringRef Token,
- const CodeGenInstruction::OperandInfo &OI) {
+ const CGIOperandList::OperandInfo &OI) {
if (OI.Rec->isSubClassOf("RegisterClass")) {
ClassInfo *CI = RegisterClassClasses[OI.Rec];
@@ -945,7 +945,8 @@ void AsmMatcherInfo::BuildInfo() {
Instructions.push_back(II.take());
}
-
+
+
// Build info for the register classes.
BuildRegisterClasses(SingletonRegisters);
@@ -998,7 +999,7 @@ void AsmMatcherInfo::BuildInfo() {
// Map this token to an operand. FIXME: Move elsewhere.
unsigned Idx;
- if (!II->Instr->hasOperandNamed(OperandName, Idx))
+ if (!II->Instr->Operands.hasOperandNamed(OperandName, Idx))
throw std::string("error: unable to find operand: '" +
OperandName.str() + "'");
@@ -1006,15 +1007,15 @@ void AsmMatcherInfo::BuildInfo() {
// XCHG8rm). What we want is the untied operand, which we now have to
// grovel for. Only worry about this for single entry operands, we have to
// clean this up anyway.
- const CodeGenInstruction::OperandInfo *OI = &II->Instr->OperandList[Idx];
+ const CGIOperandList::OperandInfo *OI = &II->Instr->Operands[Idx];
if (OI->Constraints[0].isTied()) {
unsigned TiedOp = OI->Constraints[0].getTiedOperand();
// The tied operand index is an MIOperand index, find the operand that
// contains it.
- for (unsigned i = 0, e = II->Instr->OperandList.size(); i != e; ++i) {
- if (II->Instr->OperandList[i].MIOperandNo == TiedOp) {
- OI = &II->Instr->OperandList[i];
+ for (unsigned i = 0, e = II->Instr->Operands.size(); i != e; ++i) {
+ if (II->Instr->Operands[i].MIOperandNo == TiedOp) {
+ OI = &II->Instr->Operands[i];
break;
}
}
@@ -1086,10 +1087,10 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
// Find any tied operands.
SmallVector<std::pair<unsigned, unsigned>, 4> TiedOperands;
- for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
- const CodeGenInstruction::OperandInfo &OpInfo = II.Instr->OperandList[i];
+ for (unsigned i = 0, e = II.Instr->Operands.size(); i != e; ++i) {
+ const CGIOperandList::OperandInfo &OpInfo = II.Instr->Operands[i];
for (unsigned j = 0, e = OpInfo.Constraints.size(); j != e; ++j) {
- const CodeGenInstruction::ConstraintInfo &CI = OpInfo.Constraints[j];
+ const CGIOperandList::ConstraintInfo &CI = OpInfo.Constraints[j];
if (CI.isTied())
TiedOperands.push_back(std::make_pair(OpInfo.MIOperandNo + j,
CI.getTiedOperand()));
@@ -1100,8 +1101,8 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
// Compute the total number of operands.
unsigned NumMIOperands = 0;
- for (unsigned i = 0, e = II.Instr->OperandList.size(); i != e; ++i) {
- const CodeGenInstruction::OperandInfo &OI = II.Instr->OperandList[i];
+ for (unsigned i = 0, e = II.Instr->Operands.size(); i != e; ++i) {
+ const CGIOperandList::OperandInfo &OI = II.Instr->Operands[i];
NumMIOperands = std::max(NumMIOperands,
OI.MIOperandNo + OI.MINumOperands);
}
diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp
index 7989406..fdf447f 100644
--- a/utils/TableGen/AsmWriterInst.cpp
+++ b/utils/TableGen/AsmWriterInst.cpp
@@ -198,8 +198,8 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
Modifier));
} else {
// Otherwise, normal operand.
- unsigned OpNo = CGI.getOperandNamed(VarName);
- CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+ unsigned OpNo = CGI.Operands.getOperandNamed(VarName);
+ CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];
unsigned MIOp = OpInfo.MIOperandNo;
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index b7b62d5..6310752 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -158,21 +158,22 @@ void CodeEmitterGen::run(raw_ostream &o) {
// operand number. Non-matching operands are assumed to be in
// order.
unsigned OpIdx;
- if (CGI.hasOperandNamed(VarName, OpIdx)) {
+ if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
// Get the machine operand number for the indicated operand.
- OpIdx = CGI.OperandList[OpIdx].MIOperandNo;
- assert (!CGI.isFlatOperandNotEmitted(OpIdx) &&
+ OpIdx = CGI.Operands[OpIdx].MIOperandNo;
+ assert (!CGI.Operands.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))
+ while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
++NumberedOp;
OpIdx = NumberedOp++;
}
- std::pair<unsigned, unsigned> SO = CGI.getSubOperandNumber(OpIdx);
+ std::pair<unsigned, unsigned> SO =
+ CGI.Operands.getSubOperandNumber(OpIdx);
std::string &EncoderMethodName =
- CGI.OperandList[SO.first].EncoderMethodName;
+ CGI.Operands[SO.first].EncoderMethodName;
// If the source operand has a custom encoder, use it. This will
// get the encoding for all of the suboperands.
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 6f54191..6c89453 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -829,7 +829,7 @@ static unsigned GetNumNodeResults(Record *Operator, CodeGenDAGPatterns &CDP) {
CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator);
// FIXME: Should allow access to all the results here.
- unsigned NumDefsToAdd = InstInfo.NumDefs ? 1 : 0;
+ unsigned NumDefsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
// Add on one implicit def if it has a resolvable type.
if (InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()) !=MVT::Other)
@@ -1314,7 +1314,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// Apply the result types to the node, these come from the things in the
// (outs) list of the instruction.
// FIXME: Cap at one result so far.
- unsigned NumResultsToAdd = InstInfo.NumDefs ? 1 : 0;
+ unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
Record *ResultNode = Inst.getResult(ResNo);
@@ -2258,7 +2258,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst,
HasSideEffects = true;
}
- if (Inst.isVariadic)
+ if (Inst.Operands.isVariadic)
IsVariadic = true; // Can warn if we want.
}
@@ -2283,18 +2283,18 @@ void CodeGenDAGPatterns::ParseInstructions() {
CodeGenInstruction &InstInfo = Target.getInstruction(Instrs[i]);
- if (InstInfo.OperandList.size() != 0) {
- if (InstInfo.NumDefs == 0) {
+ if (InstInfo.Operands.size() != 0) {
+ if (InstInfo.Operands.NumDefs == 0) {
// These produce no results
- for (unsigned j = 0, e = InstInfo.OperandList.size(); j < e; ++j)
- Operands.push_back(InstInfo.OperandList[j].Rec);
+ for (unsigned j = 0, e = InstInfo.Operands.size(); j < e; ++j)
+ Operands.push_back(InstInfo.Operands[j].Rec);
} else {
// Assume the first operand is the result.
- Results.push_back(InstInfo.OperandList[0].Rec);
+ Results.push_back(InstInfo.Operands[0].Rec);
// The rest are inputs.
- for (unsigned j = 1, e = InstInfo.OperandList.size(); j < e; ++j)
- Operands.push_back(InstInfo.OperandList[j].Rec);
+ for (unsigned j = 1, e = InstInfo.Operands.size(); j < e; ++j)
+ Operands.push_back(InstInfo.Operands[j].Rec);
}
}
@@ -2351,10 +2351,10 @@ void CodeGenDAGPatterns::ParseInstructions() {
std::vector<Record*> Results;
TreePatternNode *Res0Node = 0;
for (unsigned i = 0; i != NumResults; ++i) {
- if (i == CGI.OperandList.size())
+ if (i == CGI.Operands.size())
I->error("'" + InstResults.begin()->first +
"' set but does not appear in operand list!");
- const std::string &OpName = CGI.OperandList[i].Name;
+ const std::string &OpName = CGI.Operands[i].Name;
// Check that it exists in InstResults.
TreePatternNode *RNode = InstResults[OpName];
@@ -2368,11 +2368,11 @@ void CodeGenDAGPatterns::ParseInstructions() {
I->error("Operand $" + OpName + " should be a set destination: all "
"outputs must occur before inputs in operand list!");
- if (CGI.OperandList[i].Rec != R)
+ if (CGI.Operands[i].Rec != R)
I->error("Operand $" + OpName + " class mismatch!");
// Remember the return type.
- Results.push_back(CGI.OperandList[i].Rec);
+ Results.push_back(CGI.Operands[i].Rec);
// Okay, this one checks out.
InstResults.erase(OpName);
@@ -2384,8 +2384,8 @@ void CodeGenDAGPatterns::ParseInstructions() {
std::vector<TreePatternNode*> ResultNodeOperands;
std::vector<Record*> Operands;
- for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
- CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i];
+ for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) {
+ CGIOperandList::OperandInfo &Op = CGI.Operands[i];
const std::string &OpName = Op.Name;
if (OpName.empty())
I->error("Operand #" + utostr(i) + " in operands list has no name!");
@@ -2569,7 +2569,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
InstInfo.mayStore = MayStore;
InstInfo.mayLoad = MayLoad;
InstInfo.hasSideEffects = HasSideEffects;
- InstInfo.isVariadic = IsVariadic;
+ InstInfo.Operands.isVariadic = IsVariadic;
}
}
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 259e7c3..5eceaeb 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -19,134 +19,32 @@
#include <set>
using namespace llvm;
-static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
- // EARLY_CLOBBER: @early $reg
- std::string::size_type wpos = CStr.find_first_of(" \t");
- std::string::size_type start = CStr.find_first_not_of(" \t");
- std::string Tok = CStr.substr(start, wpos - start);
- if (Tok == "@earlyclobber") {
- std::string Name = CStr.substr(wpos+1);
- wpos = Name.find_first_not_of(" \t");
- if (wpos == std::string::npos)
- throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
- Name = Name.substr(wpos);
- std::pair<unsigned,unsigned> Op =
- I->ParseOperandName(Name, false);
-
- // Build the string for the operand
- if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
- throw "Operand '" + Name + "' cannot have multiple constraints!";
- I->OperandList[Op.first].Constraints[Op.second] =
- CodeGenInstruction::ConstraintInfo::getEarlyClobber();
- return;
- }
-
- // Only other constraint is "TIED_TO" for now.
- std::string::size_type pos = CStr.find_first_of('=');
- assert(pos != std::string::npos && "Unrecognized constraint");
- start = CStr.find_first_not_of(" \t");
- std::string Name = CStr.substr(start, pos - start);
-
- // TIED_TO: $src1 = $dst
- wpos = Name.find_first_of(" \t");
- if (wpos == std::string::npos)
- throw "Illegal format for tied-to constraint: '" + CStr + "'";
- std::string DestOpName = Name.substr(0, wpos);
- std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
-
- Name = CStr.substr(pos+1);
- wpos = Name.find_first_not_of(" \t");
- if (wpos == std::string::npos)
- throw "Illegal format for tied-to constraint: '" + CStr + "'";
-
- std::pair<unsigned,unsigned> SrcOp =
- I->ParseOperandName(Name.substr(wpos), false);
- if (SrcOp > DestOp)
- throw "Illegal tied-to operand constraint '" + CStr + "'";
-
-
- unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
-
- if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
- throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
- I->OperandList[DestOp.first].Constraints[DestOp.second] =
- CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
-}
-
-static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
- // Make sure the constraints list for each operand is large enough to hold
- // constraint info, even if none is present.
- for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i)
- I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
-
- if (CStr.empty()) return;
-
- const std::string delims(",");
- std::string::size_type bidx, eidx;
-
- bidx = CStr.find_first_not_of(delims);
- while (bidx != std::string::npos) {
- eidx = CStr.find_first_of(delims, bidx);
- if (eidx == std::string::npos)
- eidx = CStr.length();
-
- ParseConstraint(CStr.substr(bidx, eidx - bidx), I);
- bidx = CStr.find_first_not_of(delims, eidx);
- }
-}
-
-CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
- Namespace = R->getValueAsString("Namespace");
- AsmString = R->getValueAsString("AsmString");
+//===----------------------------------------------------------------------===//
+// CGIOperandList Implementation
+//===----------------------------------------------------------------------===//
- isReturn = R->getValueAsBit("isReturn");
- isBranch = R->getValueAsBit("isBranch");
- isIndirectBranch = R->getValueAsBit("isIndirectBranch");
- isCompare = R->getValueAsBit("isCompare");
- isBarrier = R->getValueAsBit("isBarrier");
- isCall = R->getValueAsBit("isCall");
- canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
- mayLoad = R->getValueAsBit("mayLoad");
- mayStore = R->getValueAsBit("mayStore");
- isPredicable = R->getValueAsBit("isPredicable");
- isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
- isCommutable = R->getValueAsBit("isCommutable");
- isTerminator = R->getValueAsBit("isTerminator");
- isReMaterializable = R->getValueAsBit("isReMaterializable");
- hasDelaySlot = R->getValueAsBit("hasDelaySlot");
- usesCustomInserter = R->getValueAsBit("usesCustomInserter");
- hasCtrlDep = R->getValueAsBit("hasCtrlDep");
- isNotDuplicable = R->getValueAsBit("isNotDuplicable");
- hasSideEffects = R->getValueAsBit("hasSideEffects");
- neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
- isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
- hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
- hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
+CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
+ isPredicable = false;
hasOptionalDef = false;
isVariadic = false;
- ImplicitDefs = R->getValueAsListOfDefs("Defs");
- ImplicitUses = R->getValueAsListOfDefs("Uses");
-
- if (neverHasSideEffects + hasSideEffects > 1)
- throw R->getName() + ": multiple conflicting side-effect flags set!";
-
+
DagInit *OutDI = R->getValueAsDag("OutOperandList");
-
+
if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) {
if (Init->getDef()->getName() != "outs")
throw R->getName() + ": invalid def name for output list: use 'outs'";
} else
throw R->getName() + ": invalid output list: use 'outs'";
-
+
NumDefs = OutDI->getNumArgs();
-
+
DagInit *InDI = R->getValueAsDag("InOperandList");
if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) {
if (Init->getDef()->getName() != "ins")
throw R->getName() + ": invalid def name for input list: use 'ins'";
} else
throw R->getName() + ": invalid input list: use 'ins'";
-
+
unsigned MIOperandNo = 0;
std::set<std::string> OperandNames;
for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){
@@ -163,7 +61,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
DefInit *Arg = dynamic_cast<DefInit*>(ArgInit);
if (!Arg)
throw "Illegal operand for the '" + R->getName() + "' instruction!";
-
+
Record *Rec = Arg->getDef();
std::string PrintMethod = "printOperand";
std::string EncoderMethod;
@@ -175,19 +73,19 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
if (Rec->getValue("EncoderMethod"))
EncoderMethod = Rec->getValueAsString("EncoderMethod");
MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
-
+
// Verify that MIOpInfo has an 'ops' root value.
if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
dynamic_cast<DefInit*>(MIOpInfo->getOperator())
- ->getDef()->getName() != "ops")
+ ->getDef()->getName() != "ops")
throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
- "'\n";
-
+ "'\n";
+
// If we have MIOpInfo, then we have #operands equal to number of entries
// in MIOperandInfo.
if (unsigned NumArgs = MIOpInfo->getNumArgs())
NumOps = NumArgs;
-
+
if (Rec->isSubClassOf("PredicateOperand"))
isPredicable = true;
else if (Rec->isSubClassOf("OptionalDefOperand"))
@@ -198,57 +96,38 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) {
} else if (!Rec->isSubClassOf("RegisterClass") &&
Rec->getName() != "ptr_rc" && Rec->getName() != "unknown")
throw "Unknown operand class '" + Rec->getName() +
- "' in '" + R->getName() + "' instruction!";
-
+ "' in '" + R->getName() + "' instruction!";
+
// Check that the operand has a name and that it's unique.
if (ArgName.empty())
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has no name!";
+ " has no name!";
if (!OperandNames.insert(ArgName).second)
throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has the same name as a previous operand!";
-
+ " has the same name as a previous operand!";
+
OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
MIOperandNo, NumOps, MIOpInfo));
MIOperandNo += NumOps;
}
-
- // Parse Constraints.
- ParseConstraints(R->getValueAsString("Constraints"), this);
-
- // Parse the DisableEncoding field.
- std::string DisableEncoding = R->getValueAsString("DisableEncoding");
- while (1) {
- std::string OpName;
- tie(OpName, DisableEncoding) = 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;
- }
}
+
/// getOperandNamed - Return the index of the operand with the specified
/// non-empty name. If the instruction does not have an operand with the
/// specified name, throw an exception.
///
-unsigned CodeGenInstruction::getOperandNamed(StringRef Name) const {
+unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
unsigned OpIdx;
if (hasOperandNamed(Name, OpIdx)) return OpIdx;
- throw "Instruction '" + TheDef->getName() +
- "' does not have an operand named '$" + Name.str() + "'!";
+ throw "'" + TheDef->getName() + "' does not have an operand named '$" +
+ Name.str() + "'!";
}
/// 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(StringRef Name,
- unsigned &OpIdx) const {
+bool CGIOperandList::hasOperandNamed(StringRef 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) {
@@ -259,14 +138,13 @@ bool CodeGenInstruction::hasOperandNamed(StringRef Name,
}
std::pair<unsigned,unsigned>
-CodeGenInstruction::ParseOperandName(const std::string &Op,
- bool AllowWholeOp) {
+CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) {
if (Op.empty() || Op[0] != '$')
throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
-
+
std::string OpName = Op.substr(1);
std::string SubOpName;
-
+
// Check to see if this is $foo.bar.
std::string::size_type DotIdx = OpName.find_first_of(".");
if (DotIdx != std::string::npos) {
@@ -275,34 +153,169 @@ CodeGenInstruction::ParseOperandName(const std::string &Op,
throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
OpName = OpName.substr(0, DotIdx);
}
-
+
unsigned OpIdx = getOperandNamed(OpName);
-
+
if (SubOpName.empty()) { // If no suboperand name was specified:
// If one was needed, throw.
if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
SubOpName.empty())
throw TheDef->getName() + ": Illegal to refer to"
- " whole operand part of complex operand '" + Op + "'";
-
+ " whole operand part of complex operand '" + Op + "'";
+
// Otherwise, return the operand.
return std::make_pair(OpIdx, 0U);
}
-
+
// Find the suboperand number involved.
DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
if (MIOpInfo == 0)
throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
-
+
// Find the operand with the right name.
for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
if (MIOpInfo->getArgName(i) == SubOpName)
return std::make_pair(OpIdx, i);
-
+
// Otherwise, didn't find it!
throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
}
+static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops) {
+ // EARLY_CLOBBER: @early $reg
+ std::string::size_type wpos = CStr.find_first_of(" \t");
+ std::string::size_type start = CStr.find_first_not_of(" \t");
+ std::string Tok = CStr.substr(start, wpos - start);
+ if (Tok == "@earlyclobber") {
+ std::string Name = CStr.substr(wpos+1);
+ wpos = Name.find_first_not_of(" \t");
+ if (wpos == std::string::npos)
+ throw "Illegal format for @earlyclobber constraint: '" + CStr + "'";
+ Name = Name.substr(wpos);
+ std::pair<unsigned,unsigned> Op = Ops.ParseOperandName(Name, false);
+
+ // Build the string for the operand
+ if (!Ops[Op.first].Constraints[Op.second].isNone())
+ throw "Operand '" + Name + "' cannot have multiple constraints!";
+ Ops[Op.first].Constraints[Op.second] =
+ CGIOperandList::ConstraintInfo::getEarlyClobber();
+ return;
+ }
+
+ // Only other constraint is "TIED_TO" for now.
+ std::string::size_type pos = CStr.find_first_of('=');
+ assert(pos != std::string::npos && "Unrecognized constraint");
+ start = CStr.find_first_not_of(" \t");
+ std::string Name = CStr.substr(start, pos - start);
+
+ // TIED_TO: $src1 = $dst
+ wpos = Name.find_first_of(" \t");
+ if (wpos == std::string::npos)
+ throw "Illegal format for tied-to constraint: '" + CStr + "'";
+ std::string DestOpName = Name.substr(0, wpos);
+ std::pair<unsigned,unsigned> DestOp = Ops.ParseOperandName(DestOpName, false);
+
+ Name = CStr.substr(pos+1);
+ wpos = Name.find_first_not_of(" \t");
+ if (wpos == std::string::npos)
+ throw "Illegal format for tied-to constraint: '" + CStr + "'";
+
+ std::pair<unsigned,unsigned> SrcOp =
+ Ops.ParseOperandName(Name.substr(wpos), false);
+ if (SrcOp > DestOp)
+ throw "Illegal tied-to operand constraint '" + CStr + "'";
+
+
+ unsigned FlatOpNo = Ops.getFlattenedOperandNumber(SrcOp);
+
+ if (!Ops[DestOp.first].Constraints[DestOp.second].isNone())
+ throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
+ Ops[DestOp.first].Constraints[DestOp.second] =
+ CGIOperandList::ConstraintInfo::getTied(FlatOpNo);
+}
+
+static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) {
+ // Make sure the constraints list for each operand is large enough to hold
+ // constraint info, even if none is present.
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ Ops[i].Constraints.resize(Ops[i].MINumOperands);
+
+ if (CStr.empty()) return;
+
+ const std::string delims(",");
+ std::string::size_type bidx, eidx;
+
+ bidx = CStr.find_first_not_of(delims);
+ while (bidx != std::string::npos) {
+ eidx = CStr.find_first_of(delims, bidx);
+ if (eidx == std::string::npos)
+ eidx = CStr.length();
+
+ ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops);
+ bidx = CStr.find_first_not_of(delims, eidx);
+ }
+}
+
+void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
+ while (1) {
+ std::string OpName;
+ tie(OpName, DisableEncoding) = 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;
+ }
+
+}
+
+//===----------------------------------------------------------------------===//
+// CodeGenInstruction Implementation
+//===----------------------------------------------------------------------===//
+
+CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) {
+ Namespace = R->getValueAsString("Namespace");
+ AsmString = R->getValueAsString("AsmString");
+
+ isReturn = R->getValueAsBit("isReturn");
+ isBranch = R->getValueAsBit("isBranch");
+ isIndirectBranch = R->getValueAsBit("isIndirectBranch");
+ isCompare = R->getValueAsBit("isCompare");
+ isBarrier = R->getValueAsBit("isBarrier");
+ isCall = R->getValueAsBit("isCall");
+ canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
+ mayLoad = R->getValueAsBit("mayLoad");
+ mayStore = R->getValueAsBit("mayStore");
+ isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable");
+ isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
+ isCommutable = R->getValueAsBit("isCommutable");
+ isTerminator = R->getValueAsBit("isTerminator");
+ isReMaterializable = R->getValueAsBit("isReMaterializable");
+ hasDelaySlot = R->getValueAsBit("hasDelaySlot");
+ usesCustomInserter = R->getValueAsBit("usesCustomInserter");
+ hasCtrlDep = R->getValueAsBit("hasCtrlDep");
+ isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+ hasSideEffects = R->getValueAsBit("hasSideEffects");
+ neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
+ isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
+ hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
+ hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
+ ImplicitDefs = R->getValueAsListOfDefs("Defs");
+ ImplicitUses = R->getValueAsListOfDefs("Uses");
+
+ if (neverHasSideEffects + hasSideEffects > 1)
+ throw R->getName() + ": multiple conflicting side-effect flags set!";
+
+ // Parse Constraints.
+ ParseConstraints(R->getValueAsString("Constraints"), Operands);
+
+ // Parse the DisableEncoding field.
+ Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding"));
+}
/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
/// implicit def and it has a known VT, return the VT, otherwise return
@@ -369,4 +382,3 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
return Res;
}
-
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index 7f9d249..93bec14 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -24,40 +24,33 @@ namespace llvm {
class DagInit;
class CodeGenTarget;
class StringRef;
-
- class CodeGenInstruction {
+
+ class CGIOperandList {
public:
- Record *TheDef; // The actual record defining this instruction.
- std::string Namespace; // The namespace the instruction is in.
-
- /// AsmString - The format string used to emit a .s file for the
- /// instruction.
- std::string AsmString;
-
class ConstraintInfo {
enum { None, EarlyClobber, Tied } Kind;
unsigned OtherTiedOperand;
public:
ConstraintInfo() : Kind(None) {}
-
+
static ConstraintInfo getEarlyClobber() {
ConstraintInfo I;
I.Kind = EarlyClobber;
I.OtherTiedOperand = 0;
return I;
}
-
+
static ConstraintInfo getTied(unsigned Op) {
ConstraintInfo I;
I.Kind = Tied;
I.OtherTiedOperand = Op;
return I;
}
-
+
bool isNone() const { return Kind == None; }
bool isEarlyClobber() const { return Kind == EarlyClobber; }
bool isTied() const { return Kind == Tied; }
-
+
unsigned getTiedOperand() const {
assert(isTied());
return OtherTiedOperand;
@@ -70,19 +63,19 @@ namespace llvm {
/// Rec - The definition this operand is declared as.
///
Record *Rec;
-
+
/// Name - If this operand was assigned a symbolic name, this is it,
/// otherwise, it's empty.
std::string Name;
-
+
/// PrinterMethodName - The method used to print operands of this type in
/// the asmprinter.
std::string PrinterMethodName;
-
+
/// EncoderMethodName - The method used to get the machine operand value
/// for binary encoding. "getMachineOpValue" by default.
std::string EncoderMethodName;
-
+
/// MIOperandNo - Currently (this is meant to be phased out), some logical
/// operands correspond to multiple MachineInstr operands. In the X86
/// target for example, one address operand is represented as 4
@@ -91,66 +84,63 @@ namespace llvm {
/// does, this contains the MI operand index of this operand.
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;
-
+
/// Constraint info for this operand. This operand can have pieces, so we
/// track constraint info for each.
std::vector<ConstraintInfo> Constraints;
-
+
OperandInfo(Record *R, const std::string &N, const std::string &PMN,
const std::string &EMN, unsigned MION, unsigned MINO,
DagInit *MIOI)
- : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
- MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
+ : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
+ MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
};
+
+ CGIOperandList(Record *D);
+
+ Record *TheDef; // The actual record containing this OperandList.
/// NumDefs - Number of def operands declared, this is the number of
/// elements in the instruction's (outs) list.
///
unsigned NumDefs;
-
+
/// OperandList - The list of declared operands, along with their declared
/// type (which is a record).
std::vector<OperandInfo> OperandList;
-
- /// ImplicitDefs/ImplicitUses - These are lists of registers that are
- /// implicitly defined and used by the instruction.
- std::vector<Record*> ImplicitDefs, ImplicitUses;
-
- // Various boolean values we track for the instruction.
- bool isReturn;
- bool isBranch;
- bool isIndirectBranch;
- bool isCompare;
- bool isBarrier;
- bool isCall;
- bool canFoldAsLoad;
- bool mayLoad, mayStore;
+
+ // Information gleaned from the operand list.
bool isPredicable;
- bool isConvertibleToThreeAddress;
- bool isCommutable;
- bool isTerminator;
- bool isReMaterializable;
- bool hasDelaySlot;
- bool usesCustomInserter;
- bool isVariadic;
- bool hasCtrlDep;
- bool isNotDuplicable;
bool hasOptionalDef;
- bool hasSideEffects;
- bool neverHasSideEffects;
- bool isAsCheapAsAMove;
- bool hasExtraSrcRegAllocReq;
- bool hasExtraDefRegAllocReq;
-
+ bool isVariadic;
+
+ // Provide transparent accessors to the operand list.
+ unsigned size() const { return OperandList.size(); }
+ const OperandInfo &operator[](unsigned i) const { return OperandList[i]; }
+ OperandInfo &operator[](unsigned i) { return OperandList[i]; }
+ OperandInfo &back() { return OperandList.back(); }
+ const OperandInfo &back() const { return OperandList.back(); }
+
+
+ /// getOperandNamed - Return the index of the operand with the specified
+ /// non-empty name. If the instruction does not have an operand with the
+ /// specified name, throw an exception.
+ unsigned getOperandNamed(StringRef 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(StringRef Name, unsigned &OpIdx) const;
+
/// ParseOperandName - Parse an operand name like "$foo" or "$foo.bar",
/// where $foo is a whole operand and $foo.bar refers to a suboperand.
/// This throws an exception if the name is invalid. If AllowWholeOp is
@@ -158,13 +148,13 @@ namespace llvm {
/// not.
std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
bool AllowWholeOp = true);
-
+
/// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
/// flat machineinstr operand #.
unsigned getFlattenedOperandNumber(std::pair<unsigned,unsigned> Op) const {
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 {
@@ -174,8 +164,8 @@ namespace llvm {
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 {
@@ -184,18 +174,54 @@ namespace llvm {
return OperandList[Op.first].DoNotEncode[Op.second];
return false;
}
+
+ void ProcessDisableEncoding(std::string Value);
+ };
+
- CodeGenInstruction(Record *R);
+ class CodeGenInstruction {
+ public:
+ Record *TheDef; // The actual record defining this instruction.
+ std::string Namespace; // The namespace the instruction is in.
- /// getOperandNamed - Return the index of the operand with the specified
- /// non-empty name. If the instruction does not have an operand with the
- /// specified name, throw an exception.
- unsigned getOperandNamed(StringRef Name) const;
+ /// AsmString - The format string used to emit a .s file for the
+ /// instruction.
+ std::string AsmString;
- /// 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(StringRef Name, unsigned &OpIdx) const;
+ /// Operands - This is information about the (ins) and (outs) list specified
+ /// to the instruction.
+ CGIOperandList Operands;
+
+ /// ImplicitDefs/ImplicitUses - These are lists of registers that are
+ /// implicitly defined and used by the instruction.
+ std::vector<Record*> ImplicitDefs, ImplicitUses;
+
+ // Various boolean values we track for the instruction.
+ bool isReturn;
+ bool isBranch;
+ bool isIndirectBranch;
+ bool isCompare;
+ bool isBarrier;
+ bool isCall;
+ bool canFoldAsLoad;
+ bool mayLoad, mayStore;
+ bool isPredicable;
+ bool isConvertibleToThreeAddress;
+ bool isCommutable;
+ bool isTerminator;
+ bool isReMaterializable;
+ bool hasDelaySlot;
+ bool usesCustomInserter;
+ bool hasCtrlDep;
+ bool isNotDuplicable;
+ bool hasSideEffects;
+ bool neverHasSideEffects;
+ bool isAsCheapAsAMove;
+ bool hasExtraSrcRegAllocReq;
+ bool hasExtraDefRegAllocReq;
+
+
+ CodeGenInstruction(Record *R);
/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
/// implicit def and it has a known VT, return the VT, otherwise return
@@ -209,6 +235,6 @@ namespace llvm {
static std::string FlattenAsmStringVariants(StringRef AsmString,
unsigned Variant);
};
-}
+ }
#endif
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 57c0b15..c1e3212 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -678,11 +678,11 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
// in the 'execute always' values. Match up the node operands to the
// instruction operands to do this.
SmallVector<unsigned, 8> InstOps;
- for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.OperandList.size();
+ for (unsigned ChildNo = 0, InstOpNo = NumResults, e = II.Operands.size();
InstOpNo != e; ++InstOpNo) {
// Determine what to emit for this operand.
- Record *OperandNode = II.OperandList[InstOpNo].Rec;
+ Record *OperandNode = II.Operands[InstOpNo].Rec;
if ((OperandNode->isSubClassOf("PredicateOperand") ||
OperandNode->isSubClassOf("OptionalDefOperand")) &&
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index 8b1b890..1d5e1e1 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -346,11 +346,10 @@ static void X86PopulateOperands(
return;
unsigned int index;
- unsigned int numOperands = inst.OperandList.size();
+ unsigned int numOperands = inst.Operands.size();
for (index = 0; index < numOperands; ++index) {
- const CodeGenInstruction::OperandInfo &operandInfo =
- inst.OperandList[index];
+ const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
Record &rec = *operandInfo.Rec;
if (X86TypeFromOpName(operandTypes[index], rec.getName())) {
@@ -376,7 +375,7 @@ static inline void decorate1(
const char *opFlag) {
unsigned opIndex;
- opIndex = inst.getOperandNamed(std::string(opName));
+ opIndex = inst.Operands.getOperandNamed(std::string(opName));
operandFlags[opIndex]->addEntry(opFlag);
}
@@ -648,7 +647,7 @@ static void ARMPopulateOperands(
return;
unsigned int index;
- unsigned int numOperands = inst.OperandList.size();
+ unsigned int numOperands = inst.Operands.size();
if (numOperands > EDIS_MAX_OPERANDS) {
errs() << "numOperands == " << numOperands << " > " <<
@@ -657,8 +656,7 @@ static void ARMPopulateOperands(
}
for (index = 0; index < numOperands; ++index) {
- const CodeGenInstruction::OperandInfo &operandInfo =
- inst.OperandList[index];
+ const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
Record &rec = *operandInfo.Rec;
if (ARMFlagFromOpName(operandTypes[index], rec.getName())) {
@@ -709,7 +707,7 @@ static void ARMExtractSemantics(
BRANCH("func");
unsigned opIndex;
- opIndex = inst.getOperandNamed("func");
+ opIndex = inst.Operands.getOperandNamed("func");
if (operandTypes[opIndex]->is("kOperandTypeImmediate"))
operandTypes[opIndex]->set("kOperandTypeARMBranchTarget");
}
@@ -740,7 +738,7 @@ static void populateInstInfo(CompoundConstantEmitter &infoArray,
infoStruct->addEntry(instType);
LiteralConstantEmitter *numOperandsEmitter =
- new LiteralConstantEmitter(inst.OperandList.size());
+ new LiteralConstantEmitter(inst.Operands.size());
infoStruct->addEntry(numOperandsEmitter);
CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter;
diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp
index 6c16fcf..0039506 100644
--- a/utils/TableGen/FastISelEmitter.cpp
+++ b/utils/TableGen/FastISelEmitter.cpp
@@ -263,7 +263,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
if (!Op->isSubClassOf("Instruction"))
continue;
CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
- if (II.OperandList.empty())
+ if (II.Operands.size() == 0)
continue;
// For now, ignore multi-instruction patterns.
@@ -285,7 +285,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
const CodeGenRegisterClass *DstRC = 0;
std::string SubRegNo;
if (Op->getName() != "EXTRACT_SUBREG") {
- Record *Op0Rec = II.OperandList[0].Rec;
+ Record *Op0Rec = II.Operands[0].Rec;
if (!Op0Rec->isSubClassOf("RegisterClass"))
continue;
DstRC = &Target.getRegisterClass(Op0Rec);
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 4d3aa5e..e04ab6c 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -60,23 +60,23 @@ std::vector<std::string>
InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
std::vector<std::string> Result;
- for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
+ for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) {
// Handle aggregate operands and normal operands the same way by expanding
// either case into a list of operands for this op.
- std::vector<CodeGenInstruction::OperandInfo> OperandList;
+ std::vector<CGIOperandList::OperandInfo> OperandList;
// This might be a multiple operand thing. Targets like X86 have
// registers in their multi-operand operands. It may also be an anonymous
// operand, which has a single operand, but no declared class for the
// operand.
- DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
+ DagInit *MIOI = Inst.Operands[i].MIOperandInfo;
if (!MIOI || MIOI->getNumArgs() == 0) {
// Single, anonymous, operand.
- OperandList.push_back(Inst.OperandList[i]);
+ OperandList.push_back(Inst.Operands[i]);
} else {
- for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
- OperandList.push_back(Inst.OperandList[i]);
+ for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) {
+ OperandList.push_back(Inst.Operands[i]);
Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef();
OperandList.back().Rec = OpR;
@@ -104,19 +104,19 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
// Predicate operands. Check to see if the original unexpanded operand
// was of type PredicateOperand.
- if (Inst.OperandList[i].Rec->isSubClassOf("PredicateOperand"))
+ if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand"))
Res += "|(1<<TOI::Predicate)";
// Optional def operands. Check to see if the original unexpanded operand
// was of type OptionalDefOperand.
- if (Inst.OperandList[i].Rec->isSubClassOf("OptionalDefOperand"))
+ if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand"))
Res += "|(1<<TOI::OptionalDef)";
// Fill in constraint info.
Res += ", ";
- const CodeGenInstruction::ConstraintInfo &Constraint =
- Inst.OperandList[i].Constraints[j];
+ const CGIOperandList::ConstraintInfo &Constraint =
+ Inst.Operands[i].Constraints[j];
if (Constraint.isNone())
Res += "0";
else if (Constraint.isEarlyClobber())
@@ -256,14 +256,14 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
const OperandInfoMapTy &OpInfo,
raw_ostream &OS) {
int MinOperands = 0;
- if (!Inst.OperandList.empty())
+ if (!Inst.Operands.size() == 0)
// Each logical operand can be multiple MI operands.
- MinOperands = Inst.OperandList.back().MIOperandNo +
- Inst.OperandList.back().MINumOperands;
+ MinOperands = Inst.Operands.back().MIOperandNo +
+ Inst.Operands.back().MINumOperands;
OS << " { ";
OS << Num << ",\t" << MinOperands << ",\t"
- << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
+ << Inst.Operands.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
<< ",\t\"" << Inst.TheDef->getName() << "\", 0";
// Emit all of the target indepedent flags...
@@ -283,9 +283,9 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
if (Inst.isTerminator) OS << "|(1<<TID::Terminator)";
if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)";
if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)";
- if (Inst.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)";
+ if (Inst.Operands.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)";
if (Inst.usesCustomInserter) OS << "|(1<<TID::UsesCustomInserter)";
- if (Inst.isVariadic) OS << "|(1<<TID::Variadic)";
+ if (Inst.Operands.isVariadic)OS << "|(1<<TID::Variadic)";
if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)";
if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)";
if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)";
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 1343fcf..e3cad1a 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -219,7 +219,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
Name = Rec->getName();
AsmString = Rec->getValueAsString("AsmString");
- Operands = &insn.OperandList;
+ Operands = &insn.Operands.OperandList;
IsSSE = HasOpSizePrefix && (Name.find("16") == Name.npos);
HasFROperands = false;
@@ -424,7 +424,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
Spec->insnContext = insnContext();
- const std::vector<CodeGenInstruction::OperandInfo> &OperandList = *Operands;
+ const std::vector<CGIOperandList::OperandInfo> &OperandList = *Operands;
unsigned operandIndex;
unsigned numOperands = OperandList.size();
@@ -440,7 +440,7 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
if (OperandList[operandIndex].Constraints.size()) {
- const CodeGenInstruction::ConstraintInfo &Constraint =
+ const CGIOperandList::ConstraintInfo &Constraint =
OperandList[operandIndex].Constraints[0];
if (Constraint.isTied()) {
operandMapping[operandIndex] = Constraint.getTiedOperand();
diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h
index db4d96d..113b3bd 100644
--- a/utils/TableGen/X86RecognizableInstr.h
+++ b/utils/TableGen/X86RecognizableInstr.h
@@ -76,7 +76,8 @@ private:
/// The operands of the instruction, as listed in the CodeGenInstruction.
/// They are not one-to-one with operands listed in the MCInst; for example,
/// memory operands expand to 5 operands in the MCInst
- const std::vector<CodeGenInstruction::OperandInfo>* Operands;
+ const std::vector<CGIOperandList::OperandInfo>* Operands;
+
/// The description of the instruction that is emitted into the instruction
/// info table
InstructionSpecifier* Spec;