aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/utils/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/utils/TableGen')
-rw-r--r--contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp36
-rw-r--r--contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp19
-rw-r--r--contrib/llvm/utils/TableGen/CTagsEmitter.cpp99
-rw-r--r--contrib/llvm/utils/TableGen/CodeEmitterGen.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp219
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h14
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenInstruction.cpp6
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenInstruction.h4
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenIntrinsics.h2
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenMapTable.cpp9
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.cpp49
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.h27
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenSchedule.cpp300
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenSchedule.h86
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenTarget.cpp14
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenTarget.h10
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcher.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcher.h4
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp57
-rw-r--r--contrib/llvm/utils/TableGen/DFAPacketizerEmitter.cpp11
-rw-r--r--contrib/llvm/utils/TableGen/DisassemblerEmitter.cpp5
-rw-r--r--contrib/llvm/utils/TableGen/EDEmitter.cpp1011
-rw-r--r--contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp9
-rw-r--r--contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp6
-rw-r--r--contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp71
-rw-r--r--contrib/llvm/utils/TableGen/OptParserEmitter.cpp266
-rw-r--r--contrib/llvm/utils/TableGen/PseudoLoweringEmitter.cpp1
-rw-r--r--contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp110
-rw-r--r--contrib/llvm/utils/TableGen/SequenceToOffsetTable.h4
-rw-r--r--contrib/llvm/utils/TableGen/SetTheory.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/SetTheory.h2
-rw-r--r--contrib/llvm/utils/TableGen/StringToOffsetTable.h2
-rw-r--r--contrib/llvm/utils/TableGen/SubtargetEmitter.cpp206
-rw-r--r--contrib/llvm/utils/TableGen/TableGen.cpp19
-rw-r--r--contrib/llvm/utils/TableGen/TableGenBackends.h3
-rw-r--r--contrib/llvm/utils/TableGen/X86DisassemblerShared.h2
-rw-r--r--contrib/llvm/utils/TableGen/X86DisassemblerTables.cpp5
-rw-r--r--contrib/llvm/utils/TableGen/X86DisassemblerTables.h2
-rw-r--r--contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp33
-rw-r--r--contrib/llvm/utils/TableGen/X86RecognizableInstr.h8
41 files changed, 1247 insertions, 1496 deletions
diff --git a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index ee83311c583b..6faf819529d0 100644
--- a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -100,9 +100,9 @@
#include "StringToOffsetTable.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -958,8 +958,12 @@ static std::string getEnumNameForToken(StringRef Str) {
case ':': Res += "_COLON_"; break;
case '!': Res += "_EXCLAIM_"; break;
case '.': Res += "_DOT_"; break;
+ case '<': Res += "_LT_"; break;
+ case '>': Res += "_GT_"; break;
default:
- if (isalnum(*it))
+ if ((*it >= 'A' && *it <= 'Z') ||
+ (*it >= 'a' && *it <= 'z') ||
+ (*it >= '0' && *it <= '9'))
Res += *it;
else
Res += "_" + utostr((unsigned) *it) + "_";
@@ -1723,7 +1727,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
<< " default: llvm_unreachable(\"invalid conversion entry!\");\n"
<< " case CVT_Reg:\n"
<< " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
- << " Operands[*(p + 1)]->setConstraint(\"m\");\n"
+ << " Operands[*(p + 1)]->setConstraint(\"r\");\n"
<< " ++NumMCOperands;\n"
<< " break;\n"
<< " case CVT_Tied:\n"
@@ -1754,7 +1758,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Remember this converter for the kind enum.
unsigned KindID = OperandConversionKinds.size();
- OperandConversionKinds.insert("CVT_" + AsmMatchConverter);
+ OperandConversionKinds.insert("CVT_" +
+ getEnumNameForToken(AsmMatchConverter));
// Add the converter row for this instruction.
ConversionTable.push_back(std::vector<uint8_t>());
@@ -1762,7 +1767,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
ConversionTable.back().push_back(CVT_Done);
// Add the handler to the conversion driver function.
- CvtOS << " case CVT_" << AsmMatchConverter << ":\n"
+ CvtOS << " case CVT_"
+ << getEnumNameForToken(AsmMatchConverter) << ":\n"
<< " " << AsmMatchConverter << "(Inst, Operands);\n"
<< " break;\n";
@@ -1800,6 +1806,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// the index of its entry in the vector).
std::string Name = "CVT_" + (Op.Class->isRegisterClass() ? "Reg" :
Op.Class->RenderMethod);
+ Name = getEnumNameForToken(Name);
bool IsNewConverter = false;
unsigned ID = getConverterOperandID(Name, OperandConversionKinds,
@@ -1823,9 +1830,13 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Add a handler for the operand number lookup.
OpOS << " case " << Name << ":\n"
- << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n"
- << " Operands[*(p + 1)]->setConstraint(\"m\");\n"
- << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
+ << " Operands[*(p + 1)]->setMCOperandNum(NumMCOperands);\n";
+
+ if (Op.Class->isRegisterClass())
+ OpOS << " Operands[*(p + 1)]->setConstraint(\"r\");\n";
+ else
+ OpOS << " Operands[*(p + 1)]->setConstraint(\"m\");\n";
+ OpOS << " NumMCOperands += " << OpInfo.MINumOperands << ";\n"
<< " break;\n";
break;
}
@@ -2867,6 +2878,15 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "(MatchClassKind)it->Classes[i]);\n";
OS << " if (Diag == Match_Success)\n";
OS << " continue;\n";
+ OS << " // If the generic handler indicates an invalid operand\n";
+ OS << " // failure, check for a special case.\n";
+ OS << " if (Diag == Match_InvalidOperand) {\n";
+ OS << " Diag = validateTargetOperandClass(Operands[i+1],\n";
+ OS.indent(43);
+ OS << "(MatchClassKind)it->Classes[i]);\n";
+ OS << " if (Diag == Match_Success)\n";
+ OS << " continue;\n";
+ OS << " }\n";
OS << " // If this operand is broken for all of the instances of this\n";
OS << " // mnemonic, keep track of it so we can report loc info.\n";
OS << " // If we already had a match that only failed due to a\n";
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
index a4114d9815b6..ac8d896d3647 100644
--- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -842,8 +842,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (!IAP->isOpMapped(ROName)) {
IAP->addOperand(ROName, i);
+ Record *R = CGA->ResultOperands[i].getRecord();
+ if (R->isSubClassOf("RegisterOperand"))
+ R = R->getValueAsDef("RegClass");
Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
- CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)"
+ R->getName() + "RegClassID)"
".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())";
IAP->addCond(Cond);
} else {
@@ -863,12 +866,18 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break;
}
- case CodeGenInstAlias::ResultOperand::K_Imm:
- Cond = std::string("MI->getOperand(") +
- llvm::utostr(i) + ").getImm() == " +
- llvm::utostr(CGA->ResultOperands[i].getImm());
+ case CodeGenInstAlias::ResultOperand::K_Imm: {
+ std::string Op = "MI->getOperand(" + llvm::utostr(i) + ")";
+
+ // Just because the alias has an immediate result, doesn't mean the
+ // MCInst will. An MCExpr could be present, for example.
+ IAP->addCond(Op + ".isImm()");
+
+ Cond = Op + ".getImm() == "
+ + llvm::utostr(CGA->ResultOperands[i].getImm());
IAP->addCond(Cond);
break;
+ }
case CodeGenInstAlias::ResultOperand::K_Reg:
// If this is zero_reg, something's playing tricks we're not
// equipped to handle.
diff --git a/contrib/llvm/utils/TableGen/CTagsEmitter.cpp b/contrib/llvm/utils/TableGen/CTagsEmitter.cpp
new file mode 100644
index 000000000000..8bf777839bdd
--- /dev/null
+++ b/contrib/llvm/utils/TableGen/CTagsEmitter.cpp
@@ -0,0 +1,99 @@
+//===- CTagsEmitter.cpp - Generate ctags-compatible index ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend emits an index of definitions in ctags(1) format.
+// A helper script, utils/TableGen/tdtags, provides an easier-to-use
+// interface; run 'tdtags -H' for documentation.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "ctags-emitter"
+
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <algorithm>
+#include <string>
+#include <vector>
+using namespace llvm;
+
+namespace llvm { extern SourceMgr SrcMgr; }
+
+namespace {
+
+class Tag {
+private:
+ const std::string *Id;
+ SMLoc Loc;
+public:
+ Tag(const std::string &Name, const SMLoc Location)
+ : Id(&Name), Loc(Location) {}
+ int operator<(const Tag &B) const { return *Id < *B.Id; }
+ void emit(raw_ostream &OS) const {
+ int BufferID = SrcMgr.FindBufferContainingLoc(Loc);
+ MemoryBuffer *CurMB = SrcMgr.getBufferInfo(BufferID).Buffer;
+ const char *BufferName = CurMB->getBufferIdentifier();
+ std::pair<unsigned, unsigned> LineAndColumn = SrcMgr.getLineAndColumn(Loc);
+ OS << *Id << "\t" << BufferName << "\t" << LineAndColumn.first << "\n";
+ }
+};
+
+class CTagsEmitter {
+private:
+ RecordKeeper &Records;
+public:
+ CTagsEmitter(RecordKeeper &R) : Records(R) {}
+
+ void run(raw_ostream &OS);
+
+private:
+ static SMLoc locate(const Record *R);
+};
+
+} // End anonymous namespace.
+
+SMLoc CTagsEmitter::locate(const Record *R) {
+ ArrayRef<SMLoc> Locs = R->getLoc();
+ if (Locs.empty()) {
+ SMLoc NullLoc;
+ return NullLoc;
+ }
+ return Locs.front();
+}
+
+void CTagsEmitter::run(raw_ostream &OS) {
+ const std::map<std::string, Record *> &Classes = Records.getClasses();
+ const std::map<std::string, Record *> &Defs = Records.getDefs();
+ std::vector<Tag> Tags;
+ // Collect tags.
+ Tags.reserve(Classes.size() + Defs.size());
+ for (std::map<std::string, Record *>::const_iterator I = Classes.begin(),
+ E = Classes.end();
+ I != E; ++I)
+ Tags.push_back(Tag(I->first, locate(I->second)));
+ for (std::map<std::string, Record *>::const_iterator I = Defs.begin(),
+ E = Defs.end();
+ I != E; ++I)
+ Tags.push_back(Tag(I->first, locate(I->second)));
+ // Emit tags.
+ std::sort(Tags.begin(), Tags.end());
+ OS << "!_TAG_FILE_FORMAT\t1\t/original ctags format/\n";
+ OS << "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/\n";
+ for (std::vector<Tag>::const_iterator I = Tags.begin(), E = Tags.end();
+ I != E; ++I)
+ I->emit(OS);
+}
+
+namespace llvm {
+
+void EmitCTags(RecordKeeper &RK, raw_ostream &OS) { CTagsEmitter(RK).run(OS); }
+
+} // End llvm namespace.
diff --git a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
index 3e4f626d4862..c94d384901f0 100644
--- a/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -14,10 +14,10 @@
//===----------------------------------------------------------------------===//
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <map>
#include <string>
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index d5b581b5981a..8e5bb7760f65 100644
--- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -13,13 +13,13 @@
//===----------------------------------------------------------------------===//
#include "CodeGenDAGPatterns.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <algorithm>
#include <cstdio>
#include <set>
@@ -57,7 +57,7 @@ EEVT::TypeSet::TypeSet(MVT::SimpleValueType VT, TreePattern &TP) {
}
-EEVT::TypeSet::TypeSet(const std::vector<MVT::SimpleValueType> &VTList) {
+EEVT::TypeSet::TypeSet(ArrayRef<MVT::SimpleValueType> VTList) {
assert(!VTList.empty() && "empty list?");
TypeVec.append(VTList.begin(), VTList.end());
@@ -76,7 +76,7 @@ bool EEVT::TypeSet::FillWithPossibleTypes(TreePattern &TP,
bool (*Pred)(MVT::SimpleValueType),
const char *PredicateName) {
assert(isCompletelyUnknown());
- const std::vector<MVT::SimpleValueType> &LegalTypes =
+ ArrayRef<MVT::SimpleValueType> LegalTypes =
TP.getDAGPatterns().getTargetInfo().getLegalValueTypes();
if (TP.hasError())
@@ -956,6 +956,40 @@ bool SDTypeConstraint::ApplyTypeConstraint(TreePatternNode *N,
llvm_unreachable("Invalid ConstraintType!");
}
+// Update the node type to match an instruction operand or result as specified
+// in the ins or outs lists on the instruction definition. Return true if the
+// type was actually changed.
+bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
+ Record *Operand,
+ TreePattern &TP) {
+ // The 'unknown' operand indicates that types should be inferred from the
+ // context.
+ if (Operand->isSubClassOf("unknown_class"))
+ return false;
+
+ // The Operand class specifies a type directly.
+ if (Operand->isSubClassOf("Operand"))
+ return UpdateNodeType(ResNo, getValueType(Operand->getValueAsDef("Type")),
+ TP);
+
+ // PointerLikeRegClass has a type that is determined at runtime.
+ if (Operand->isSubClassOf("PointerLikeRegClass"))
+ return UpdateNodeType(ResNo, MVT::iPTR, TP);
+
+ // Both RegisterClass and RegisterOperand operands derive their types from a
+ // register class def.
+ Record *RC = 0;
+ if (Operand->isSubClassOf("RegisterClass"))
+ RC = Operand;
+ else if (Operand->isSubClassOf("RegisterOperand"))
+ RC = Operand->getValueAsDef("RegClass");
+
+ assert(RC && "Unknown operand type");
+ CodeGenTarget &Tgt = TP.getDAGPatterns().getTargetInfo();
+ return UpdateNodeType(ResNo, Tgt.getRegisterClass(RC).getValueTypes(), TP);
+}
+
+
//===----------------------------------------------------------------------===//
// SDNodeInfo implementation
//
@@ -1287,8 +1321,18 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) {
/// type which should be applied to it. This will infer the type of register
/// references from the register file information, for example.
///
+/// When Unnamed is set, return the type of a DAG operand with no name, such as
+/// the F8RC register class argument in:
+///
+/// (COPY_TO_REGCLASS GPR:$src, F8RC)
+///
+/// When Unnamed is false, return the type of a named DAG operand such as the
+/// GPR:$src operand above.
+///
static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
- bool NotRegisters, TreePattern &TP) {
+ bool NotRegisters,
+ bool Unnamed,
+ TreePattern &TP) {
// Check to see if this is a register operand.
if (R->isSubClassOf("RegisterOperand")) {
assert(ResNo == 0 && "Regoperand ref only has one result!");
@@ -1302,6 +1346,13 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
// Check to see if this is a register or a register class.
if (R->isSubClassOf("RegisterClass")) {
assert(ResNo == 0 && "Regclass ref only has one result!");
+ // An unnamed register class represents itself as an i32 immediate, for
+ // example on a COPY_TO_REGCLASS instruction.
+ if (Unnamed)
+ return EEVT::TypeSet(MVT::i32, TP);
+
+ // In a named operand, the register class provides the possible set of
+ // types.
if (NotRegisters)
return EEVT::TypeSet(); // Unknown.
const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo();
@@ -1327,9 +1378,27 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo,
return EEVT::TypeSet();
}
- if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
+ if (R->isSubClassOf("ValueType")) {
assert(ResNo == 0 && "This node only has one result!");
- // Using a VTSDNode or CondCodeSDNode.
+ // An unnamed VTSDNode represents itself as an MVT::Other immediate.
+ //
+ // (sext_inreg GPR:$src, i16)
+ // ~~~
+ if (Unnamed)
+ return EEVT::TypeSet(MVT::Other, TP);
+ // With a name, the ValueType simply provides the type of the named
+ // variable.
+ //
+ // (sext_inreg i32:$src, i16)
+ // ~~~~~~~~
+ if (NotRegisters)
+ return EEVT::TypeSet(); // Unknown.
+ return EEVT::TypeSet(getValueType(R), TP);
+ }
+
+ if (R->isSubClassOf("CondCode")) {
+ assert(ResNo == 0 && "This node only has one result!");
+ // Using a CondCodeSDNode.
return EEVT::TypeSet(MVT::Other, TP);
}
@@ -1435,7 +1504,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
bool MadeChange = false;
for (unsigned i = 0, e = Types.size(); i != e; ++i)
MadeChange |= UpdateNodeType(i, getImplicitType(DI->getDef(), i,
- NotRegisters, TP), TP);
+ NotRegisters,
+ !hasName(), TP), TP);
return MadeChange;
}
@@ -1498,25 +1568,6 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
return MadeChange;
}
- if (getOperator()->getName() == "COPY_TO_REGCLASS") {
- bool MadeChange = false;
- MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
- MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
-
- assert(getChild(0)->getNumTypes() == 1 &&
- getChild(1)->getNumTypes() == 1 && "Unhandled case");
-
- // child #1 of COPY_TO_REGCLASS should be a register class. We don't care
- // what type it gets, so if it didn't get a concrete type just give it the
- // first viable type from the reg class.
- if (!getChild(1)->hasTypeSet(0) &&
- !getChild(1)->getExtType(0).isCompletelyUnknown()) {
- MVT::SimpleValueType RCVT = getChild(1)->getExtType(0).getTypeList()[0];
- MadeChange |= getChild(1)->UpdateNodeType(0, RCVT, TP);
- }
- return MadeChange;
- }
-
if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
bool MadeChange = false;
@@ -1575,26 +1626,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
// (outs) list of the instruction.
// FIXME: Cap at one result so far.
unsigned NumResultsToAdd = InstInfo.Operands.NumDefs ? 1 : 0;
- for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo) {
- Record *ResultNode = Inst.getResult(ResNo);
-
- if (ResultNode->isSubClassOf("PointerLikeRegClass")) {
- MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP);
- } else if (ResultNode->isSubClassOf("RegisterOperand")) {
- Record *RegClass = ResultNode->getValueAsDef("RegClass");
- const CodeGenRegisterClass &RC =
- CDP.getTargetInfo().getRegisterClass(RegClass);
- MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
- } else if (ResultNode->isSubClassOf("unknown_class")) {
- // Nothing to do.
- } else {
- assert(ResultNode->isSubClassOf("RegisterClass") &&
- "Operands should be register classes!");
- const CodeGenRegisterClass &RC =
- CDP.getTargetInfo().getRegisterClass(ResultNode);
- MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP);
- }
- }
+ for (unsigned ResNo = 0; ResNo != NumResultsToAdd; ++ResNo)
+ MadeChange |= UpdateNodeTypeFromInst(ResNo, Inst.getResult(ResNo), TP);
// If the instruction has implicit defs, we apply the first one as a result.
// FIXME: This sucks, it should apply all implicit defs.
@@ -1636,30 +1669,44 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
return false;
}
- MVT::SimpleValueType VT;
TreePatternNode *Child = getChild(ChildNo++);
unsigned ChildResNo = 0; // Instructions always use res #0 of their op.
- if (OperandNode->isSubClassOf("RegisterClass")) {
- const CodeGenRegisterClass &RC =
- CDP.getTargetInfo().getRegisterClass(OperandNode);
- MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
- } else if (OperandNode->isSubClassOf("RegisterOperand")) {
- Record *RegClass = OperandNode->getValueAsDef("RegClass");
- const CodeGenRegisterClass &RC =
- CDP.getTargetInfo().getRegisterClass(RegClass);
- MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP);
- } else if (OperandNode->isSubClassOf("Operand")) {
- VT = getValueType(OperandNode->getValueAsDef("Type"));
- MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP);
- } else if (OperandNode->isSubClassOf("PointerLikeRegClass")) {
- MadeChange |= Child->UpdateNodeType(ChildResNo, MVT::iPTR, TP);
- } else if (OperandNode->isSubClassOf("unknown_class")) {
- // Nothing to do.
- } else
- llvm_unreachable("Unknown operand type!");
+ // If the operand has sub-operands, they may be provided by distinct
+ // child patterns, so attempt to match each sub-operand separately.
+ if (OperandNode->isSubClassOf("Operand")) {
+ DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
+ if (unsigned NumArgs = MIOpInfo->getNumArgs()) {
+ // But don't do that if the whole operand is being provided by
+ // a single ComplexPattern.
+ const ComplexPattern *AM = Child->getComplexPatternInfo(CDP);
+ if (!AM || AM->getNumOperands() < NumArgs) {
+ // Match first sub-operand against the child we already have.
+ Record *SubRec = cast<DefInit>(MIOpInfo->getArg(0))->getDef();
+ MadeChange |=
+ Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
+
+ // And the remaining sub-operands against subsequent children.
+ for (unsigned Arg = 1; Arg < NumArgs; ++Arg) {
+ if (ChildNo >= getNumChildren()) {
+ TP.error("Instruction '" + getOperator()->getName() +
+ "' expects more operands than were provided.");
+ return false;
+ }
+ Child = getChild(ChildNo++);
+
+ SubRec = cast<DefInit>(MIOpInfo->getArg(Arg))->getDef();
+ MadeChange |=
+ Child->UpdateNodeTypeFromInst(ChildResNo, SubRec, TP);
+ }
+ continue;
+ }
+ }
+ }
- MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
+ // If we didn't match by pieces above, attempt to match the whole
+ // operand now.
+ MadeChange |= Child->UpdateNodeTypeFromInst(ChildResNo, OperandNode, TP);
}
if (ChildNo != getNumChildren()) {
@@ -1668,6 +1715,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
return false;
}
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+ MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
return MadeChange;
}
@@ -1817,6 +1866,16 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){
return Res;
}
+ // ?:$name or just $name.
+ if (TheInit == UnsetInit::get()) {
+ if (OpName.empty())
+ error("'?' argument requires a name to match with operand list");
+ TreePatternNode *Res = new TreePatternNode(TheInit, 1);
+ Args.push_back(OpName);
+ Res->setName(OpName);
+ return Res;
+ }
+
if (IntInit *II = dyn_cast<IntInit>(TheInit)) {
if (!OpName.empty())
error("Constant int argument should not have a name!");
@@ -2383,6 +2442,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
I->error("set destination should be a register!");
if (Val->getDef()->isSubClassOf("RegisterClass") ||
+ Val->getDef()->isSubClassOf("ValueType") ||
Val->getDef()->isSubClassOf("RegisterOperand") ||
Val->getDef()->isSubClassOf("PointerLikeRegClass")) {
if (Dest->getName().empty())
@@ -2599,6 +2659,25 @@ getInstructionsInTree(TreePatternNode *Tree, SmallVectorImpl<Record*> &Instrs) {
getInstructionsInTree(Tree->getChild(i), Instrs);
}
+/// Check the class of a pattern leaf node against the instruction operand it
+/// represents.
+static bool checkOperandClass(CGIOperandList::OperandInfo &OI,
+ Record *Leaf) {
+ if (OI.Rec == Leaf)
+ return true;
+
+ // Allow direct value types to be used in instruction set patterns.
+ // The type will be checked later.
+ if (Leaf->isSubClassOf("ValueType"))
+ return true;
+
+ // Patterns can also be ComplexPattern instances.
+ if (Leaf->isSubClassOf("ComplexPattern"))
+ return true;
+
+ return false;
+}
+
/// ParseInstructions - Parse all of the instructions, inlining and resolving
/// any fragments involved. This populates the Instructions list with fully
/// resolved instructions.
@@ -2708,7 +2787,7 @@ void CodeGenDAGPatterns::ParseInstructions() {
I->error("Operand $" + OpName + " should be a set destination: all "
"outputs must occur before inputs in operand list!");
- if (CGI.Operands[i].Rec != R)
+ if (!checkOperandClass(CGI.Operands[i], R))
I->error("Operand $" + OpName + " class mismatch!");
// Remember the return type.
@@ -2747,7 +2826,7 @@ void CodeGenDAGPatterns::ParseInstructions() {
if (InVal->isLeaf() && isa<DefInit>(InVal->getLeafValue())) {
Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
- if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern"))
+ if (!checkOperandClass(Op, InRec))
I->error("Operand $" + OpName + "'s register class disagrees"
" between the operand and pattern");
}
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
index 9be763f2ff11..7c2fa3674108 100644
--- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
+++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.h
@@ -15,15 +15,15 @@
#ifndef CODEGEN_DAGPATTERNS_H
#define CODEGEN_DAGPATTERNS_H
-#include "CodeGenTarget.h"
#include "CodeGenIntrinsics.h"
+#include "CodeGenTarget.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ErrorHandling.h"
-#include <set>
#include <algorithm>
-#include <vector>
#include <map>
+#include <set>
+#include <vector>
namespace llvm {
class Record;
@@ -59,7 +59,7 @@ namespace EEVT {
public:
TypeSet() {}
TypeSet(MVT::SimpleValueType VT, TreePattern &TP);
- TypeSet(const std::vector<MVT::SimpleValueType> &VTList);
+ TypeSet(ArrayRef<MVT::SimpleValueType> VTList);
bool isCompletelyUnknown() const { return TypeVec.empty(); }
@@ -334,6 +334,7 @@ public:
}
~TreePatternNode();
+ bool hasName() const { return !Name.empty(); }
const std::string &getName() const { return Name; }
void setName(StringRef N) { Name.assign(N.begin(), N.end()); }
@@ -463,6 +464,11 @@ public: // Higher level manipulation routines.
return Types[ResNo].MergeInTypeInfo(EEVT::TypeSet(InTy, TP), TP);
}
+ // Update node type with types inferred from an instruction operand or result
+ // def from the ins/outs lists.
+ // Return true if the type changed.
+ bool UpdateNodeTypeFromInst(unsigned ResNo, Record *Operand, TreePattern &TP);
+
/// ContainsUnresolvedType - Return true if this tree contains any
/// unresolved types.
bool ContainsUnresolvedType() const {
diff --git a/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp b/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
index 0a8684d3da5a..367320498f59 100644
--- a/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -13,11 +13,11 @@
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <set>
using namespace llvm;
diff --git a/contrib/llvm/utils/TableGen/CodeGenInstruction.h b/contrib/llvm/utils/TableGen/CodeGenInstruction.h
index 55d44399dff9..d1e115355483 100644
--- a/contrib/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/contrib/llvm/utils/TableGen/CodeGenInstruction.h
@@ -14,12 +14,12 @@
#ifndef CODEGEN_INSTRUCTION_H
#define CODEGEN_INSTRUCTION_H
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/SourceMgr.h"
#include <string>
-#include <vector>
#include <utility>
+#include <vector>
namespace llvm {
class Record;
diff --git a/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h b/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
index 6efe952ea2bb..f0570f95b8ab 100644
--- a/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -14,9 +14,9 @@
#ifndef CODEGEN_INTRINSIC_H
#define CODEGEN_INTRINSIC_H
+#include "llvm/CodeGen/ValueTypes.h"
#include <string>
#include <vector>
-#include "llvm/CodeGen/ValueTypes.h"
namespace llvm {
class Record;
diff --git a/contrib/llvm/utils/TableGen/CodeGenMapTable.cpp b/contrib/llvm/utils/TableGen/CodeGenMapTable.cpp
index 1653d67da97a..ee32aa13e034 100644
--- a/contrib/llvm/utils/TableGen/CodeGenMapTable.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenMapTable.cpp
@@ -533,12 +533,11 @@ static void emitEnums(raw_ostream &OS, RecordKeeper &Records) {
II = ColFieldValueMap.begin(), IE = ColFieldValueMap.end();
II != IE; II++) {
std::vector<Init*> FieldValues = (*II).second;
- unsigned FieldSize = FieldValues.size();
// Delete duplicate entries from ColFieldValueMap
- for (unsigned i = 0; i < FieldSize - 1; i++) {
+ for (unsigned i = 0; i < FieldValues.size() - 1; i++) {
Init *CurVal = FieldValues[i];
- for (unsigned j = i+1; j < FieldSize; j++) {
+ for (unsigned j = i+1; j < FieldValues.size(); j++) {
if (CurVal == FieldValues[j]) {
FieldValues.erase(FieldValues.begin()+j);
}
@@ -547,9 +546,9 @@ static void emitEnums(raw_ostream &OS, RecordKeeper &Records) {
// Emit enumerated values for the column fields.
OS << "enum " << (*II).first << " {\n";
- for (unsigned i = 0; i < FieldSize; i++) {
+ for (unsigned i = 0, endFV = FieldValues.size(); i < endFV; i++) {
OS << "\t" << (*II).first << "_" << FieldValues[i]->getAsUnquotedString();
- if (i != FieldValues.size() - 1)
+ if (i != endFV - 1)
OS << ",\n";
else
OS << "\n};\n\n";
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
index 580e319f24ec..993b8dba4267 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -14,12 +14,12 @@
#include "CodeGenRegisters.h"
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Error.h"
#include "llvm/ADT/IntEqClasses.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/TableGen/Error.h"
using namespace llvm;
@@ -636,8 +636,10 @@ struct TupleExpander : SetTheory::Expander {
Elts.insert(NewReg);
// Copy Proto super-classes.
- for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i)
- NewReg->addSuperClass(Proto->getSuperClasses()[i]);
+ ArrayRef<Record *> Supers = Proto->getSuperClasses();
+ ArrayRef<SMRange> Ranges = Proto->getSuperClassRanges();
+ for (unsigned i = 0, e = Supers.size(); i != e; ++i)
+ NewReg->addSuperClass(Supers[i], Ranges[i]);
// Copy Proto fields.
for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
@@ -701,7 +703,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
// Rename anonymous register classes.
if (R->getName().size() > 9 && R->getName()[9] == '.') {
static unsigned AnonCounter = 0;
- R->setName("AnonRegClass_"+utostr(AnonCounter++));
+ R->setName("AnonRegClass_" + utostr(AnonCounter));
+ // MSVC2012 ICEs if AnonCounter++ is directly passed to utostr.
+ ++AnonCounter;
}
std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
@@ -1196,6 +1200,12 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
if (Idx->getComposites().empty()) {
Idx->LaneMask = 1u << Bit;
// Share bit 31 in the unlikely case there are more than 32 leafs.
+ //
+ // Sharing bits is harmless; it allows graceful degradation in targets
+ // with more than 32 vector lanes. They simply get a limited resolution
+ // view of lanes beyond the 32nd.
+ //
+ // See also the comment for getSubRegIndexLaneMask().
if (Bit < 31) ++Bit;
} else {
Idx->LaneMask = 0;
@@ -1589,6 +1599,35 @@ void CodeGenRegBank::computeRegUnitSets() {
}
assert(!RegClassUnitSets[RCIdx].empty() && "missing unit set for regclass");
}
+
+ // For each register unit, ensure that we have the list of UnitSets that
+ // contain the unit. Normally, this matches an existing list of UnitSets for a
+ // register class. If not, we create a new entry in RegClassUnitSets as a
+ // "fake" register class.
+ for (unsigned UnitIdx = 0, UnitEnd = NumNativeRegUnits;
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ std::vector<unsigned> RUSets;
+ for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) {
+ RegUnitSet &RUSet = RegUnitSets[i];
+ if (std::find(RUSet.Units.begin(), RUSet.Units.end(), UnitIdx)
+ == RUSet.Units.end())
+ continue;
+ RUSets.push_back(i);
+ }
+ unsigned RCUnitSetsIdx = 0;
+ for (unsigned e = RegClassUnitSets.size();
+ RCUnitSetsIdx != e; ++RCUnitSetsIdx) {
+ if (RegClassUnitSets[RCUnitSetsIdx] == RUSets) {
+ break;
+ }
+ }
+ RegUnits[UnitIdx].RegClassUnitSetsIdx = RCUnitSetsIdx;
+ if (RCUnitSetsIdx == RegClassUnitSets.size()) {
+ // Create a new list of UnitSets as a "fake" register class.
+ RegClassUnitSets.resize(RCUnitSetsIdx + 1);
+ RegClassUnitSets[RCUnitSetsIdx].swap(RUSets);
+ }
+ }
}
void CodeGenRegBank::computeDerivedInfo() {
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.h b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
index e41107415612..4f2cc28d4924 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
@@ -16,17 +16,17 @@
#define CODEGEN_REGISTERS_H
#include "SetTheory.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Record.h"
#include <cstdlib>
#include <map>
-#include <string>
#include <set>
+#include <string>
#include <vector>
namespace llvm {
@@ -261,7 +261,7 @@ namespace llvm {
public:
unsigned EnumValue;
std::string Namespace;
- std::vector<MVT::SimpleValueType> VTs;
+ SmallVector<MVT::SimpleValueType, 4> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
int CopyCost;
@@ -274,7 +274,7 @@ namespace llvm {
const std::string &getName() const { return Name; }
std::string getQualifiedName() const;
- const std::vector<MVT::SimpleValueType> &getValueTypes() const {return VTs;}
+ ArrayRef<MVT::SimpleValueType> getValueTypes() const {return VTs;}
unsigned getNumValueTypes() const { return VTs.size(); }
MVT::SimpleValueType getValueTypeNum(unsigned VTNum) const {
@@ -403,7 +403,11 @@ namespace llvm {
// these two registers and their super-registers.
const CodeGenRegister *Roots[2];
- RegUnit() : Weight(0) { Roots[0] = Roots[1] = 0; }
+ // Index into RegClassUnitSets where we can find the list of UnitSets that
+ // contain this unit.
+ unsigned RegClassUnitSetsIdx;
+
+ RegUnit() : Weight(0), RegClassUnitSetsIdx(0) { Roots[0] = Roots[1] = 0; }
ArrayRef<const CodeGenRegister*> getRoots() const {
assert(!(Roots[1] && !Roots[0]) && "Invalid roots array");
@@ -462,6 +466,10 @@ namespace llvm {
// Map RegisterClass index to the index of the RegUnitSet that contains the
// class's units and any inferred RegUnit supersets.
+ //
+ // NOTE: This could grow beyond the number of register classes when we map
+ // register units to lists of unit sets. If the list of unit sets does not
+ // already exist for a register class, we create a new entry in this vector.
std::vector<std::vector<unsigned> > RegClassUnitSets;
// Add RC to *2RC maps.
@@ -615,6 +623,13 @@ namespace llvm {
return RegUnitSets[Idx];
}
+ // The number of pressure set lists may be larget than the number of
+ // register classes if some register units appeared in a list of sets that
+ // did not correspond to an existing register class.
+ unsigned getNumRegClassPressureSetLists() const {
+ return RegClassUnitSets.size();
+ }
+
// Get a list of pressure set IDs for a register class. Liveness of a
// register in this class impacts each pressure set in this list by the
// weight of the register. An exact solution requires all registers in a
diff --git a/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp b/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
index 63cc97a8c1da..c02f0843d651 100644
--- a/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -16,10 +16,10 @@
#include "CodeGenSchedule.h"
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Error.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Regex.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/TableGen/Error.h"
using namespace llvm;
@@ -88,7 +88,7 @@ struct InstRegexOp : public SetTheory::Operator {
/// CodeGenModels ctor interprets machine model records and populates maps.
CodeGenSchedModels::CodeGenSchedModels(RecordKeeper &RK,
const CodeGenTarget &TGT):
- Records(RK), Target(TGT), NumItineraryClasses(0) {
+ Records(RK), Target(TGT) {
Sets.addFieldExpander("InstRW", "Instrs");
@@ -217,7 +217,7 @@ void CodeGenSchedModels::collectSchedRW() {
for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
E = Target.inst_end(); I != E; ++I) {
Record *SchedDef = (*I)->TheDef;
- if (!SchedDef->isSubClassOf("Sched"))
+ if (SchedDef->isValueUnset("SchedRW"))
continue;
RecVec RWs = SchedDef->getValueAsListOfDefs("SchedRW");
for (RecIter RWI = RWs.begin(), RWE = RWs.end(); RWI != RWE; ++RWI) {
@@ -502,40 +502,25 @@ void CodeGenSchedModels::collectSchedClasses() {
// NoItinerary is always the first class at Idx=0
SchedClasses.resize(1);
- SchedClasses.back().Name = "NoItinerary";
+ SchedClasses.back().Index = 0;
+ SchedClasses.back().Name = "NoInstrModel";
+ SchedClasses.back().ItinClassDef = Records.getDef("NoItinerary");
SchedClasses.back().ProcIndices.push_back(0);
- SchedClassIdxMap[SchedClasses.back().Name] = 0;
- // Gather and sort all itinerary classes used by instruction descriptions.
- RecVec ItinClassList;
+ // Create a SchedClass for each unique combination of itinerary class and
+ // SchedRW list.
for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
E = Target.inst_end(); I != E; ++I) {
Record *ItinDef = (*I)->TheDef->getValueAsDef("Itinerary");
- // Map a new SchedClass with no index.
- if (!SchedClassIdxMap.count(ItinDef->getName())) {
- SchedClassIdxMap[ItinDef->getName()] = 0;
- ItinClassList.push_back(ItinDef);
- }
- }
- // Assign each itinerary class unique number, skipping NoItinerary==0
- NumItineraryClasses = ItinClassList.size();
- std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
- for (unsigned i = 0, N = NumItineraryClasses; i < N; i++) {
- Record *ItinDef = ItinClassList[i];
- SchedClassIdxMap[ItinDef->getName()] = SchedClasses.size();
- SchedClasses.push_back(CodeGenSchedClass(ItinDef));
- }
- // Infer classes from SchedReadWrite resources listed for each
- // instruction definition that inherits from class Sched.
- for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
- E = Target.inst_end(); I != E; ++I) {
- if (!(*I)->TheDef->isSubClassOf("Sched"))
- continue;
IdxVec Writes, Reads;
- findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
+ if (!(*I)->TheDef->isValueUnset("SchedRW"))
+ findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
+
// ProcIdx == 0 indicates the class applies to all processors.
IdxVec ProcIndices(1, 0);
- addSchedClass(Writes, Reads, ProcIndices);
+
+ unsigned SCIdx = addSchedClass(ItinDef, Writes, Reads, ProcIndices);
+ InstrClassMap[(*I)->TheDef] = SCIdx;
}
// Create classes for InstRW defs.
RecVec InstRWDefs = Records.getAllDerivedDefinitions("InstRW");
@@ -549,68 +534,70 @@ void CodeGenSchedModels::collectSchedClasses() {
DEBUG(EnableDump = true);
if (!EnableDump)
return;
+
for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
E = Target.inst_end(); I != E; ++I) {
- Record *SchedDef = (*I)->TheDef;
+
std::string InstName = (*I)->TheDef->getName();
- if (SchedDef->isSubClassOf("Sched")) {
+ unsigned SCIdx = InstrClassMap.lookup((*I)->TheDef);
+ if (!SCIdx) {
+ dbgs() << "No machine model for " << (*I)->TheDef->getName() << '\n';
+ continue;
+ }
+ CodeGenSchedClass &SC = getSchedClass(SCIdx);
+ if (SC.ProcIndices[0] != 0)
+ PrintFatalError((*I)->TheDef->getLoc(), "Instruction's sched class "
+ "must not be subtarget specific.");
+
+ IdxVec ProcIndices;
+ if (SC.ItinClassDef->getName() != "NoItinerary") {
+ ProcIndices.push_back(0);
+ dbgs() << "Itinerary for " << InstName << ": "
+ << SC.ItinClassDef->getName() << '\n';
+ }
+ if (!SC.Writes.empty()) {
+ ProcIndices.push_back(0);
+ dbgs() << "SchedRW machine model for " << InstName;
+ for (IdxIter WI = SC.Writes.begin(), WE = SC.Writes.end(); WI != WE; ++WI)
+ dbgs() << " " << SchedWrites[*WI].Name;
+ for (IdxIter RI = SC.Reads.begin(), RE = SC.Reads.end(); RI != RE; ++RI)
+ dbgs() << " " << SchedReads[*RI].Name;
+ dbgs() << '\n';
+ }
+ const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
+ for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end();
+ RWI != RWE; ++RWI) {
+ const CodeGenProcModel &ProcModel =
+ getProcModel((*RWI)->getValueAsDef("SchedModel"));
+ ProcIndices.push_back(ProcModel.Index);
+ dbgs() << "InstRW on " << ProcModel.ModelName << " for " << InstName;
IdxVec Writes;
IdxVec Reads;
- findRWs((*I)->TheDef->getValueAsListOfDefs("SchedRW"), Writes, Reads);
- dbgs() << "SchedRW machine model for " << InstName;
+ findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"),
+ Writes, Reads);
for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
dbgs() << " " << SchedWrites[*WI].Name;
for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
dbgs() << " " << SchedReads[*RI].Name;
dbgs() << '\n';
}
- unsigned SCIdx = InstrClassMap.lookup((*I)->TheDef);
- if (SCIdx) {
- const RecVec &RWDefs = SchedClasses[SCIdx].InstRWs;
- for (RecIter RWI = RWDefs.begin(), RWE = RWDefs.end();
- RWI != RWE; ++RWI) {
- const CodeGenProcModel &ProcModel =
- getProcModel((*RWI)->getValueAsDef("SchedModel"));
- dbgs() << "InstRW on " << ProcModel.ModelName << " for " << InstName;
- IdxVec Writes;
- IdxVec Reads;
- findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"),
- Writes, Reads);
- for (IdxIter WI = Writes.begin(), WE = Writes.end(); WI != WE; ++WI)
- dbgs() << " " << SchedWrites[*WI].Name;
- for (IdxIter RI = Reads.begin(), RE = Reads.end(); RI != RE; ++RI)
- dbgs() << " " << SchedReads[*RI].Name;
- dbgs() << '\n';
- }
- continue;
- }
- if (!SchedDef->isSubClassOf("Sched")
- && (SchedDef->getValueAsDef("Itinerary")->getName() == "NoItinerary")) {
- dbgs() << "No machine model for " << (*I)->TheDef->getName() << '\n';
+ for (std::vector<CodeGenProcModel>::iterator PI = ProcModels.begin(),
+ PE = ProcModels.end(); PI != PE; ++PI) {
+ if (!std::count(ProcIndices.begin(), ProcIndices.end(), PI->Index))
+ dbgs() << "No machine model for " << (*I)->TheDef->getName()
+ << " on processor " << PI->ModelName << '\n';
}
}
}
-unsigned CodeGenSchedModels::getSchedClassIdx(
- const RecVec &RWDefs) const {
-
- IdxVec Writes, Reads;
- findRWs(RWDefs, Writes, Reads);
- return findSchedClassIdx(Writes, Reads);
-}
-
/// Find an SchedClass that has been inferred from a per-operand list of
/// SchedWrites and SchedReads.
-unsigned CodeGenSchedModels::findSchedClassIdx(const IdxVec &Writes,
+unsigned CodeGenSchedModels::findSchedClassIdx(Record *ItinClassDef,
+ const IdxVec &Writes,
const IdxVec &Reads) const {
for (SchedClassIter I = schedClassBegin(), E = schedClassEnd(); I != E; ++I) {
- // Classes with InstRWs may have the same Writes/Reads as a class originally
- // produced by a SchedRW definition. We need to be able to recover the
- // original class index for processors that don't match any InstRWs.
- if (I->ItinClassDef || !I->InstRWs.empty())
- continue;
-
- if (I->Writes == Writes && I->Reads == Reads) {
+ if (I->ItinClassDef == ItinClassDef
+ && I->Writes == Writes && I->Reads == Reads) {
return I - schedClassBegin();
}
}
@@ -621,29 +608,17 @@ unsigned CodeGenSchedModels::findSchedClassIdx(const IdxVec &Writes,
unsigned CodeGenSchedModels::getSchedClassIdx(
const CodeGenInstruction &Inst) const {
- unsigned SCIdx = InstrClassMap.lookup(Inst.TheDef);
- if (SCIdx)
- return SCIdx;
-
- // If this opcode isn't mapped by the subtarget fallback to the instruction
- // definition's SchedRW or ItinDef values.
- if (Inst.TheDef->isSubClassOf("Sched")) {
- RecVec RWs = Inst.TheDef->getValueAsListOfDefs("SchedRW");
- return getSchedClassIdx(RWs);
- }
- Record *ItinDef = Inst.TheDef->getValueAsDef("Itinerary");
- assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass");
- unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName());
- assert(Idx <= NumItineraryClasses && "bad ItinClass index");
- return Idx;
+ return InstrClassMap.lookup(Inst.TheDef);
}
std::string CodeGenSchedModels::createSchedClassName(
- const IdxVec &OperWrites, const IdxVec &OperReads) {
+ Record *ItinClassDef, const IdxVec &OperWrites, const IdxVec &OperReads) {
std::string Name;
+ if (ItinClassDef && ItinClassDef->getName() != "NoItinerary")
+ Name = ItinClassDef->getName();
for (IdxIter WI = OperWrites.begin(), WE = OperWrites.end(); WI != WE; ++WI) {
- if (WI != OperWrites.begin())
+ if (!Name.empty())
Name += '_';
Name += SchedWrites[*WI].Name;
}
@@ -665,17 +640,18 @@ std::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) {
return Name;
}
-/// Add an inferred sched class from a per-operand list of SchedWrites and
-/// SchedReads. ProcIndices contains the set of IDs of processors that may
-/// utilize this class.
-unsigned CodeGenSchedModels::addSchedClass(const IdxVec &OperWrites,
+/// Add an inferred sched class from an itinerary class and per-operand list of
+/// SchedWrites and SchedReads. ProcIndices contains the set of IDs of
+/// processors that may utilize this class.
+unsigned CodeGenSchedModels::addSchedClass(Record *ItinClassDef,
+ const IdxVec &OperWrites,
const IdxVec &OperReads,
const IdxVec &ProcIndices)
{
assert(!ProcIndices.empty() && "expect at least one ProcIdx");
- unsigned Idx = findSchedClassIdx(OperWrites, OperReads);
- if (Idx) {
+ unsigned Idx = findSchedClassIdx(ItinClassDef, OperWrites, OperReads);
+ if (Idx || SchedClasses[0].isKeyEqual(ItinClassDef, OperWrites, OperReads)) {
IdxVec PI;
std::set_union(SchedClasses[Idx].ProcIndices.begin(),
SchedClasses[Idx].ProcIndices.end(),
@@ -687,7 +663,9 @@ unsigned CodeGenSchedModels::addSchedClass(const IdxVec &OperWrites,
Idx = SchedClasses.size();
SchedClasses.resize(Idx+1);
CodeGenSchedClass &SC = SchedClasses.back();
- SC.Name = createSchedClassName(OperWrites, OperReads);
+ SC.Index = Idx;
+ SC.Name = createSchedClassName(ItinClassDef, OperWrites, OperReads);
+ SC.ItinClassDef = ItinClassDef;
SC.Writes = OperWrites;
SC.Reads = OperReads;
SC.ProcIndices = ProcIndices;
@@ -709,19 +687,10 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
PrintFatalError(InstRWDef->getLoc(), "No matching instruction opcodes");
for (RecIter I = InstDefs->begin(), E = InstDefs->end(); I != E; ++I) {
- unsigned SCIdx = 0;
InstClassMapTy::const_iterator Pos = InstrClassMap.find(*I);
- if (Pos != InstrClassMap.end())
- SCIdx = Pos->second;
- else {
- // This instruction has not been mapped yet. Get the original class. All
- // instructions in the same InstrRW class must be from the same original
- // class because that is the fall-back class for other processors.
- Record *ItinDef = (*I)->getValueAsDef("Itinerary");
- SCIdx = SchedClassIdxMap.lookup(ItinDef->getName());
- if (!SCIdx && (*I)->isSubClassOf("Sched"))
- SCIdx = getSchedClassIdx((*I)->getValueAsListOfDefs("SchedRW"));
- }
+ if (Pos == InstrClassMap.end())
+ PrintFatalError((*I)->getLoc(), "No sched class for instruction.");
+ unsigned SCIdx = Pos->second;
unsigned CIdx = 0, CEnd = ClassInstrs.size();
for (; CIdx != CEnd; ++CIdx) {
if (ClassInstrs[CIdx].first == SCIdx)
@@ -741,7 +710,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
ArrayRef<Record*> InstDefs = ClassInstrs[CIdx].second;
// If the all instrs in the current class are accounted for, then leave
// them mapped to their old class.
- if (SchedClasses[OldSCIdx].InstRWs.size() == InstDefs.size()) {
+ if (OldSCIdx && SchedClasses[OldSCIdx].InstRWs.size() == InstDefs.size()) {
assert(SchedClasses[OldSCIdx].ProcIndices[0] == 0 &&
"expected a generic SchedClass");
continue;
@@ -749,6 +718,7 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
unsigned SCIdx = SchedClasses.size();
SchedClasses.resize(SCIdx+1);
CodeGenSchedClass &SC = SchedClasses.back();
+ SC.Index = SCIdx;
SC.Name = createSchedClassName(InstDefs);
// Preserve ItinDef and Writes/Reads for processors without an InstRW entry.
SC.ItinClassDef = SchedClasses[OldSCIdx].ItinClassDef;
@@ -780,32 +750,48 @@ void CodeGenSchedModels::createInstRWClass(Record *InstRWDef) {
}
}
+// True if collectProcItins found anything.
+bool CodeGenSchedModels::hasItineraries() const {
+ for (CodeGenSchedModels::ProcIter PI = procModelBegin(), PE = procModelEnd();
+ PI != PE; ++PI) {
+ if (PI->hasItineraries())
+ return true;
+ }
+ return false;
+}
+
// Gather the processor itineraries.
void CodeGenSchedModels::collectProcItins() {
for (std::vector<CodeGenProcModel>::iterator PI = ProcModels.begin(),
PE = ProcModels.end(); PI != PE; ++PI) {
CodeGenProcModel &ProcModel = *PI;
- RecVec ItinRecords = ProcModel.ItinsDef->getValueAsListOfDefs("IID");
- // Skip empty itinerary.
- if (ItinRecords.empty())
+ if (!ProcModel.hasItineraries())
continue;
- ProcModel.ItinDefList.resize(NumItineraryClasses+1);
+ RecVec ItinRecords = ProcModel.ItinsDef->getValueAsListOfDefs("IID");
+ assert(!ItinRecords.empty() && "ProcModel.hasItineraries is incorrect");
+
+ // Populate ItinDefList with Itinerary records.
+ ProcModel.ItinDefList.resize(NumInstrSchedClasses);
// Insert each itinerary data record in the correct position within
// the processor model's ItinDefList.
for (unsigned i = 0, N = ItinRecords.size(); i < N; i++) {
Record *ItinData = ItinRecords[i];
Record *ItinDef = ItinData->getValueAsDef("TheClass");
- if (!SchedClassIdxMap.count(ItinDef->getName())) {
+ bool FoundClass = false;
+ for (SchedClassIter SCI = schedClassBegin(), SCE = schedClassEnd();
+ SCI != SCE; ++SCI) {
+ // Multiple SchedClasses may share an itinerary. Update all of them.
+ if (SCI->ItinClassDef == ItinDef) {
+ ProcModel.ItinDefList[SCI->Index] = ItinData;
+ FoundClass = true;
+ }
+ }
+ if (!FoundClass) {
DEBUG(dbgs() << ProcModel.ItinsDef->getName()
- << " has unused itinerary class " << ItinDef->getName() << '\n');
- continue;
+ << " missing class for itinerary " << ItinDef->getName() << '\n');
}
- assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass");
- unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName());
- assert(Idx <= NumItineraryClasses && "bad ItinClass index");
- ProcModel.ItinDefList[Idx] = ItinData;
}
// Check for missing itinerary entries.
assert(!ProcModel.ItinDefList[0] && "NoItinerary class can't have rec");
@@ -839,13 +825,17 @@ void CodeGenSchedModels::collectProcItinRW() {
/// Infer new classes from existing classes. In the process, this may create new
/// SchedWrites from sequences of existing SchedWrites.
void CodeGenSchedModels::inferSchedClasses() {
+ DEBUG(dbgs() << NumInstrSchedClasses << " instr sched classes.\n");
+
// Visit all existing classes and newly created classes.
for (unsigned Idx = 0; Idx != SchedClasses.size(); ++Idx) {
+ assert(SchedClasses[Idx].Index == Idx && "bad SCIdx");
+
if (SchedClasses[Idx].ItinClassDef)
inferFromItinClass(SchedClasses[Idx].ItinClassDef, Idx);
- else if (!SchedClasses[Idx].InstRWs.empty())
+ if (!SchedClasses[Idx].InstRWs.empty())
inferFromInstRWs(Idx);
- else {
+ if (!SchedClasses[Idx].Writes.empty()) {
inferFromRW(SchedClasses[Idx].Writes, SchedClasses[Idx].Reads,
Idx, SchedClasses[Idx].ProcIndices);
}
@@ -1042,11 +1032,13 @@ static bool hasVariant(ArrayRef<PredTransition> Transitions,
// Populate IntersectingVariants with any variants or aliased sequences of the
// given SchedRW whose processor indices and predicates are not mutually
-// exclusive with the given transition,
+// exclusive with the given transition.
void PredTransitions::getIntersectingVariants(
const CodeGenSchedRW &SchedRW, unsigned TransIdx,
std::vector<TransVariant> &IntersectingVariants) {
+ bool GenericRW = false;
+
std::vector<TransVariant> Variants;
if (SchedRW.HasVariants) {
unsigned VarProcIdx = 0;
@@ -1058,6 +1050,8 @@ void PredTransitions::getIntersectingVariants(
const RecVec VarDefs = SchedRW.TheDef->getValueAsListOfDefs("Variants");
for (RecIter RI = VarDefs.begin(), RE = VarDefs.end(); RI != RE; ++RI)
Variants.push_back(TransVariant(*RI, SchedRW.Index, VarProcIdx, 0));
+ if (VarProcIdx == 0)
+ GenericRW = true;
}
for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
AI != AE; ++AI) {
@@ -1081,6 +1075,8 @@ void PredTransitions::getIntersectingVariants(
Variants.push_back(
TransVariant(AliasRW.TheDef, SchedRW.Index, AliasProcIdx, 0));
}
+ if (AliasProcIdx == 0)
+ GenericRW = true;
}
for (unsigned VIdx = 0, VEnd = Variants.size(); VIdx != VEnd; ++VIdx) {
TransVariant &Variant = Variants[VIdx];
@@ -1118,6 +1114,10 @@ void PredTransitions::getIntersectingVariants(
TransVec.push_back(TransVec[TransIdx]);
}
}
+ if (GenericRW && IntersectingVariants.empty()) {
+ PrintFatalError(SchedRW.TheDef->getLoc(), "No variant of this type has "
+ "a matching predicate on any processor");
+ }
}
// Push the Reads/Writes selected by this variant onto the PredTransition
@@ -1215,10 +1215,6 @@ void PredTransitions::substituteVariantOperand(
// This will push a copies of TransVec[TransIdx] on the back of TransVec.
std::vector<TransVariant> IntersectingVariants;
getIntersectingVariants(SchedRW, TransIdx, IntersectingVariants);
- if (IntersectingVariants.empty())
- PrintFatalError(SchedRW.TheDef->getLoc(),
- "No variant of this type has "
- "a matching predicate on any processor");
// Now expand each variant on top of its copy of the transition.
for (std::vector<TransVariant>::const_iterator
IVI = IntersectingVariants.begin(),
@@ -1295,8 +1291,8 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
IdxVec ProcIndices(I->ProcIndices.begin(), I->ProcIndices.end());
CodeGenSchedTransition SCTrans;
SCTrans.ToClassIdx =
- SchedModels.addSchedClass(OperWritesVariant, OperReadsVariant,
- ProcIndices);
+ SchedModels.addSchedClass(/*ItinClassDef=*/0, OperWritesVariant,
+ OperReadsVariant, ProcIndices);
SCTrans.ProcIndices = ProcIndices;
// The final PredTerm is unique set of predicates guarding the transition.
RecVec Preds;
@@ -1318,7 +1314,7 @@ void CodeGenSchedModels::inferFromRW(const IdxVec &OperWrites,
const IdxVec &OperReads,
unsigned FromClassIdx,
const IdxVec &ProcIndices) {
- DEBUG(dbgs() << "INFER RW: ");
+ DEBUG(dbgs() << "INFER RW proc("; dumpIdxVec(ProcIndices); dbgs() << ") ");
// Create a seed transition with an empty PredTerm and the expanded sequences
// of SchedWrites for the current SchedClass.
@@ -1380,8 +1376,22 @@ void CodeGenSchedModels::collectProcResources() {
SCI != SCE; ++SCI) {
if (SCI->ItinClassDef)
collectItinProcResources(SCI->ItinClassDef);
- else
+ else {
+ // This class may have a default ReadWrite list which can be overriden by
+ // InstRW definitions.
+ if (!SCI->InstRWs.empty()) {
+ for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
+ RWI != RWE; ++RWI) {
+ Record *RWModelDef = (*RWI)->getValueAsDef("SchedModel");
+ IdxVec ProcIndices(1, getProcModel(RWModelDef).Index);
+ IdxVec Writes, Reads;
+ findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"),
+ Writes, Reads);
+ collectRWResources(Writes, Reads, ProcIndices);
+ }
+ }
collectRWResources(SCI->Writes, SCI->Reads, SCI->ProcIndices);
+ }
}
// Add resources separately defined by each subtarget.
RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes");
@@ -1528,6 +1538,20 @@ Record *CodeGenSchedModels::findProcResUnits(Record *ProcResKind,
ProcUnitDef = *RI;
}
}
+ RecVec ProcResGroups = Records.getAllDerivedDefinitions("ProcResGroup");
+ for (RecIter RI = ProcResGroups.begin(), RE = ProcResGroups.end();
+ RI != RE; ++RI) {
+
+ if (*RI == ProcResKind
+ && (*RI)->getValueAsDef("SchedModel") == PM.ModelDef) {
+ if (ProcUnitDef) {
+ PrintFatalError((*RI)->getLoc(),
+ "Multiple ProcessorResourceUnits associated with "
+ + ProcResKind->getName());
+ }
+ ProcUnitDef = *RI;
+ }
+ }
if (!ProcUnitDef) {
PrintFatalError(ProcResKind->getLoc(),
"No ProcessorResources associated with "
@@ -1549,6 +1573,9 @@ void CodeGenSchedModels::addProcResource(Record *ProcResKind,
return;
PM.ProcResourceDefs.push_back(ProcResUnits);
+ if (ProcResUnits->isSubClassOf("ProcResGroup"))
+ return;
+
if (!ProcResUnits->getValueInit("Super")->isComplete())
return;
@@ -1611,7 +1638,7 @@ void CodeGenSchedRW::dump() const {
}
void CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const {
- dbgs() << "SCHEDCLASS " << Name << '\n'
+ dbgs() << "SCHEDCLASS " << Index << ":" << Name << '\n'
<< " Writes: ";
for (unsigned i = 0, N = Writes.size(); i < N; ++i) {
SchedModels->getSchedWrite(Writes[i]).dump();
@@ -1629,6 +1656,13 @@ void CodeGenSchedClass::dump(const CodeGenSchedModels* SchedModels) const {
}
}
dbgs() << "\n ProcIdx: "; dumpIdxVec(ProcIndices); dbgs() << '\n';
+ if (!Transitions.empty()) {
+ dbgs() << "\n Transitions for Proc ";
+ for (std::vector<CodeGenSchedTransition>::const_iterator
+ TI = Transitions.begin(), TE = Transitions.end(); TI != TE; ++TI) {
+ dumpIdxVec(TI->ProcIndices);
+ }
+ }
}
void PredTransitions::dump() const {
diff --git a/contrib/llvm/utils/TableGen/CodeGenSchedule.h b/contrib/llvm/utils/TableGen/CodeGenSchedule.h
index eed058971b80..e5b9118fb062 100644
--- a/contrib/llvm/utils/TableGen/CodeGenSchedule.h
+++ b/contrib/llvm/utils/TableGen/CodeGenSchedule.h
@@ -16,10 +16,10 @@
#define CODEGEN_SCHEDULE_H
#include "SetTheory.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TableGen/Record.h"
namespace llvm {
@@ -55,10 +55,11 @@ struct CodeGenSchedRW {
IdxVec Sequence;
RecVec Aliases;
- CodeGenSchedRW(): Index(0), TheDef(0), IsAlias(false), HasVariants(false),
- IsVariadic(false), IsSequence(false) {}
- CodeGenSchedRW(unsigned Idx, Record *Def): Index(Idx), TheDef(Def),
- IsAlias(false), IsVariadic(false) {
+ CodeGenSchedRW()
+ : Index(0), TheDef(0), IsRead(false), IsAlias(false),
+ HasVariants(false), IsVariadic(false), IsSequence(false) {}
+ CodeGenSchedRW(unsigned Idx, Record *Def)
+ : Index(Idx), TheDef(Def), IsAlias(false), IsVariadic(false) {
Name = Def->getName();
IsRead = Def->isSubClassOf("SchedRead");
HasVariants = Def->isSubClassOf("SchedVariant");
@@ -72,9 +73,9 @@ struct CodeGenSchedRW {
}
CodeGenSchedRW(unsigned Idx, bool Read, const IdxVec &Seq,
- const std::string &Name):
- Index(Idx), Name(Name), TheDef(0), IsRead(Read), IsAlias(false),
- HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) {
+ const std::string &Name)
+ : Index(Idx), Name(Name), TheDef(0), IsRead(Read), IsAlias(false),
+ HasVariants(false), IsVariadic(false), IsSequence(true), Sequence(Seq) {
assert(Sequence.size() > 1 && "implied sequence needs >1 RWs");
}
@@ -124,6 +125,7 @@ struct CodeGenSchedTransition {
/// itinerary class. Each inherits the processor index from the ItinRW record
/// that mapped the itinerary class to the variant Writes or Reads.
struct CodeGenSchedClass {
+ unsigned Index;
std::string Name;
Record *ItinClassDef;
@@ -140,12 +142,16 @@ struct CodeGenSchedClass {
// off to join another inferred class.
RecVec InstRWs;
- CodeGenSchedClass(): ItinClassDef(0) {}
- CodeGenSchedClass(Record *rec): ItinClassDef(rec) {
- Name = rec->getName();
- ProcIndices.push_back(0);
+ CodeGenSchedClass(): Index(0), ItinClassDef(0) {}
+
+ bool isKeyEqual(Record *IC, const IdxVec &W, const IdxVec &R) {
+ return ItinClassDef == IC && Writes == W && Reads == R;
}
+ // Is this class generated from a variants if existing classes? Instructions
+ // are never mapped directly to inferred scheduling classes.
+ bool isInferred() const { return !ItinClassDef; }
+
#ifndef NDEBUG
void dump(const CodeGenSchedModels *SchedModels) const;
#endif
@@ -188,11 +194,16 @@ struct CodeGenProcModel {
// Per-operand machine model resources associated with this processor.
RecVec ProcResourceDefs;
+ RecVec ProcResGroupDefs;
CodeGenProcModel(unsigned Idx, const std::string &Name, Record *MDef,
Record *IDef) :
Index(Idx), ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {}
+ bool hasItineraries() const {
+ return !ItinsDef->getValueAsListOfDefs("IID").empty();
+ }
+
bool hasInstrSchedModel() const {
return !WriteResDefs.empty() || !ItinRWDefs.empty();
}
@@ -226,24 +237,11 @@ class CodeGenSchedModels {
// List of unique SchedClasses.
std::vector<CodeGenSchedClass> SchedClasses;
- // Map SchedClass name to itinerary index.
- // These are either explicit itinerary classes or classes implied by
- // instruction definitions with SchedReadWrite lists.
- StringMap<unsigned> SchedClassIdxMap;
-
- // SchedClass indices 1 up to and including NumItineraryClasses identify
- // itinerary classes that are explicitly used for this target's instruction
- // definitions. NoItinerary always has index 0 regardless of whether it is
- // explicitly referenced.
- //
- // Any implied SchedClass has an index greater than NumItineraryClasses.
- unsigned NumItineraryClasses;
-
// Any inferred SchedClass has an index greater than NumInstrSchedClassses.
unsigned NumInstrSchedClasses;
- // Map Instruction to SchedClass index. Only for Instructions mentioned in
- // InstRW records.
+ // Map each instruction to its unique SchedClass index considering the
+ // combination of it's itinerary class, SchedRW list, and InstRW records.
typedef DenseMap<Record*, unsigned> InstClassMapTy;
InstClassMapTy InstrClassMap;
@@ -279,6 +277,9 @@ public:
ProcIter procModelBegin() const { return ProcModels.begin(); }
ProcIter procModelEnd() const { return ProcModels.end(); }
+ // Return true if any processors have itineraries.
+ bool hasItineraries() const;
+
// Get a SchedWrite from its index.
const CodeGenSchedRW &getSchedWrite(unsigned Idx) const {
assert(Idx < SchedWrites.size() && "bad SchedWrite index");
@@ -310,16 +311,6 @@ public:
// Return true if the given write record is referenced by a ReadAdvance.
bool hasReadOfWrite(Record *WriteDef) const;
- // Check if any instructions are assigned to an explicit itinerary class other
- // than NoItinerary.
- bool hasItineraryClasses() const { return NumItineraryClasses > 0; }
-
- // Return the number of itinerary classes in use by this target's instruction
- // descriptions, not including "NoItinerary".
- unsigned numItineraryClasses() const {
- return NumItineraryClasses;
- }
-
// Get a SchedClass from its index.
CodeGenSchedClass &getSchedClass(unsigned Idx) {
assert(Idx < SchedClasses.size() && "bad SchedClass index");
@@ -335,28 +326,26 @@ public:
// for NoItinerary.
unsigned getSchedClassIdx(const CodeGenInstruction &Inst) const;
- unsigned getSchedClassIdx(const RecVec &RWDefs) const;
-
- unsigned getSchedClassIdxForItin(const Record *ItinDef) {
- return SchedClassIdxMap[ItinDef->getName()];
- }
-
typedef std::vector<CodeGenSchedClass>::const_iterator SchedClassIter;
SchedClassIter schedClassBegin() const { return SchedClasses.begin(); }
SchedClassIter schedClassEnd() const { return SchedClasses.end(); }
+ unsigned numInstrSchedClasses() const { return NumInstrSchedClasses; }
+
void findRWs(const RecVec &RWDefs, IdxVec &Writes, IdxVec &Reads) const;
void findRWs(const RecVec &RWDefs, IdxVec &RWs, bool IsRead) const;
void expandRWSequence(unsigned RWIdx, IdxVec &RWSeq, bool IsRead) const;
void expandRWSeqForProc(unsigned RWIdx, IdxVec &RWSeq, bool IsRead,
const CodeGenProcModel &ProcModel) const;
- unsigned addSchedClass(const IdxVec &OperWrites, const IdxVec &OperReads,
- const IdxVec &ProcIndices);
+ unsigned addSchedClass(Record *ItinDef, const IdxVec &OperWrites,
+ const IdxVec &OperReads, const IdxVec &ProcIndices);
unsigned findOrInsertRW(ArrayRef<unsigned> Seq, bool IsRead);
- unsigned findSchedClassIdx(const IdxVec &Writes, const IdxVec &Reads) const;
+ unsigned findSchedClassIdx(Record *ItinClassDef,
+ const IdxVec &Writes,
+ const IdxVec &Reads) const;
Record *findProcResUnits(Record *ProcResKind,
const CodeGenProcModel &PM) const;
@@ -374,7 +363,8 @@ private:
void collectSchedClasses();
- std::string createSchedClassName(const IdxVec &OperWrites,
+ std::string createSchedClassName(Record *ItinClassDef,
+ const IdxVec &OperWrites,
const IdxVec &OperReads);
std::string createSchedClassName(const RecVec &InstDefs);
void createInstRWClass(Record *InstRWDef);
diff --git a/contrib/llvm/utils/TableGen/CodeGenTarget.cpp b/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
index c9992eb39228..8b292b957288 100644
--- a/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -17,11 +17,11 @@
#include "CodeGenTarget.h"
#include "CodeGenIntrinsics.h"
#include "CodeGenSchedule.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <algorithm>
using namespace llvm;
@@ -73,16 +73,20 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v4i1: return "MVT::v4i1";
case MVT::v8i1: return "MVT::v8i1";
case MVT::v16i1: return "MVT::v16i1";
+ case MVT::v32i1: return "MVT::v32i1";
+ case MVT::v64i1: return "MVT::v64i1";
case MVT::v2i8: return "MVT::v2i8";
case MVT::v4i8: return "MVT::v4i8";
case MVT::v8i8: return "MVT::v8i8";
case MVT::v16i8: return "MVT::v16i8";
case MVT::v32i8: return "MVT::v32i8";
+ case MVT::v64i8: return "MVT::v64i8";
case MVT::v1i16: return "MVT::v1i16";
case MVT::v2i16: return "MVT::v2i16";
case MVT::v4i16: return "MVT::v4i16";
case MVT::v8i16: return "MVT::v8i16";
case MVT::v16i16: return "MVT::v16i16";
+ case MVT::v32i16: return "MVT::v32i16";
case MVT::v1i32: return "MVT::v1i32";
case MVT::v2i32: return "MVT::v2i32";
case MVT::v4i32: return "MVT::v4i32";
@@ -97,8 +101,10 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
case MVT::v2f32: return "MVT::v2f32";
case MVT::v4f32: return "MVT::v4f32";
case MVT::v8f32: return "MVT::v8f32";
+ case MVT::v16f32: return "MVT::v16f32";
case MVT::v2f64: return "MVT::v2f64";
case MVT::v4f64: return "MVT::v4f64";
+ case MVT::v8f64: return "MVT::v8f64";
case MVT::Metadata: return "MVT::Metadata";
case MVT::iPTR: return "MVT::iPTR";
case MVT::iPTRAny: return "MVT::iPTRAny";
@@ -223,7 +229,7 @@ getRegisterVTs(Record *R) const {
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
const CodeGenRegisterClass &RC = *RCs[i];
if (RC.contains(Reg)) {
- const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
+ ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
Result.insert(Result.end(), InVTs.begin(), InVTs.end());
}
}
diff --git a/contrib/llvm/utils/TableGen/CodeGenTarget.h b/contrib/llvm/utils/TableGen/CodeGenTarget.h
index ddeecee36fdf..627144302932 100644
--- a/contrib/llvm/utils/TableGen/CodeGenTarget.h
+++ b/contrib/llvm/utils/TableGen/CodeGenTarget.h
@@ -17,10 +17,10 @@
#ifndef CODEGEN_TARGET_H
#define CODEGEN_TARGET_H
-#include "CodeGenRegisters.h"
#include "CodeGenInstruction.h"
-#include "llvm/TableGen/Record.h"
+#include "CodeGenRegisters.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Record.h"
#include <algorithm>
namespace llvm {
@@ -68,7 +68,7 @@ class CodeGenTarget {
mutable DenseMap<const Record*, CodeGenInstruction*> Instructions;
mutable CodeGenRegBank *RegBank;
mutable std::vector<Record*> RegAltNameIndices;
- mutable std::vector<MVT::SimpleValueType> LegalValueTypes;
+ mutable SmallVector<MVT::SimpleValueType, 8> LegalValueTypes;
void ReadRegAltNameIndices() const;
void ReadInstructions() const;
void ReadLegalValueTypes() const;
@@ -129,7 +129,7 @@ public:
/// specified physical register.
std::vector<MVT::SimpleValueType> getRegisterVTs(Record *R) const;
- const std::vector<MVT::SimpleValueType> &getLegalValueTypes() const {
+ ArrayRef<MVT::SimpleValueType> getLegalValueTypes() const {
if (LegalValueTypes.empty()) ReadLegalValueTypes();
return LegalValueTypes;
}
@@ -137,7 +137,7 @@ public:
/// isLegalValueType - Return true if the specified value type is natively
/// supported by the target (i.e. there are registers that directly hold it).
bool isLegalValueType(MVT::SimpleValueType VT) const {
- const std::vector<MVT::SimpleValueType> &LegalVTs = getLegalValueTypes();
+ ArrayRef<MVT::SimpleValueType> LegalVTs = getLegalValueTypes();
for (unsigned i = 0, e = LegalVTs.size(); i != e; ++i)
if (LegalVTs[i] == VT) return true;
return false;
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcher.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcher.cpp
index bd77907a9bd9..d173cf006a46 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcher.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcher.cpp
@@ -10,9 +10,9 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
void Matcher::anchor() { }
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcher.h b/contrib/llvm/utils/TableGen/DAGISelMatcher.h
index 7c6ce3babcd8..f978188aae59 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcher.h
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcher.h
@@ -10,10 +10,10 @@
#ifndef TBLGEN_DAGISELMATCHER_H
#define TBLGEN_DAGISELMATCHER_H
-#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/Casting.h"
namespace llvm {
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 713f1743c143..93f84ce6e817 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -13,12 +13,12 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
-#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
enum {
@@ -132,7 +132,7 @@ static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) {
return NumBytes+1;
}
-/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
+/// EmitMatcher - Emit bytes for the specified matcher and return
/// the number of bytes emitted.
unsigned MatcherTableEmitter::
EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index 573f55875ec6..ed41631456b0 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -10,11 +10,11 @@
#include "DAGISelMatcher.h"
#include "CodeGenDAGPatterns.h"
#include "CodeGenRegisters.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include <utility>
using namespace llvm;
@@ -211,6 +211,12 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
return AddMatcher(new CheckIntegerMatcher(II->getValue()));
}
+ // An UnsetInit represents a named node without any constraints.
+ if (N->getLeafValue() == UnsetInit::get()) {
+ assert(N->hasName() && "Unnamed ? leaf");
+ return;
+ }
+
DefInit *DI = dyn_cast<DefInit>(N->getLeafValue());
if (DI == 0) {
errs() << "Unknown leaf kind: " << *N << "\n";
@@ -218,6 +224,17 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
}
Record *LeafRec = DI->getDef();
+
+ // A ValueType leaf node can represent a register when named, or itself when
+ // unnamed.
+ if (LeafRec->isSubClassOf("ValueType")) {
+ // A named ValueType leaf always matches: (add i32:$a, i32:$b).
+ if (N->hasName())
+ return;
+ // An unnamed ValueType as in (sext_inreg GPR:$foo, i8).
+ return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
+ }
+
if (// Handle register references. Nothing to do here, they always match.
LeafRec->isSubClassOf("RegisterClass") ||
LeafRec->isSubClassOf("RegisterOperand") ||
@@ -236,9 +253,6 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
return;
}
- if (LeafRec->isSubClassOf("ValueType"))
- return AddMatcher(new CheckValueTypeMatcher(LeafRec->getName()));
-
if (LeafRec->isSubClassOf("CondCode"))
return AddMatcher(new CheckCondCodeMatcher(LeafRec->getName()));
@@ -734,20 +748,33 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
continue;
}
- const TreePatternNode *Child = N->getChild(ChildNo);
-
// Otherwise this is a normal operand or a predicate operand without
// 'execute always'; emit it.
- unsigned BeforeAddingNumOps = InstOps.size();
- EmitResultOperand(Child, InstOps);
- assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
- // If the operand is an instruction and it produced multiple results, just
- // take the first one.
- if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
- InstOps.resize(BeforeAddingNumOps+1);
+ // For operands with multiple sub-operands we may need to emit
+ // multiple child patterns to cover them all. However, ComplexPattern
+ // children may themselves emit multiple MI operands.
+ unsigned NumSubOps = 1;
+ if (OperandNode->isSubClassOf("Operand")) {
+ DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
+ if (unsigned NumArgs = MIOpInfo->getNumArgs())
+ NumSubOps = NumArgs;
+ }
+
+ unsigned FinalNumOps = InstOps.size() + NumSubOps;
+ while (InstOps.size() < FinalNumOps) {
+ const TreePatternNode *Child = N->getChild(ChildNo);
+ unsigned BeforeAddingNumOps = InstOps.size();
+ EmitResultOperand(Child, InstOps);
+ assert(InstOps.size() > BeforeAddingNumOps && "Didn't add any operands");
- ++ChildNo;
+ // If the operand is an instruction and it produced multiple results, just
+ // take the first one.
+ if (!Child->isLeaf() && Child->getOperator()->isSubClassOf("Instruction"))
+ InstOps.resize(BeforeAddingNumOps+1);
+
+ ++ChildNo;
+ }
}
// If this node has input glue or explicitly specified input physregs, we
diff --git a/contrib/llvm/utils/TableGen/DFAPacketizerEmitter.cpp b/contrib/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
index 0ad25a5428db..2549c47c3318 100644
--- a/contrib/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
@@ -279,6 +279,7 @@ DFAPacketizerEmitter::DFAPacketizerEmitter(RecordKeeper &R):
//
//
void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
+ static const std::string SentinelEntry = "{-1, -1}";
DFA::StateSet::iterator SI = states.begin();
// This table provides a map to the beginning of the transitions for State s
// in DFAStateInputTable.
@@ -305,12 +306,17 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
// If there are no valid transitions from this stage, we need a sentinel
// transition.
if (ValidTransitions == StateEntry[i]) {
- OS << "{-1, -1},";
+ OS << SentinelEntry << ",";
++ValidTransitions;
}
OS << "\n";
}
+
+ // Print out a sentinel entry at the end of the StateInputTable. This is
+ // needed to iterate over StateInputTable in DFAPacketizer::ReadTable()
+ OS << SentinelEntry << "\n";
+
OS << "};\n\n";
OS << "const unsigned int " << TargetName << "DFAStateEntryTable[] = {\n";
@@ -319,6 +325,9 @@ void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName) {
for (unsigned i = 0; i < states.size(); ++i)
OS << StateEntry[i] << ", ";
+ // Print out the index to the sentinel entry in StateInputTable
+ OS << ValidTransitions << ", ";
+
OS << "\n};\n";
OS << "} // namespace\n";
diff --git a/contrib/llvm/utils/TableGen/DisassemblerEmitter.cpp b/contrib/llvm/utils/TableGen/DisassemblerEmitter.cpp
index 2d11d2480de4..5a2a41b456d7 100644
--- a/contrib/llvm/utils/TableGen/DisassemblerEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/DisassemblerEmitter.cpp
@@ -127,8 +127,9 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
// ARM and Thumb have a CHECK() macro to deal with DecodeStatuses.
if (Target.getName() == "ARM" ||
- Target.getName() == "Thumb") {
- EmitFixedLenDecoder(Records, OS, "ARM",
+ Target.getName() == "Thumb" ||
+ Target.getName() == "AArch64") {
+ EmitFixedLenDecoder(Records, OS, Target.getName() == "AArch64" ? "AArch64" : "ARM",
"if (!Check(S, ", ")) return MCDisassembler::Fail;",
"S", "MCDisassembler::Fail",
" MCDisassembler::DecodeStatus S = "
diff --git a/contrib/llvm/utils/TableGen/EDEmitter.cpp b/contrib/llvm/utils/TableGen/EDEmitter.cpp
deleted file mode 100644
index ea2545050bc0..000000000000
--- a/contrib/llvm/utils/TableGen/EDEmitter.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This tablegen backend is responsible for emitting a description of each
-// instruction in a format that the enhanced disassembler can use to tokenize
-// and parse instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AsmWriterInst.h"
-#include "CodeGenTarget.h"
-#include "llvm/MC/EDInstInfo.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
-#include "llvm/TableGen/TableGenBackend.h"
-#include <string>
-#include <vector>
-
-using namespace llvm;
-
-// TODO: There's a suspiciously large amount of "table" data in this
-// backend which should probably be in the TableGen file itself.
-
-///////////////////////////////////////////////////////////
-// Support classes for emitting nested C data structures //
-///////////////////////////////////////////////////////////
-
-// TODO: These classes are probably generally useful to other backends;
-// add them to TableGen's "helper" API's.
-
-namespace {
-class EnumEmitter {
-private:
- std::string Name;
- std::vector<std::string> Entries;
-public:
- EnumEmitter(const char *N) : Name(N) {
- }
- int addEntry(const char *e) {
- Entries.push_back(std::string(e));
- return Entries.size() - 1;
- }
- void emit(raw_ostream &o, unsigned int &i) {
- o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
- i += 2;
-
- unsigned int index = 0;
- unsigned int numEntries = Entries.size();
- for (index = 0; index < numEntries; ++index) {
- o.indent(i) << Entries[index];
- if (index < (numEntries - 1))
- o << ",";
- o << "\n";
- }
-
- i -= 2;
- o.indent(i) << "};" << "\n";
- }
-
- void emitAsFlags(raw_ostream &o, unsigned int &i) {
- o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
- i += 2;
-
- unsigned int index = 0;
- unsigned int numEntries = Entries.size();
- unsigned int flag = 1;
- for (index = 0; index < numEntries; ++index) {
- o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
- if (index < (numEntries - 1))
- o << ",";
- o << "\n";
- flag <<= 1;
- }
-
- i -= 2;
- o.indent(i) << "};" << "\n";
- }
-};
-} // End anonymous namespace
-
-namespace {
-class ConstantEmitter {
-public:
- virtual ~ConstantEmitter() { }
- virtual void emit(raw_ostream &o, unsigned int &i) = 0;
-};
-} // End anonymous namespace
-
-namespace {
-class LiteralConstantEmitter : public ConstantEmitter {
-private:
- bool IsNumber;
- union {
- int Number;
- const char* String;
- };
-public:
- LiteralConstantEmitter(int number = 0) :
- IsNumber(true),
- Number(number) {
- }
- void set(const char *string) {
- IsNumber = false;
- Number = 0;
- String = string;
- }
- bool is(const char *string) {
- return !strcmp(String, string);
- }
- void emit(raw_ostream &o, unsigned int &i) {
- if (IsNumber)
- o << Number;
- else
- o << String;
- }
-};
-} // End anonymous namespace
-
-namespace {
-class CompoundConstantEmitter : public ConstantEmitter {
-private:
- unsigned int Padding;
- std::vector<ConstantEmitter *> Entries;
-public:
- CompoundConstantEmitter(unsigned int padding = 0) : Padding(padding) {
- }
- CompoundConstantEmitter &addEntry(ConstantEmitter *e) {
- Entries.push_back(e);
-
- return *this;
- }
- ~CompoundConstantEmitter() {
- while (Entries.size()) {
- ConstantEmitter *entry = Entries.back();
- Entries.pop_back();
- delete entry;
- }
- }
- void emit(raw_ostream &o, unsigned int &i) {
- o << "{" << "\n";
- i += 2;
-
- unsigned int index;
- unsigned int numEntries = Entries.size();
-
- unsigned int numToPrint;
-
- if (Padding) {
- if (numEntries > Padding) {
- fprintf(stderr, "%u entries but %u padding\n", numEntries, Padding);
- llvm_unreachable("More entries than padding");
- }
- numToPrint = Padding;
- } else {
- numToPrint = numEntries;
- }
-
- for (index = 0; index < numToPrint; ++index) {
- o.indent(i);
- if (index < numEntries)
- Entries[index]->emit(o, i);
- else
- o << "-1";
-
- if (index < (numToPrint - 1))
- o << ",";
- o << "\n";
- }
-
- i -= 2;
- o.indent(i) << "}";
- }
-};
-} // End anonymous namespace
-
-namespace {
-class FlagsConstantEmitter : public ConstantEmitter {
-private:
- std::vector<std::string> Flags;
-public:
- FlagsConstantEmitter() {
- }
- FlagsConstantEmitter &addEntry(const char *f) {
- Flags.push_back(std::string(f));
- return *this;
- }
- void emit(raw_ostream &o, unsigned int &i) {
- unsigned int index;
- unsigned int numFlags = Flags.size();
- if (numFlags == 0)
- o << "0";
-
- for (index = 0; index < numFlags; ++index) {
- o << Flags[index].c_str();
- if (index < (numFlags - 1))
- o << " | ";
- }
- }
-};
-} // End anonymous namespace
-
-/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
-/// AsmWriterInst for the desired assembly syntax, giving an ordered list of
-/// operands in the order they appear in the printed instruction. Then, for
-/// each entry in that list, determines the index of the same operand in the
-/// CodeGenInstruction, and emits the resulting mapping into an array, filling
-/// in unused slots with -1.
-///
-/// @arg operandOrder - The array that will be populated with the operand
-/// mapping. Each entry will contain -1 (invalid index
-/// into the operands present in the AsmString) or a number
-/// representing an index in the operand descriptor array.
-/// @arg inst - The instruction to use when looking up the operands
-/// @arg syntax - The syntax to use, according to LLVM's enumeration
-static void populateOperandOrder(CompoundConstantEmitter *operandOrder,
- const CodeGenInstruction &inst,
- unsigned syntax) {
- unsigned int numArgs = 0;
-
- AsmWriterInst awInst(inst, syntax, -1, -1);
-
- std::vector<AsmWriterOperand>::iterator operandIterator;
-
- for (operandIterator = awInst.Operands.begin();
- operandIterator != awInst.Operands.end();
- ++operandIterator) {
- if (operandIterator->OperandType ==
- AsmWriterOperand::isMachineInstrOperand) {
- operandOrder->addEntry(
- new LiteralConstantEmitter(operandIterator->CGIOpNo));
- numArgs++;
- }
- }
-}
-
-/////////////////////////////////////////////////////
-// Support functions for handling X86 instructions //
-/////////////////////////////////////////////////////
-
-#define SET(flag) { type->set(flag); return 0; }
-
-#define REG(str) if (name == str) SET("kOperandTypeRegister");
-#define MEM(str) if (name == str) SET("kOperandTypeX86Memory");
-#define LEA(str) if (name == str) SET("kOperandTypeX86EffectiveAddress");
-#define IMM(str) if (name == str) SET("kOperandTypeImmediate");
-#define PCR(str) if (name == str) SET("kOperandTypeX86PCRelative");
-
-/// X86TypeFromOpName - Processes the name of a single X86 operand (which is
-/// actually its type) and translates it into an operand type
-///
-/// @arg flags - The type object to set
-/// @arg name - The name of the operand
-static int X86TypeFromOpName(LiteralConstantEmitter *type,
- const std::string &name) {
- REG("GR8");
- REG("GR8_NOREX");
- REG("GR16");
- REG("GR16_NOAX");
- REG("GR32");
- REG("GR32_NOAX");
- REG("GR32_NOREX");
- REG("GR32_TC");
- REG("FR32");
- REG("RFP32");
- REG("GR64");
- REG("GR64_NOAX");
- REG("GR64_TC");
- REG("FR64");
- REG("VR64");
- REG("RFP64");
- REG("RFP80");
- REG("VR128");
- REG("VR256");
- REG("RST");
- REG("SEGMENT_REG");
- REG("DEBUG_REG");
- REG("CONTROL_REG");
-
- IMM("i8imm");
- IMM("i16imm");
- IMM("i16i8imm");
- IMM("i32imm");
- IMM("i32i8imm");
- IMM("u32u8imm");
- IMM("i64imm");
- IMM("i64i8imm");
- IMM("i64i32imm");
- IMM("SSECC");
- IMM("AVXCC");
-
- // all R, I, R, I, R
- MEM("i8mem");
- MEM("i8mem_NOREX");
- MEM("i16mem");
- MEM("i32mem");
- MEM("i32mem_TC");
- MEM("f32mem");
- MEM("ssmem");
- MEM("opaque32mem");
- MEM("opaque48mem");
- MEM("i64mem");
- MEM("i64mem_TC");
- MEM("f64mem");
- MEM("sdmem");
- MEM("f80mem");
- MEM("opaque80mem");
- MEM("i128mem");
- MEM("i256mem");
- MEM("f128mem");
- MEM("f256mem");
- MEM("opaque512mem");
- // Gather
- MEM("vx32mem")
- MEM("vy32mem")
- MEM("vx64mem")
- MEM("vy64mem")
-
- // all R, I, R, I
- LEA("lea32mem");
- LEA("lea64_32mem");
- LEA("lea64mem");
-
- // all I
- PCR("i16imm_pcrel");
- PCR("i32imm_pcrel");
- PCR("i64i32imm_pcrel");
- PCR("brtarget8");
- PCR("offset8");
- PCR("offset16");
- PCR("offset32");
- PCR("offset64");
- PCR("brtarget");
- PCR("uncondbrtarget");
- PCR("bltarget");
-
- // all I, ARM mode only, conditional/unconditional
- PCR("br_target");
- PCR("bl_target");
- return 1;
-}
-
-#undef REG
-#undef MEM
-#undef LEA
-#undef IMM
-#undef PCR
-
-#undef SET
-
-/// X86PopulateOperands - Handles all the operands in an X86 instruction, adding
-/// the appropriate flags to their descriptors
-///
-/// \param operandTypes A reference the array of operand type objects
-/// \param inst The instruction to use as a source of information
-static void X86PopulateOperands(
- LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
- const CodeGenInstruction &inst) {
- if (!inst.TheDef->isSubClassOf("X86Inst"))
- return;
-
- unsigned int index;
- unsigned int numOperands = inst.Operands.size();
-
- for (index = 0; index < numOperands; ++index) {
- const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
- Record &rec = *operandInfo.Rec;
-
- if (X86TypeFromOpName(operandTypes[index], rec.getName()) &&
- !rec.isSubClassOf("PointerLikeRegClass")) {
- errs() << "Operand type: " << rec.getName().c_str() << "\n";
- errs() << "Operand name: " << operandInfo.Name.c_str() << "\n";
- errs() << "Instruction name: " << inst.TheDef->getName().c_str() << "\n";
- llvm_unreachable("Unhandled type");
- }
- }
-}
-
-/// decorate1 - Decorates a named operand with a new flag
-///
-/// \param operandFlags The array of operand flag objects, which don't have
-/// names
-/// \param inst The CodeGenInstruction, which provides a way to
-// translate between names and operand indices
-/// \param opName The name of the operand
-/// \param opFlag The name of the flag to add
-static inline void decorate1(
- FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
- const CodeGenInstruction &inst,
- const char *opName,
- const char *opFlag) {
- unsigned opIndex;
-
- opIndex = inst.Operands.getOperandNamed(std::string(opName));
-
- operandFlags[opIndex]->addEntry(opFlag);
-}
-
-#define DECORATE1(opName, opFlag) decorate1(operandFlags, inst, opName, opFlag)
-
-#define MOV(source, target) { \
- instType.set("kInstructionTypeMove"); \
- DECORATE1(source, "kOperandFlagSource"); \
- DECORATE1(target, "kOperandFlagTarget"); \
-}
-
-#define BRANCH(target) { \
- instType.set("kInstructionTypeBranch"); \
- DECORATE1(target, "kOperandFlagTarget"); \
-}
-
-#define PUSH(source) { \
- instType.set("kInstructionTypePush"); \
- DECORATE1(source, "kOperandFlagSource"); \
-}
-
-#define POP(target) { \
- instType.set("kInstructionTypePop"); \
- DECORATE1(target, "kOperandFlagTarget"); \
-}
-
-#define CALL(target) { \
- instType.set("kInstructionTypeCall"); \
- DECORATE1(target, "kOperandFlagTarget"); \
-}
-
-#define RETURN() { \
- instType.set("kInstructionTypeReturn"); \
-}
-
-/// X86ExtractSemantics - Performs various checks on the name of an X86
-/// instruction to determine what sort of an instruction it is and then adds
-/// the appropriate flags to the instruction and its operands
-///
-/// \param instType A reference to the type for the instruction as a whole
-/// \param operandFlags A reference to the array of operand flag object pointers
-/// \param inst A reference to the original instruction
-static void X86ExtractSemantics(
- LiteralConstantEmitter &instType,
- FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
- const CodeGenInstruction &inst) {
- const std::string &name = inst.TheDef->getName();
-
- if (name.find("MOV") != name.npos) {
- if (name.find("MOV_V") != name.npos) {
- // ignore (this is a pseudoinstruction)
- } else if (name.find("MASK") != name.npos) {
- // ignore (this is a masking move)
- } else if (name.find("r0") != name.npos) {
- // ignore (this is a pseudoinstruction)
- } else if (name.find("PS") != name.npos ||
- name.find("PD") != name.npos) {
- // ignore (this is a shuffling move)
- } else if (name.find("MOVS") != name.npos) {
- // ignore (this is a string move)
- } else if (name.find("_F") != name.npos) {
- // TODO handle _F moves to ST(0)
- } else if (name.find("a") != name.npos) {
- // TODO handle moves to/from %ax
- } else if (name.find("CMOV") != name.npos) {
- MOV("src2", "dst");
- } else if (name.find("PC") != name.npos) {
- MOV("label", "reg")
- } else {
- MOV("src", "dst");
- }
- }
-
- if (name.find("JMP") != name.npos ||
- name.find("J") == 0) {
- if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
- BRANCH("off");
- } else {
- BRANCH("dst");
- }
- }
-
- if (name.find("PUSH") != name.npos) {
- if (name.find("CS") != name.npos ||
- name.find("DS") != name.npos ||
- name.find("ES") != name.npos ||
- name.find("FS") != name.npos ||
- name.find("GS") != name.npos ||
- name.find("SS") != name.npos) {
- instType.set("kInstructionTypePush");
- // TODO add support for fixed operands
- } else if (name.find("F") != name.npos) {
- // ignore (this pushes onto the FP stack)
- } else if (name.find("A") != name.npos) {
- // ignore (pushes all GP registoers onto the stack)
- } else if (name[name.length() - 1] == 'm') {
- PUSH("src");
- } else if (name.find("i") != name.npos) {
- PUSH("imm");
- } else {
- PUSH("reg");
- }
- }
-
- if (name.find("POP") != name.npos) {
- if (name.find("POPCNT") != name.npos) {
- // ignore (not a real pop)
- } else if (name.find("CS") != name.npos ||
- name.find("DS") != name.npos ||
- name.find("ES") != name.npos ||
- name.find("FS") != name.npos ||
- name.find("GS") != name.npos ||
- name.find("SS") != name.npos) {
- instType.set("kInstructionTypePop");
- // TODO add support for fixed operands
- } else if (name.find("F") != name.npos) {
- // ignore (this pops from the FP stack)
- } else if (name.find("A") != name.npos) {
- // ignore (pushes all GP registoers onto the stack)
- } else if (name[name.length() - 1] == 'm') {
- POP("dst");
- } else {
- POP("reg");
- }
- }
-
- if (name.find("CALL") != name.npos) {
- if (name.find("ADJ") != name.npos) {
- // ignore (not a call)
- } else if (name.find("SYSCALL") != name.npos) {
- // ignore (doesn't go anywhere we know about)
- } else if (name.find("VMCALL") != name.npos) {
- // ignore (rather different semantics than a regular call)
- } else if (name.find("VMMCALL") != name.npos) {
- // ignore (rather different semantics than a regular call)
- } else if (name.find("FAR") != name.npos && name.find("i") != name.npos) {
- CALL("off");
- } else {
- CALL("dst");
- }
- }
-
- if (name.find("RET") != name.npos) {
- RETURN();
- }
-}
-
-#undef MOV
-#undef BRANCH
-#undef PUSH
-#undef POP
-#undef CALL
-#undef RETURN
-
-/////////////////////////////////////////////////////
-// Support functions for handling ARM instructions //
-/////////////////////////////////////////////////////
-
-#define SET(flag) { type->set(flag); return 0; }
-
-#define REG(str) if (name == str) SET("kOperandTypeRegister");
-#define IMM(str) if (name == str) SET("kOperandTypeImmediate");
-
-#define MISC(str, type) if (name == str) SET(type);
-
-/// ARMFlagFromOpName - Processes the name of a single ARM operand (which is
-/// actually its type) and translates it into an operand type
-///
-/// \param type The type object to set
-/// \param name The name of the operand
-static int ARMFlagFromOpName(LiteralConstantEmitter *type,
- const std::string &name) {
- REG("GPR");
- REG("rGPR");
- REG("GPRnopc");
- REG("GPRsp");
- REG("tcGPR");
- REG("cc_out");
- REG("s_cc_out");
- REG("tGPR");
- REG("DPR");
- REG("DPR_VFP2");
- REG("DPR_8");
- REG("DPair");
- REG("SPR");
- REG("QPR");
- REG("QQPR");
- REG("QQQQPR");
- REG("VecListOneD");
- REG("VecListDPair");
- REG("VecListDPairSpaced");
- REG("VecListThreeD");
- REG("VecListFourD");
- REG("VecListOneDAllLanes");
- REG("VecListDPairAllLanes");
- REG("VecListDPairSpacedAllLanes");
-
- IMM("i32imm");
- IMM("fbits16");
- IMM("fbits32");
- IMM("i32imm_hilo16");
- IMM("bf_inv_mask_imm");
- IMM("lsb_pos_imm");
- IMM("width_imm");
- IMM("jtblock_operand");
- IMM("nohash_imm");
- IMM("p_imm");
- IMM("pf_imm");
- IMM("c_imm");
- IMM("coproc_option_imm");
- IMM("imod_op");
- IMM("iflags_op");
- IMM("cpinst_operand");
- IMM("setend_op");
- IMM("cps_opt");
- IMM("vfp_f64imm");
- IMM("vfp_f32imm");
- IMM("memb_opt");
- IMM("msr_mask");
- IMM("neg_zero");
- IMM("imm0_31");
- IMM("imm0_31_m1");
- IMM("imm1_16");
- IMM("imm1_32");
- IMM("nModImm");
- IMM("nImmSplatI8");
- IMM("nImmSplatI16");
- IMM("nImmSplatI32");
- IMM("nImmSplatI64");
- IMM("nImmVMOVI32");
- IMM("nImmVMOVF32");
- IMM("imm8");
- IMM("imm16");
- IMM("imm32");
- IMM("imm1_7");
- IMM("imm1_15");
- IMM("imm1_31");
- IMM("imm0_1");
- IMM("imm0_3");
- IMM("imm0_7");
- IMM("imm0_15");
- IMM("imm0_255");
- IMM("imm0_4095");
- IMM("imm0_65535");
- IMM("imm0_65535_expr");
- IMM("imm24b");
- IMM("pkh_lsl_amt");
- IMM("pkh_asr_amt");
- IMM("jt2block_operand");
- IMM("t_imm0_1020s4");
- IMM("t_imm0_508s4");
- IMM("pclabel");
- IMM("adrlabel");
- IMM("t_adrlabel");
- IMM("t2adrlabel");
- IMM("shift_imm");
- IMM("t2_shift_imm");
- IMM("neon_vcvt_imm32");
- IMM("shr_imm8");
- IMM("shr_imm16");
- IMM("shr_imm32");
- IMM("shr_imm64");
- IMM("t2ldrlabel");
- IMM("postidx_imm8");
- IMM("postidx_imm8s4");
- IMM("imm_sr");
- IMM("imm1_31");
- IMM("VectorIndex8");
- IMM("VectorIndex16");
- IMM("VectorIndex32");
-
- MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("t_brtarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("t_bcctarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("t_cbtarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("bltarget", "kOperandTypeARMBranchTarget"); // ?
-
- MISC("br_target", "kOperandTypeARMBranchTarget"); // ?
- MISC("bl_target", "kOperandTypeARMBranchTarget"); // ?
- MISC("blx_target", "kOperandTypeARMBranchTarget"); // ?
-
- MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ?
- MISC("so_reg_imm", "kOperandTypeARMSoRegReg"); // R, R, I
- MISC("so_reg_reg", "kOperandTypeARMSoRegImm"); // R, R, I
- MISC("shift_so_reg_reg", "kOperandTypeARMSoRegReg"); // R, R, I
- MISC("shift_so_reg_imm", "kOperandTypeARMSoRegImm"); // R, R, I
- MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I
- MISC("so_imm", "kOperandTypeARMSoImm"); // I
- MISC("rot_imm", "kOperandTypeARMRotImm"); // I
- MISC("t2_so_imm", "kOperandTypeThumb2SoImm"); // I
- MISC("so_imm2part", "kOperandTypeARMSoImm2Part"); // I
- MISC("pred", "kOperandTypeARMPredicate"); // I, R
- MISC("it_pred", "kOperandTypeARMPredicate"); // I
- MISC("addrmode_imm12", "kOperandTypeAddrModeImm12"); // R, I
- MISC("ldst_so_reg", "kOperandTypeLdStSOReg"); // R, R, I
- MISC("postidx_reg", "kOperandTypeARMAddrMode3Offset"); // R, I
- MISC("addrmode2", "kOperandTypeARMAddrMode2"); // R, R, I
- MISC("am2offset_reg", "kOperandTypeARMAddrMode2Offset"); // R, I
- MISC("am2offset_imm", "kOperandTypeARMAddrMode2Offset"); // R, I
- MISC("addrmode3", "kOperandTypeARMAddrMode3"); // R, R, I
- MISC("am3offset", "kOperandTypeARMAddrMode3Offset"); // R, I
- MISC("ldstm_mode", "kOperandTypeARMLdStmMode"); // I
- MISC("addrmode5", "kOperandTypeARMAddrMode5"); // R, I
- MISC("addrmode6", "kOperandTypeARMAddrMode6"); // R, R, I, I
- MISC("am6offset", "kOperandTypeARMAddrMode6Offset"); // R, I, I
- MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I
- MISC("addrmode6oneL32", "kOperandTypeARMAddrMode6"); // R, R, I, I
- MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I
- MISC("addr_offset_none", "kOperandTypeARMAddrMode7"); // R
- MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ...
- MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList"); // I, R, ...
- MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ...
- MISC("it_mask", "kOperandTypeThumbITMask"); // I
- MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R
- MISC("t2addrmode_posimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
- MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
- MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
- MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
- MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12"); // R, I
- MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg"); // R, R, I
- MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I
- MISC("t2addrmode_imm0_1020s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I
- MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset");
- // R, I
- MISC("tb_addrmode", "kOperandTypeARMTBAddrMode"); // I
- MISC("t_addrmode_rrs1", "kOperandTypeThumbAddrModeRegS1"); // R, R
- MISC("t_addrmode_rrs2", "kOperandTypeThumbAddrModeRegS2"); // R, R
- MISC("t_addrmode_rrs4", "kOperandTypeThumbAddrModeRegS4"); // R, R
- MISC("t_addrmode_is1", "kOperandTypeThumbAddrModeImmS1"); // R, I
- MISC("t_addrmode_is2", "kOperandTypeThumbAddrModeImmS2"); // R, I
- MISC("t_addrmode_is4", "kOperandTypeThumbAddrModeImmS4"); // R, I
- MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R
- MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I
- MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I
- MISC("addrmode_tbb", "kOperandTypeThumbAddrModeRR"); // R, R
- MISC("addrmode_tbh", "kOperandTypeThumbAddrModeRR"); // R, R
-
- return 1;
-}
-
-#undef REG
-#undef MEM
-#undef MISC
-
-#undef SET
-
-/// ARMPopulateOperands - Handles all the operands in an ARM instruction, adding
-/// the appropriate flags to their descriptors
-///
-/// \param operandTypes A reference the array of operand type objects
-/// \param inst The instruction to use as a source of information
-static void ARMPopulateOperands(
- LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
- const CodeGenInstruction &inst) {
- if (!inst.TheDef->isSubClassOf("InstARM") &&
- !inst.TheDef->isSubClassOf("InstThumb"))
- return;
-
- unsigned int index;
- unsigned int numOperands = inst.Operands.size();
-
- if (numOperands > EDIS_MAX_OPERANDS) {
- errs() << "numOperands == " << numOperands << " > " <<
- EDIS_MAX_OPERANDS << '\n';
- llvm_unreachable("Too many operands");
- }
-
- for (index = 0; index < numOperands; ++index) {
- const CGIOperandList::OperandInfo &operandInfo = inst.Operands[index];
- Record &rec = *operandInfo.Rec;
-
- if (ARMFlagFromOpName(operandTypes[index], rec.getName())) {
- errs() << "Operand type: " << rec.getName() << '\n';
- errs() << "Operand name: " << operandInfo.Name << '\n';
- errs() << "Instruction name: " << inst.TheDef->getName() << '\n';
- PrintFatalError("Unhandled type in EDEmitter");
- }
- }
-}
-
-#define BRANCH(target) { \
- instType.set("kInstructionTypeBranch"); \
- DECORATE1(target, "kOperandFlagTarget"); \
-}
-
-/// ARMExtractSemantics - Performs various checks on the name of an ARM
-/// instruction to determine what sort of an instruction it is and then adds
-/// the appropriate flags to the instruction and its operands
-///
-/// \param instType A reference to the type for the instruction as a whole
-/// \param operandTypes A reference to the array of operand type object pointers
-/// \param operandFlags A reference to the array of operand flag object pointers
-/// \param inst A reference to the original instruction
-static void ARMExtractSemantics(
- LiteralConstantEmitter &instType,
- LiteralConstantEmitter *(&operandTypes)[EDIS_MAX_OPERANDS],
- FlagsConstantEmitter *(&operandFlags)[EDIS_MAX_OPERANDS],
- const CodeGenInstruction &inst) {
- const std::string &name = inst.TheDef->getName();
-
- if (name == "tBcc" ||
- name == "tB" ||
- name == "t2Bcc" ||
- name == "Bcc" ||
- name == "tCBZ" ||
- name == "tCBNZ") {
- BRANCH("target");
- }
-
- if (name == "tBLr9" ||
- name == "BLr9_pred" ||
- name == "tBLXi_r9" ||
- name == "tBLXr_r9" ||
- name == "BLXr9" ||
- name == "t2BXJ" ||
- name == "BXJ") {
- BRANCH("func");
-
- unsigned opIndex;
- opIndex = inst.Operands.getOperandNamed("func");
- if (operandTypes[opIndex]->is("kOperandTypeImmediate"))
- operandTypes[opIndex]->set("kOperandTypeARMBranchTarget");
- }
-}
-
-#undef BRANCH
-
-/// populateInstInfo - Fills an array of InstInfos with information about each
-/// instruction in a target
-///
-/// \param infoArray The array of InstInfo objects to populate
-/// \param target The CodeGenTarget to use as a source of instructions
-static void populateInstInfo(CompoundConstantEmitter &infoArray,
- CodeGenTarget &target) {
- const std::vector<const CodeGenInstruction*> &numberedInstructions =
- target.getInstructionsByEnumValue();
-
- unsigned int index;
- unsigned int numInstructions = numberedInstructions.size();
-
- for (index = 0; index < numInstructions; ++index) {
- const CodeGenInstruction& inst = *numberedInstructions[index];
-
- CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter;
- infoArray.addEntry(infoStruct);
-
- LiteralConstantEmitter *instType = new LiteralConstantEmitter;
- infoStruct->addEntry(instType);
-
- LiteralConstantEmitter *numOperandsEmitter =
- new LiteralConstantEmitter(inst.Operands.size());
- infoStruct->addEntry(numOperandsEmitter);
-
- CompoundConstantEmitter *operandTypeArray = new CompoundConstantEmitter;
- infoStruct->addEntry(operandTypeArray);
-
- LiteralConstantEmitter *operandTypes[EDIS_MAX_OPERANDS];
-
- CompoundConstantEmitter *operandFlagArray = new CompoundConstantEmitter;
- infoStruct->addEntry(operandFlagArray);
-
- FlagsConstantEmitter *operandFlags[EDIS_MAX_OPERANDS];
-
- for (unsigned operandIndex = 0;
- operandIndex < EDIS_MAX_OPERANDS;
- ++operandIndex) {
- operandTypes[operandIndex] = new LiteralConstantEmitter;
- operandTypeArray->addEntry(operandTypes[operandIndex]);
-
- operandFlags[operandIndex] = new FlagsConstantEmitter;
- operandFlagArray->addEntry(operandFlags[operandIndex]);
- }
-
- unsigned numSyntaxes = 0;
-
- // We don't need to do anything for pseudo-instructions, as we'll never
- // see them here. We'll only see real instructions.
- // We still need to emit null initializers for everything.
- if (!inst.isPseudo) {
- if (target.getName() == "X86") {
- X86PopulateOperands(operandTypes, inst);
- X86ExtractSemantics(*instType, operandFlags, inst);
- numSyntaxes = 2;
- }
- else if (target.getName() == "ARM") {
- ARMPopulateOperands(operandTypes, inst);
- ARMExtractSemantics(*instType, operandTypes, operandFlags, inst);
- numSyntaxes = 1;
- }
- }
-
- CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter;
-
- infoStruct->addEntry(operandOrderArray);
-
- for (unsigned syntaxIndex = 0;
- syntaxIndex < EDIS_MAX_SYNTAXES;
- ++syntaxIndex) {
- CompoundConstantEmitter *operandOrder =
- new CompoundConstantEmitter(EDIS_MAX_OPERANDS);
-
- operandOrderArray->addEntry(operandOrder);
-
- if (syntaxIndex < numSyntaxes) {
- populateOperandOrder(operandOrder, inst, syntaxIndex);
- }
- }
-
- infoStruct = NULL;
- }
-}
-
-static void emitCommonEnums(raw_ostream &o, unsigned int &i) {
- EnumEmitter operandTypes("OperandTypes");
- operandTypes.addEntry("kOperandTypeNone");
- operandTypes.addEntry("kOperandTypeImmediate");
- operandTypes.addEntry("kOperandTypeRegister");
- operandTypes.addEntry("kOperandTypeX86Memory");
- operandTypes.addEntry("kOperandTypeX86EffectiveAddress");
- operandTypes.addEntry("kOperandTypeX86PCRelative");
- operandTypes.addEntry("kOperandTypeARMBranchTarget");
- operandTypes.addEntry("kOperandTypeARMSoRegReg");
- operandTypes.addEntry("kOperandTypeARMSoRegImm");
- operandTypes.addEntry("kOperandTypeARMSoImm");
- operandTypes.addEntry("kOperandTypeARMRotImm");
- operandTypes.addEntry("kOperandTypeARMSoImm2Part");
- operandTypes.addEntry("kOperandTypeARMPredicate");
- operandTypes.addEntry("kOperandTypeAddrModeImm12");
- operandTypes.addEntry("kOperandTypeLdStSOReg");
- operandTypes.addEntry("kOperandTypeARMAddrMode2");
- operandTypes.addEntry("kOperandTypeARMAddrMode2Offset");
- operandTypes.addEntry("kOperandTypeARMAddrMode3");
- operandTypes.addEntry("kOperandTypeARMAddrMode3Offset");
- operandTypes.addEntry("kOperandTypeARMLdStmMode");
- operandTypes.addEntry("kOperandTypeARMAddrMode5");
- operandTypes.addEntry("kOperandTypeARMAddrMode6");
- operandTypes.addEntry("kOperandTypeARMAddrMode6Offset");
- operandTypes.addEntry("kOperandTypeARMAddrMode7");
- operandTypes.addEntry("kOperandTypeARMAddrModePC");
- operandTypes.addEntry("kOperandTypeARMRegisterList");
- operandTypes.addEntry("kOperandTypeARMDPRRegisterList");
- operandTypes.addEntry("kOperandTypeARMSPRRegisterList");
- operandTypes.addEntry("kOperandTypeARMTBAddrMode");
- operandTypes.addEntry("kOperandTypeThumbITMask");
- operandTypes.addEntry("kOperandTypeThumbAddrModeImmS1");
- operandTypes.addEntry("kOperandTypeThumbAddrModeImmS2");
- operandTypes.addEntry("kOperandTypeThumbAddrModeImmS4");
- operandTypes.addEntry("kOperandTypeThumbAddrModeRegS1");
- operandTypes.addEntry("kOperandTypeThumbAddrModeRegS2");
- operandTypes.addEntry("kOperandTypeThumbAddrModeRegS4");
- operandTypes.addEntry("kOperandTypeThumbAddrModeRR");
- operandTypes.addEntry("kOperandTypeThumbAddrModeSP");
- operandTypes.addEntry("kOperandTypeThumbAddrModePC");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeReg");
- operandTypes.addEntry("kOperandTypeThumb2SoReg");
- operandTypes.addEntry("kOperandTypeThumb2SoImm");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8Offset");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeImm12");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeSoReg");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4");
- operandTypes.addEntry("kOperandTypeThumb2AddrModeImm8s4Offset");
- operandTypes.emit(o, i);
-
- o << "\n";
-
- EnumEmitter operandFlags("OperandFlags");
- operandFlags.addEntry("kOperandFlagSource");
- operandFlags.addEntry("kOperandFlagTarget");
- operandFlags.emitAsFlags(o, i);
-
- o << "\n";
-
- EnumEmitter instructionTypes("InstructionTypes");
- instructionTypes.addEntry("kInstructionTypeNone");
- instructionTypes.addEntry("kInstructionTypeMove");
- instructionTypes.addEntry("kInstructionTypeBranch");
- instructionTypes.addEntry("kInstructionTypePush");
- instructionTypes.addEntry("kInstructionTypePop");
- instructionTypes.addEntry("kInstructionTypeCall");
- instructionTypes.addEntry("kInstructionTypeReturn");
- instructionTypes.emit(o, i);
-
- o << "\n";
-}
-
-namespace llvm {
-
-void EmitEnhancedDisassemblerInfo(RecordKeeper &RK, raw_ostream &OS) {
- emitSourceFileHeader("Enhanced Disassembler Info", OS);
- unsigned int i = 0;
-
- CompoundConstantEmitter infoArray;
- CodeGenTarget target(RK);
-
- populateInstInfo(infoArray, target);
-
- emitCommonEnums(OS, i);
-
- OS << "static const llvm::EDInstInfo instInfo"
- << target.getName() << "[] = ";
- infoArray.emit(OS, i);
- OS << ";" << "\n";
-}
-
-} // End llvm namespace
diff --git a/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 5cabcadabdbc..0c3017f38920 100644
--- a/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -15,8 +15,6 @@
#define DEBUG_TYPE "decoder-emitter"
#include "CodeGenTarget.h"
-#include "llvm/TableGen/Error.h"
-#include "llvm/TableGen/Record.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -28,11 +26,12 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
-
-#include <vector>
#include <map>
#include <string>
+#include <vector>
using namespace llvm;
@@ -1867,7 +1866,7 @@ static void emitFieldFromInstruction(formatted_raw_ostream &OS) {
<< " if (numBits == sizeof(InsnType)*8)\n"
<< " fieldMask = (InsnType)(-1LL);\n"
<< " else\n"
- << " fieldMask = ((1 << numBits) - 1) << startBit;\n"
+ << " fieldMask = (((InsnType)1 << numBits) - 1) << startBit;\n"
<< " return (insn & fieldMask) >> startBit;\n"
<< "}\n\n";
}
diff --git a/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp b/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 48d41d7b96bd..d6020a8461d2 100644
--- a/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -16,8 +16,8 @@
#include "CodeGenDAGPatterns.h"
#include "CodeGenSchedule.h"
#include "CodeGenTarget.h"
-#include "TableGenBackends.h"
#include "SequenceToOffsetTable.h"
+#include "TableGenBackends.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
@@ -271,7 +271,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
std::string ClassName = TargetName + "GenInstrInfo";
OS << "namespace llvm {\n";
- OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"
+ OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
<< " explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
<< "};\n";
OS << "} // End llvm namespace \n";
@@ -286,7 +286,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
OS << "extern const char " << TargetName << "InstrNameData[];\n";
OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
- << " : TargetInstrInfoImpl(SO, DO) {\n"
+ << " : TargetInstrInfo(SO, DO) {\n"
<< " InitMCInstrInfo(" << TargetName << "Insts, "
<< TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
<< NumberedInstructions.size() << ");\n}\n";
diff --git a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
index fe55242930b1..df4d847a4d7f 100644
--- a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -221,27 +221,28 @@ enum IIT_Info {
IIT_I16 = 3,
IIT_I32 = 4,
IIT_I64 = 5,
- IIT_F32 = 6,
- IIT_F64 = 7,
- IIT_V2 = 8,
- IIT_V4 = 9,
- IIT_V8 = 10,
- IIT_V16 = 11,
- IIT_V32 = 12,
- IIT_MMX = 13,
+ IIT_F16 = 6,
+ IIT_F32 = 7,
+ IIT_F64 = 8,
+ IIT_V2 = 9,
+ IIT_V4 = 10,
+ IIT_V8 = 11,
+ IIT_V16 = 12,
+ IIT_V32 = 13,
IIT_PTR = 14,
IIT_ARG = 15,
-
+
// Values from 16+ are only encodable with the inefficient encoding.
- IIT_METADATA = 16,
- IIT_EMPTYSTRUCT = 17,
- IIT_STRUCT2 = 18,
- IIT_STRUCT3 = 19,
- IIT_STRUCT4 = 20,
- IIT_STRUCT5 = 21,
- IIT_EXTEND_VEC_ARG = 22,
- IIT_TRUNC_VEC_ARG = 23,
- IIT_ANYPTR = 24
+ IIT_MMX = 16,
+ IIT_METADATA = 17,
+ IIT_EMPTYSTRUCT = 18,
+ IIT_STRUCT2 = 19,
+ IIT_STRUCT3 = 20,
+ IIT_STRUCT4 = 21,
+ IIT_STRUCT5 = 22,
+ IIT_EXTEND_VEC_ARG = 23,
+ IIT_TRUNC_VEC_ARG = 24,
+ IIT_ANYPTR = 25
};
@@ -261,6 +262,7 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT,
switch (VT) {
default: PrintFatalError("unhandled MVT in intrinsic!");
+ case MVT::f16: return Sig.push_back(IIT_F16);
case MVT::f32: return Sig.push_back(IIT_F32);
case MVT::f64: return Sig.push_back(IIT_F64);
case MVT::Metadata: return Sig.push_back(IIT_METADATA);
@@ -511,10 +513,10 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << "// Add parameter attributes that are not common to all intrinsics.\n";
OS << "#ifdef GET_INTRINSIC_ATTRIBUTES\n";
if (TargetOnly)
- OS << "static AttrListPtr getAttributes(LLVMContext &C, " << TargetPrefix
+ OS << "static AttributeSet getAttributes(LLVMContext &C, " << TargetPrefix
<< "Intrinsic::ID id) {\n";
else
- OS << "AttrListPtr Intrinsic::getAttributes(LLVMContext &C, ID id) {\n";
+ OS << "AttributeSet Intrinsic::getAttributes(LLVMContext &C, ID id) {\n";
// Compute the maximum number of attribute arguments and the map
typedef std::map<const CodeGenIntrinsic*, unsigned,
@@ -532,9 +534,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
N = ++AttrNum;
}
- // Emit an array of AttributeWithIndex. Most intrinsics will have
- // at least one entry, for the function itself (index ~1), which is
- // usually nounwind.
+ // Emit an array of AttributeSet. Most intrinsics will have at least one
+ // entry, for the function itself (index ~1), which is usually nounwind.
OS << " static const uint8_t IntrinsicsToAttributesMap[] = {\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
@@ -545,10 +546,10 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
}
OS << " };\n\n";
- OS << " AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n";
+ OS << " AttributeSet AS[" << maxArgAttrs+1 << "];\n";
OS << " unsigned NumAttrs = 0;\n";
OS << " if (id != 0) {\n";
- OS << " SmallVector<Attributes::AttrVal, 8> AttrVec;\n";
+ OS << " SmallVector<Attribute::AttrKind, 8> AttrVec;\n";
OS << " switch(IntrinsicsToAttributesMap[id - ";
if (TargetOnly)
OS << "Intrinsic::num_intrinsics";
@@ -576,14 +577,14 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
do {
switch (intrinsic.ArgumentAttributes[ai].second) {
case CodeGenIntrinsic::NoCapture:
- OS << " AttrVec.push_back(Attributes::NoCapture);\n";
+ OS << " AttrVec.push_back(Attribute::NoCapture);\n";
break;
}
++ai;
} while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo);
- OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, "
+ OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, "
<< argNo+1 << ", AttrVec);\n";
}
}
@@ -594,34 +595,34 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << " AttrVec.clear();\n";
if (!intrinsic.canThrow)
- OS << " AttrVec.push_back(Attributes::NoUnwind);\n";
+ OS << " AttrVec.push_back(Attribute::NoUnwind);\n";
if (intrinsic.isNoReturn)
- OS << " AttrVec.push_back(Attributes::NoReturn);\n";
+ OS << " AttrVec.push_back(Attribute::NoReturn);\n";
switch (modRef) {
case MRK_none: break;
case MRK_readonly:
- OS << " AttrVec.push_back(Attributes::ReadOnly);\n";
+ OS << " AttrVec.push_back(Attribute::ReadOnly);\n";
break;
case MRK_readnone:
- OS << " AttrVec.push_back(Attributes::ReadNone);\n";
+ OS << " AttrVec.push_back(Attribute::ReadNone);\n";
break;
}
- OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, "
- << "AttrListPtr::FunctionIndex, AttrVec);\n";
+ OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, "
+ << "AttributeSet::FunctionIndex, AttrVec);\n";
}
if (numAttrs) {
OS << " NumAttrs = " << numAttrs << ";\n";
OS << " break;\n";
} else {
- OS << " return AttrListPtr();\n";
+ OS << " return AttributeSet();\n";
}
}
OS << " }\n";
OS << " }\n";
- OS << " return AttrListPtr::get(C, ArrayRef<AttributeWithIndex>(AWI, "
+ OS << " return AttributeSet::get(C, ArrayRef<AttributeSet>(AS, "
"NumAttrs));\n";
OS << "}\n";
OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";
diff --git a/contrib/llvm/utils/TableGen/OptParserEmitter.cpp b/contrib/llvm/utils/TableGen/OptParserEmitter.cpp
new file mode 100644
index 000000000000..0c1f6236e059
--- /dev/null
+++ b/contrib/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -0,0 +1,266 @@
+//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TableGen/Error.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <map>
+
+using namespace llvm;
+
+static int StrCmpOptionName(const char *A, const char *B) {
+ char a = *A, b = *B;
+ while (a == b) {
+ if (a == '\0')
+ return 0;
+
+ a = *++A;
+ b = *++B;
+ }
+
+ if (a == '\0') // A is a prefix of B.
+ return 1;
+ if (b == '\0') // B is a prefix of A.
+ return -1;
+
+ // Otherwise lexicographic.
+ return (a < b) ? -1 : 1;
+}
+
+static int CompareOptionRecords(const void *Av, const void *Bv) {
+ const Record *A = *(const Record*const*) Av;
+ const Record *B = *(const Record*const*) Bv;
+
+ // Sentinel options precede all others and are only ordered by precedence.
+ bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+ bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel");
+ if (ASent != BSent)
+ return ASent ? -1 : 1;
+
+ // Compare options by name, unless they are sentinels.
+ if (!ASent)
+ if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
+ B->getValueAsString("Name").c_str()))
+ return Cmp;
+
+ if (!ASent) {
+ std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes");
+ std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes");
+
+ for (std::vector<std::string>::const_iterator APre = APrefixes.begin(),
+ AEPre = APrefixes.end(),
+ BPre = BPrefixes.begin(),
+ BEPre = BPrefixes.end();
+ APre != AEPre &&
+ BPre != BEPre;
+ ++APre, ++BPre) {
+ if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str()))
+ return Cmp;
+ }
+ }
+
+ // Then by the kind precedence;
+ int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");
+ int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence");
+ if (APrec == BPrec &&
+ A->getValueAsListOfStrings("Prefixes") ==
+ B->getValueAsListOfStrings("Prefixes")) {
+ PrintError(A->getLoc(), Twine("Option is equivilent to"));
+ PrintError(B->getLoc(), Twine("Other defined here"));
+ PrintFatalError("Equivalent Options found.");
+ }
+ return APrec < BPrec ? -1 : 1;
+}
+
+static const std::string getOptionName(const Record &R) {
+ // Use the record name unless EnumName is defined.
+ if (isa<UnsetInit>(R.getValueInit("EnumName")))
+ return R.getName();
+
+ return R.getValueAsString("EnumName");
+}
+
+static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
+ OS << '"';
+ OS.write_escaped(Str);
+ OS << '"';
+ return OS;
+}
+
+/// OptParserEmitter - This tablegen backend takes an input .td file
+/// describing a list of options and emits a data structure for parsing and
+/// working with those options when given an input command line.
+namespace llvm {
+void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
+ // Get the option groups and options.
+ const std::vector<Record*> &Groups =
+ Records.getAllDerivedDefinitions("OptionGroup");
+ std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");
+
+ emitSourceFileHeader("Option Parsing Definitions", OS);
+
+ array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
+ // Generate prefix groups.
+ typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
+ typedef std::map<PrefixKeyT, std::string> PrefixesT;
+ PrefixesT Prefixes;
+ Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
+ unsigned CurPrefix = 0;
+ for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+ const Record &R = *Opts[i];
+ std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+ PrefixKeyT prfkey(prf.begin(), prf.end());
+ unsigned NewPrefix = CurPrefix + 1;
+ if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
+ Twine(NewPrefix)).str())).second)
+ CurPrefix = NewPrefix;
+ }
+
+ // Dump prefixes.
+
+ OS << "/////////\n";
+ OS << "// Prefixes\n\n";
+ OS << "#ifdef PREFIX\n";
+ OS << "#define COMMA ,\n";
+ for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
+ I != E; ++I) {
+ OS << "PREFIX(";
+
+ // Prefix name.
+ OS << I->second;
+
+ // Prefix values.
+ OS << ", {";
+ for (PrefixKeyT::const_iterator PI = I->first.begin(),
+ PE = I->first.end(); PI != PE; ++PI) {
+ OS << "\"" << *PI << "\" COMMA ";
+ }
+ OS << "0})\n";
+ }
+ OS << "#undef COMMA\n";
+ OS << "#endif\n\n";
+
+ OS << "/////////\n";
+ OS << "// Groups\n\n";
+ OS << "#ifdef OPTION\n";
+ for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
+ const Record &R = *Groups[i];
+
+ // Start a single option entry.
+ OS << "OPTION(";
+
+ // The option prefix;
+ OS << "0";
+
+ // The option string.
+ OS << ", \"" << R.getValueAsString("Name") << '"';
+
+ // The option identifier name.
+ OS << ", "<< getOptionName(R);
+
+ // The option kind.
+ OS << ", Group";
+
+ // The containing option group (if any).
+ OS << ", ";
+ if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
+ OS << getOptionName(*DI->getDef());
+ else
+ OS << "INVALID";
+
+ // The other option arguments (unused for groups).
+ OS << ", INVALID, 0, 0";
+
+ // The option help text.
+ if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
+ OS << ",\n";
+ OS << " ";
+ write_cstring(OS, R.getValueAsString("HelpText"));
+ } else
+ OS << ", 0";
+
+ // The option meta-variable name (unused).
+ OS << ", 0)\n";
+ }
+ OS << "\n";
+
+ OS << "//////////\n";
+ OS << "// Options\n\n";
+ for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
+ const Record &R = *Opts[i];
+
+ // Start a single option entry.
+ OS << "OPTION(";
+
+ // The option prefix;
+ std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
+ OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
+
+ // The option string.
+ write_cstring(OS, R.getValueAsString("Name"));
+
+ // The option identifier name.
+ OS << ", "<< getOptionName(R);
+
+ // The option kind.
+ OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
+
+ // The containing option group (if any).
+ OS << ", ";
+ if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
+ OS << getOptionName(*DI->getDef());
+ else
+ OS << "INVALID";
+
+ // The option alias (if any).
+ OS << ", ";
+ if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))
+ OS << getOptionName(*DI->getDef());
+ else
+ OS << "INVALID";
+
+ // The option flags.
+ const ListInit *LI = R.getValueAsListInit("Flags");
+ if (LI->empty()) {
+ OS << ", 0";
+ } else {
+ OS << ", ";
+ for (unsigned i = 0, e = LI->size(); i != e; ++i) {
+ if (i)
+ OS << " | ";
+ OS << cast<DefInit>(LI->getElement(i))->getDef()->getName();
+ }
+ }
+
+ // The option parameter field.
+ OS << ", " << R.getValueAsInt("NumArgs");
+
+ // The option help text.
+ if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
+ OS << ",\n";
+ OS << " ";
+ write_cstring(OS, R.getValueAsString("HelpText"));
+ } else
+ OS << ", 0";
+
+ // The option meta-variable name.
+ OS << ", ";
+ if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
+ write_cstring(OS, R.getValueAsString("MetaVarName"));
+ else
+ OS << "0";
+
+ OS << ")\n";
+ }
+ OS << "#endif\n";
+}
+} // end namespace llvm
diff --git a/contrib/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/contrib/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
index 64aaee756b1d..1ea6f7932a3e 100644
--- a/contrib/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -252,6 +252,7 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
MIOpNo += Dest.Operands[OpNo].MINumOperands;
}
if (Dest.Operands.isVariadic) {
+ MIOpNo = Source.Operands.size() + 1;
o << " // variable_ops\n";
o << " for (unsigned i = " << MIOpNo
<< ", e = MI->getNumOperands(); i != e; ++i)\n"
diff --git a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 95b626723830..1b5d90b8bda2 100644
--- a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -185,6 +185,36 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
<< " return RCWeightTable[RC->getID()];\n"
<< "}\n\n";
+ // Reasonable targets (not ARMv7) have unit weight for all units, so don't
+ // bother generating a table.
+ bool RegUnitsHaveUnitWeight = true;
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ if (RegBank.getRegUnit(UnitIdx).Weight > 1)
+ RegUnitsHaveUnitWeight = false;
+ }
+ OS << "/// Get the weight in units of pressure for this register unit.\n"
+ << "unsigned " << ClassName << "::\n"
+ << "getRegUnitWeight(unsigned RegUnit) const {\n"
+ << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
+ << " && \"invalid register unit\");\n";
+ if (!RegUnitsHaveUnitWeight) {
+ OS << " static const uint8_t RUWeightTable[] = {\n ";
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ const RegUnit &RU = RegBank.getRegUnit(UnitIdx);
+ assert(RU.Weight < 256 && "RegUnit too heavy");
+ OS << RU.Weight << ", ";
+ }
+ OS << "0 };\n"
+ << " return RUWeightTable[RegUnit];\n";
+ }
+ else {
+ OS << " // All register units have unit weight.\n"
+ << " return 1;\n";
+ }
+ OS << "}\n\n";
+
OS << "\n"
<< "// Get the number of dimensions of register pressure.\n"
<< "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
@@ -215,14 +245,13 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
<< " return PressureLimitTable[Idx];\n"
<< "}\n\n";
- OS << "/// Get the dimensions of register pressure "
- << "impacted by this register class.\n"
- << "/// Returns a -1 terminated array of pressure set IDs\n"
- << "const int* " << ClassName << "::\n"
- << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n"
- << " static const int RCSetsTable[] = {\n ";
- std::vector<unsigned> RCSetStarts(NumRCs);
- for (unsigned i = 0, StartIdx = 0, e = NumRCs; i != e; ++i) {
+ // This table may be larger than NumRCs if some register units needed a list
+ // of unit sets that did not correspond to a register class.
+ unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
+ OS << "/// Table of pressure sets per register class or unit.\n"
+ << "static const int RCSetsTable[] = {\n ";
+ std::vector<unsigned> RCSetStarts(NumRCUnitSets);
+ for (unsigned i = 0, StartIdx = 0, e = NumRCUnitSets; i != e; ++i) {
RCSetStarts[i] = StartIdx;
ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
@@ -230,10 +259,26 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
OS << *PSetI << ", ";
++StartIdx;
}
- OS << "-1, \t// " << RegBank.getRegClasses()[i]->getName() << "\n ";
+ OS << "-1, \t// #" << RCSetStarts[i] << " ";
+ if (i < NumRCs)
+ OS << RegBank.getRegClasses()[i]->getName();
+ else {
+ OS << "inferred";
+ for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
+ PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) {
+ OS << "~" << RegBank.getRegPressureSet(*PSetI).Name;
+ }
+ }
+ OS << "\n ";
++StartIdx;
}
- OS << "-1 };\n";
+ OS << "-1 };\n\n";
+
+ OS << "/// Get the dimensions of register pressure impacted by this "
+ << "register class.\n"
+ << "/// Returns a -1 terminated array of pressure set IDs\n"
+ << "const int* " << ClassName << "::\n"
+ << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
OS << " static const unsigned RCSetStartTable[] = {\n ";
for (unsigned i = 0, e = NumRCs; i != e; ++i) {
OS << RCSetStarts[i] << ",";
@@ -242,6 +287,23 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
<< " unsigned SetListStart = RCSetStartTable[RC->getID()];\n"
<< " return &RCSetsTable[SetListStart];\n"
<< "}\n\n";
+
+ OS << "/// Get the dimensions of register pressure impacted by this "
+ << "register unit.\n"
+ << "/// Returns a -1 terminated array of pressure set IDs\n"
+ << "const int* " << ClassName << "::\n"
+ << "getRegUnitPressureSets(unsigned RegUnit) const {\n"
+ << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
+ << " && \"invalid register unit\");\n";
+ OS << " static const unsigned RUSetStartTable[] = {\n ";
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ OS << RCSetStarts[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx] << ",";
+ }
+ OS << "0 };\n"
+ << " unsigned SetListStart = RUSetStartTable[RegUnit];\n"
+ << " return &RCSetsTable[SetListStart];\n"
+ << "}\n\n";
}
void
@@ -729,7 +791,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
const std::string &TargetName = Target.getName();
// Emit the shared table of differential lists.
- OS << "extern const uint16_t " << TargetName << "RegDiffLists[] = {\n";
+ OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
DiffSeqs.emit(OS, printDiff16);
OS << "};\n\n";
@@ -859,9 +921,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// MCRegisterInfo initialization routine.
OS << "static inline void Init" << TargetName
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
- << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"
+ << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) {\n"
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
- << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
+ << Regs.size()+1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
<< RegisterClasses.size() << ", "
<< TargetName << "RegUnitRoots, "
<< RegBank.getNumNativeRegUnits() << ", "
@@ -896,7 +958,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
- << "(unsigned RA, unsigned D = 0, unsigned E = 0);\n"
+ << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
<< " { return false; }\n";
if (!RegBank.getSubRegIndices().empty()) {
@@ -907,11 +969,13 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
}
OS << " virtual const RegClassWeight &getRegClassWeight("
<< "const TargetRegisterClass *RC) const;\n"
+ << " virtual unsigned getRegUnitWeight(unsigned RegUnit) const;\n"
<< " virtual unsigned getNumRegPressureSets() const;\n"
<< " virtual const char *getRegPressureSetName(unsigned Idx) const;\n"
<< " virtual unsigned getRegPressureSetLimit(unsigned Idx) const;\n"
<< " virtual const int *getRegClassPressureSets("
<< "const TargetRegisterClass *RC) const;\n"
+ << " virtual const int *getRegUnitPressureSets(unsigned RegUnit) const;\n"
<< "};\n\n";
ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
@@ -967,7 +1031,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
// Build a shared array of value types.
- SequenceToOffsetTable<std::vector<MVT::SimpleValueType> > VTSeqs;
+ SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc)
VTSeqs.add(RegisterClasses[rc]->VTs);
VTSeqs.layout();
@@ -1074,12 +1138,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "\nstatic inline unsigned " << RC.getName()
<< "AltOrderSelect(const MachineFunction &MF) {"
<< RC.AltOrderSelect << "}\n\n"
- << "static ArrayRef<uint16_t> " << RC.getName()
+ << "static ArrayRef<MCPhysReg> " << RC.getName()
<< "GetRawAllocationOrder(const MachineFunction &MF) {\n";
for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) {
ArrayRef<Record*> Elems = RC.getOrder(oi);
if (!Elems.empty()) {
- OS << " static const uint16_t AltOrder" << oi << "[] = {";
+ OS << " static const MCPhysReg AltOrder" << oi << "[] = {";
for (unsigned elem = 0; elem != Elems.size(); ++elem)
OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
OS << " };\n";
@@ -1087,11 +1151,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << " const MCRegisterClass &MCR = " << Target.getName()
<< "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
- << " const ArrayRef<uint16_t> Order[] = {\n"
+ << " const ArrayRef<MCPhysReg> Order[] = {\n"
<< " makeArrayRef(MCR.begin(), MCR.getNumRegs()";
for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
if (RC.getOrder(oi).empty())
- OS << "),\n ArrayRef<uint16_t>(";
+ OS << "),\n ArrayRef<MCPhysReg>(";
else
OS << "),\n makeArrayRef(AltOrder" << oi;
OS << ")\n };\n const unsigned Select = " << RC.getName()
@@ -1194,7 +1258,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
- OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n";
+ OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
OS << "extern const char " << TargetName << "RegStrings[];\n";
OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n";
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
@@ -1203,12 +1267,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
EmitRegMappingTables(OS, Regs, true);
OS << ClassName << "::\n" << ClassName
- << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
+ << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
- << Regs.size()+1 << ", RA,\n " << TargetName
+ << Regs.size()+1 << ", RA, PC,\n " << TargetName
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
<< " " << TargetName << "RegUnitRoots,\n"
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
@@ -1232,7 +1296,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
assert(Regs && "Cannot expand CalleeSavedRegs instance");
// Emit the *_SaveList list of callee-saved registers.
- OS << "static const uint16_t " << CSRSet->getName()
+ OS << "static const MCPhysReg " << CSRSet->getName()
<< "_SaveList[] = { ";
for (unsigned r = 0, re = Regs->size(); r != re; ++r)
OS << getQualifiedName((*Regs)[r]) << ", ";
diff --git a/contrib/llvm/utils/TableGen/SequenceToOffsetTable.h b/contrib/llvm/utils/TableGen/SequenceToOffsetTable.h
index d4db152a9681..fcda233dc913 100644
--- a/contrib/llvm/utils/TableGen/SequenceToOffsetTable.h
+++ b/contrib/llvm/utils/TableGen/SequenceToOffsetTable.h
@@ -17,11 +17,11 @@
#define TBLGEN_SEQUENCE_TO_OFFSET_TABLE_H
#include "llvm/Support/raw_ostream.h"
-#include <functional>
#include <algorithm>
-#include <vector>
#include <cassert>
#include <cctype>
+#include <functional>
+#include <vector>
namespace llvm {
diff --git a/contrib/llvm/utils/TableGen/SetTheory.cpp b/contrib/llvm/utils/TableGen/SetTheory.cpp
index 0dd9853843fe..3e5c38cf0a51 100644
--- a/contrib/llvm/utils/TableGen/SetTheory.cpp
+++ b/contrib/llvm/utils/TableGen/SetTheory.cpp
@@ -13,9 +13,9 @@
//===----------------------------------------------------------------------===//
#include "SetTheory.h"
+#include "llvm/Support/Format.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
-#include "llvm/Support/Format.h"
using namespace llvm;
diff --git a/contrib/llvm/utils/TableGen/SetTheory.h b/contrib/llvm/utils/TableGen/SetTheory.h
index 122372ab33c0..5baed79fb76a 100644
--- a/contrib/llvm/utils/TableGen/SetTheory.h
+++ b/contrib/llvm/utils/TableGen/SetTheory.h
@@ -47,8 +47,8 @@
#ifndef SETTHEORY_H
#define SETTHEORY_H
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/SourceMgr.h"
#include <map>
#include <vector>
diff --git a/contrib/llvm/utils/TableGen/StringToOffsetTable.h b/contrib/llvm/utils/TableGen/StringToOffsetTable.h
index a098d7d744a1..d94d3a266822 100644
--- a/contrib/llvm/utils/TableGen/StringToOffsetTable.h
+++ b/contrib/llvm/utils/TableGen/StringToOffsetTable.h
@@ -11,8 +11,8 @@
#define TBLGEN_STRING_TO_OFFSET_TABLE_H
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
diff --git a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
index f1a06bb52887..98892e11441b 100644
--- a/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -15,14 +15,14 @@
#include "CodeGenTarget.h"
#include "CodeGenSchedule.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
#include <algorithm>
#include <map>
#include <string>
@@ -87,6 +87,8 @@ class SubtargetEmitter {
const CodeGenProcModel &ProcModel);
Record *FindReadAdvance(const CodeGenSchedRW &SchedRead,
const CodeGenProcModel &ProcModel);
+ void ExpandProcResources(RecVec &PRVec, std::vector<int64_t> &Cycles,
+ const CodeGenProcModel &ProcModel);
void GenSchedClassTables(const CodeGenProcModel &ProcModel,
SchedClassTables &SchedTables);
void EmitSchedClassTables(SchedClassTables &SchedTables, raw_ostream &OS);
@@ -445,17 +447,15 @@ EmitStageAndOperandCycleData(raw_ostream &OS,
// If this processor defines no itineraries, then leave the itinerary list
// empty.
std::vector<InstrItinerary> &ItinList = ProcItinLists.back();
- if (ProcModel.ItinDefList.empty())
+ if (!ProcModel.hasItineraries())
continue;
- // Reserve index==0 for NoItinerary.
- ItinList.resize(SchedModels.numItineraryClasses()+1);
-
const std::string &Name = ProcModel.ItinsDef->getName();
- // For each itinerary data
- for (unsigned SchedClassIdx = 0,
- SchedClassEnd = ProcModel.ItinDefList.size();
+ ItinList.resize(SchedModels.numInstrSchedClasses());
+ assert(ProcModel.ItinDefList.size() == ItinList.size() && "bad Itins");
+
+ for (unsigned SchedClassIdx = 0, SchedClassEnd = ItinList.size();
SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
// Next itinerary data
@@ -631,13 +631,31 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
for (unsigned i = 0, e = ProcModel.ProcResourceDefs.size(); i < e; ++i) {
Record *PRDef = ProcModel.ProcResourceDefs[i];
- // Find the SuperIdx
- unsigned SuperIdx = 0;
Record *SuperDef = 0;
- if (PRDef->getValueInit("Super")->isComplete()) {
- SuperDef =
- SchedModels.findProcResUnits(PRDef->getValueAsDef("Super"), ProcModel);
- SuperIdx = ProcModel.getProcResourceIdx(SuperDef);
+ unsigned SuperIdx = 0;
+ unsigned NumUnits = 0;
+ bool IsBuffered = true;
+ if (PRDef->isSubClassOf("ProcResGroup")) {
+ RecVec ResUnits = PRDef->getValueAsListOfDefs("Resources");
+ for (RecIter RUI = ResUnits.begin(), RUE = ResUnits.end();
+ RUI != RUE; ++RUI) {
+ if (!NumUnits)
+ IsBuffered = (*RUI)->getValueAsBit("Buffered");
+ else if(IsBuffered != (*RUI)->getValueAsBit("Buffered"))
+ PrintFatalError(PRDef->getLoc(),
+ "Mixing buffered and unbuffered resources.");
+ NumUnits += (*RUI)->getValueAsInt("NumUnits");
+ }
+ }
+ else {
+ // Find the SuperIdx
+ if (PRDef->getValueInit("Super")->isComplete()) {
+ SuperDef = SchedModels.findProcResUnits(
+ PRDef->getValueAsDef("Super"), ProcModel);
+ SuperIdx = ProcModel.getProcResourceIdx(SuperDef);
+ }
+ NumUnits = PRDef->getValueAsInt("NumUnits");
+ IsBuffered = PRDef->getValueAsBit("Buffered");
}
// Emit the ProcResourceDesc
if (i+1 == e)
@@ -645,8 +663,8 @@ void SubtargetEmitter::EmitProcessorResources(const CodeGenProcModel &ProcModel,
OS << " {DBGFIELD(\"" << PRDef->getName() << "\") ";
if (PRDef->getName().size() < 15)
OS.indent(15 - PRDef->getName().size());
- OS << PRDef->getValueAsInt("NumUnits") << ", " << SuperIdx << ", "
- << PRDef->getValueAsBit("Buffered") << "}" << Sep << " // #" << i+1;
+ OS << NumUnits << ", " << SuperIdx << ", "
+ << IsBuffered << "}" << Sep << " // #" << i+1;
if (SuperDef)
OS << ", Super=" << SuperDef->getName();
OS << "\n";
@@ -763,6 +781,51 @@ Record *SubtargetEmitter::FindReadAdvance(const CodeGenSchedRW &SchedRead,
return ResDef;
}
+// Expand an explicit list of processor resources into a full list of implied
+// resource groups that cover them.
+//
+// FIXME: Effectively consider a super-resource a group that include all of its
+// subresources to allow mixing and matching super-resources and groups.
+//
+// FIXME: Warn if two overlapping groups don't have a common supergroup.
+void SubtargetEmitter::ExpandProcResources(RecVec &PRVec,
+ std::vector<int64_t> &Cycles,
+ const CodeGenProcModel &ProcModel) {
+ // Default to 1 resource cycle.
+ Cycles.resize(PRVec.size(), 1);
+ for (unsigned i = 0, e = PRVec.size(); i != e; ++i) {
+ RecVec SubResources;
+ if (PRVec[i]->isSubClassOf("ProcResGroup")) {
+ SubResources = PRVec[i]->getValueAsListOfDefs("Resources");
+ std::sort(SubResources.begin(), SubResources.end(), LessRecord());
+ }
+ else {
+ SubResources.push_back(PRVec[i]);
+ }
+ for (RecIter PRI = ProcModel.ProcResourceDefs.begin(),
+ PRE = ProcModel.ProcResourceDefs.end();
+ PRI != PRE; ++PRI) {
+ if (*PRI == PRVec[i] || !(*PRI)->isSubClassOf("ProcResGroup"))
+ continue;
+ RecVec SuperResources = (*PRI)->getValueAsListOfDefs("Resources");
+ std::sort(SuperResources.begin(), SuperResources.end(), LessRecord());
+ RecIter SubI = SubResources.begin(), SubE = SubResources.end();
+ RecIter SuperI = SuperResources.begin(), SuperE = SuperResources.end();
+ for ( ; SubI != SubE && SuperI != SuperE; ++SuperI) {
+ if (*SubI < *SuperI)
+ break;
+ else if (*SuperI < *SubI)
+ continue;
+ ++SubI;
+ }
+ if (SubI == SubE) {
+ PRVec.push_back(*PRI);
+ Cycles.push_back(Cycles[i]);
+ }
+ }
+ }
+}
+
// Generate the SchedClass table for this processor and update global
// tables. Must be called for each processor in order.
void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
@@ -787,7 +850,22 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
SCDesc.ReadAdvanceIdx = 0;
// A Variant SchedClass has no resources of its own.
- if (!SCI->Transitions.empty()) {
+ bool HasVariants = false;
+ for (std::vector<CodeGenSchedTransition>::const_iterator
+ TI = SCI->Transitions.begin(), TE = SCI->Transitions.end();
+ TI != TE; ++TI) {
+ if (TI->ProcIndices[0] == 0) {
+ HasVariants = true;
+ break;
+ }
+ IdxIter PIPos = std::find(TI->ProcIndices.begin(),
+ TI->ProcIndices.end(), ProcModel.Index);
+ if (PIPos != TI->ProcIndices.end()) {
+ HasVariants = true;
+ break;
+ }
+ }
+ if (HasVariants) {
SCDesc.NumMicroOps = MCSchedClassDesc::VariantNumMicroOps;
continue;
}
@@ -804,27 +882,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
}
IdxVec Writes = SCI->Writes;
IdxVec Reads = SCI->Reads;
- if (SCI->ItinClassDef) {
- assert(SCI->InstRWs.empty() && "ItinClass should not have InstRWs");
- // Check this processor's itinerary class resources.
- for (RecIter II = ProcModel.ItinRWDefs.begin(),
- IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) {
- RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
- if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef)
- != Matched.end()) {
- SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"),
- Writes, Reads);
- break;
- }
- }
- if (Writes.empty()) {
- DEBUG(dbgs() << ProcModel.ItinsDef->getName()
- << " does not have resources for itinerary class "
- << SCI->ItinClassDef->getName() << '\n');
- }
- }
- else if (!SCI->InstRWs.empty()) {
- // This class may have a default ReadWrite list which can be overriden by
+ if (!SCI->InstRWs.empty()) {
+ // This class has a default ReadWrite list which can be overriden by
// InstRW definitions.
Record *RWDef = 0;
for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end();
@@ -842,6 +901,23 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
Writes, Reads);
}
}
+ if (Writes.empty()) {
+ // Check this processor's itinerary class resources.
+ for (RecIter II = ProcModel.ItinRWDefs.begin(),
+ IE = ProcModel.ItinRWDefs.end(); II != IE; ++II) {
+ RecVec Matched = (*II)->getValueAsListOfDefs("MatchedItinClasses");
+ if (std::find(Matched.begin(), Matched.end(), SCI->ItinClassDef)
+ != Matched.end()) {
+ SchedModels.findRWs((*II)->getValueAsListOfDefs("OperandReadWrites"),
+ Writes, Reads);
+ break;
+ }
+ }
+ if (Writes.empty()) {
+ DEBUG(dbgs() << ProcModel.ModelName
+ << " does not have resources for class " << SCI->Name << '\n');
+ }
+ }
// Sum resources across all operand writes.
std::vector<MCWriteProcResEntry> WriteProcResources;
std::vector<MCWriteLatencyEntry> WriteLatencies;
@@ -859,7 +935,8 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
WriterNames.push_back(SchedModels.getSchedWrite(WriteID).Name);
// If this Write is not referenced by a ReadAdvance, don't distinguish it
// from other WriteLatency entries.
- if (!SchedModels.hasReadOfWrite(SchedModels.getSchedWrite(WriteID).TheDef)) {
+ if (!SchedModels.hasReadOfWrite(
+ SchedModels.getSchedWrite(WriteID).TheDef)) {
WriteID = 0;
}
WLEntry.WriteResourceID = WriteID;
@@ -884,16 +961,29 @@ void SubtargetEmitter::GenSchedClassTables(const CodeGenProcModel &ProcModel,
RecVec PRVec = WriteRes->getValueAsListOfDefs("ProcResources");
std::vector<int64_t> Cycles =
WriteRes->getValueAsListOfInts("ResourceCycles");
+
+ ExpandProcResources(PRVec, Cycles, ProcModel);
+
for (unsigned PRIdx = 0, PREnd = PRVec.size();
PRIdx != PREnd; ++PRIdx) {
MCWriteProcResEntry WPREntry;
WPREntry.ProcResourceIdx = ProcModel.getProcResourceIdx(PRVec[PRIdx]);
assert(WPREntry.ProcResourceIdx && "Bad ProcResourceIdx");
- if (Cycles.size() > PRIdx)
- WPREntry.Cycles = Cycles[PRIdx];
- else
- WPREntry.Cycles = 1;
- WriteProcResources.push_back(WPREntry);
+ WPREntry.Cycles = Cycles[PRIdx];
+ // If this resource is already used in this sequence, add the current
+ // entry's cycles so that the same resource appears to be used
+ // serially, rather than multiple parallel uses. This is important for
+ // in-order machine where the resource consumption is a hazard.
+ unsigned WPRIdx = 0, WPREnd = WriteProcResources.size();
+ for( ; WPRIdx != WPREnd; ++WPRIdx) {
+ if (WriteProcResources[WPRIdx].ProcResourceIdx
+ == WPREntry.ProcResourceIdx) {
+ WriteProcResources[WPRIdx].Cycles += WPREntry.Cycles;
+ break;
+ }
+ }
+ if (WPRIdx == WPREnd)
+ WriteProcResources.push_back(WPREntry);
}
}
WriteLatencies.push_back(WLEntry);
@@ -1062,7 +1152,7 @@ void SubtargetEmitter::EmitSchedClassTables(SchedClassTables &SchedTables,
// The first class is always invalid. We no way to distinguish it except by
// name and position.
- assert(SchedModels.getSchedClass(0).Name == "NoItinerary"
+ assert(SchedModels.getSchedClass(0).Name == "NoInstrModel"
&& "invalid class not first");
OS << " {DBGFIELD(\"InvalidSchedClass\") "
<< MCSchedClassDesc::InvalidNumMicroOps
@@ -1108,6 +1198,7 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
EmitProcessorProp(OS, PI->ModelDef, "MinLatency", ',');
EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ',');
EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ',');
+ EmitProcessorProp(OS, PI->ModelDef, "ILPWindow", ',');
EmitProcessorProp(OS, PI->ModelDef, "MispredictPenalty", ',');
OS << " " << PI->Index << ", // Processor ID\n";
if (PI->hasInstrSchedModel())
@@ -1118,7 +1209,7 @@ void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
- SchedModels.schedClassBegin()) << ",\n";
else
OS << " 0, 0, 0, 0, // No instruction-level machine model.\n";
- if (SchedModels.hasItineraryClasses())
+ if (SchedModels.hasItineraries())
OS << " " << PI->ItinsDef->getName() << ");\n";
else
OS << " 0); // No Itinerary\n";
@@ -1175,7 +1266,7 @@ void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
<< "#define DBGFIELD(x)\n"
<< "#endif\n";
- if (SchedModels.hasItineraryClasses()) {
+ if (SchedModels.hasItineraries()) {
std::vector<std::vector<InstrItinerary> > ProcItinLists;
// Emit the stage data
EmitStageAndOperandCycleData(OS, ProcItinLists);
@@ -1216,7 +1307,7 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName,
SCE = SchedModels.schedClassEnd(); SCI != SCE; ++SCI) {
if (SCI->Transitions.empty())
continue;
- VariantClasses.push_back(SCI - SchedModels.schedClassBegin());
+ VariantClasses.push_back(SCI->Index);
}
if (!VariantClasses.empty()) {
OS << " switch (SchedClass) {\n";
@@ -1263,13 +1354,8 @@ void SubtargetEmitter::EmitSchedModelHelpers(std::string ClassName,
if (*PI == 0)
break;
}
- unsigned SCIdx = 0;
- if (SC.ItinClassDef)
- SCIdx = SchedModels.getSchedClassIdxForItin(SC.ItinClassDef);
- else
- SCIdx = SchedModels.findSchedClassIdx(SC.Writes, SC.Reads);
- if (SCIdx != *VCI)
- OS << " return " << SCIdx << ";\n";
+ if (SC.isInferred())
+ OS << " return " << SC.Index << ";\n";
OS << " break;\n";
}
OS << " };\n";
@@ -1375,7 +1461,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< Target << "WriteProcResTable, "
<< Target << "WriteLatencyTable, "
<< Target << "ReadAdvanceTable, ";
- if (SchedModels.hasItineraryClasses()) {
+ if (SchedModels.hasItineraries()) {
OS << '\n'; OS.indent(22);
OS << Target << "Stages, "
<< Target << "OperandCycles, "
@@ -1432,7 +1518,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
OS << "extern const llvm::MCReadAdvanceEntry "
<< Target << "ReadAdvanceTable[];\n";
- if (SchedModels.hasItineraryClasses()) {
+ if (SchedModels.hasItineraries()) {
OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
OS << "extern const unsigned " << Target << "OperandCycles[];\n";
OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
@@ -1456,7 +1542,7 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< Target << "WriteLatencyTable, "
<< Target << "ReadAdvanceTable, ";
OS << '\n'; OS.indent(22);
- if (SchedModels.hasItineraryClasses()) {
+ if (SchedModels.hasItineraries()) {
OS << Target << "Stages, "
<< Target << "OperandCycles, "
<< Target << "ForwardingPaths, ";
diff --git a/contrib/llvm/utils/TableGen/TableGen.cpp b/contrib/llvm/utils/TableGen/TableGen.cpp
index 49efe7ed7374..b5c3ca760db6 100644
--- a/contrib/llvm/utils/TableGen/TableGen.cpp
+++ b/contrib/llvm/utils/TableGen/TableGen.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "TableGenBackends.h" // Declares all backends.
-
#include "SetTheory.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -39,9 +38,10 @@ enum ActionType {
GenSubtarget,
GenIntrinsic,
GenTgtIntrinsic,
- GenEDInfo,
PrintEnums,
- PrintSets
+ PrintSets,
+ GenOptParserDefs,
+ GenCTags
};
namespace {
@@ -77,12 +77,14 @@ namespace {
"Generate intrinsic information"),
clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
"Generate target intrinsic information"),
- clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
- "Generate enhanced disassembly info"),
clEnumValN(PrintEnums, "print-enums",
"Print enum values for a class"),
clEnumValN(PrintSets, "print-sets",
"Print expanded sets for testing DAG exprs"),
+ clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
+ "Generate option definitions"),
+ clEnumValN(GenCTags, "gen-ctags",
+ "Generate ctags-compatible index"),
clEnumValEnd));
cl::opt<std::string>
@@ -136,8 +138,8 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenTgtIntrinsic:
EmitIntrinsics(Records, OS, true);
break;
- case GenEDInfo:
- EmitEnhancedDisassemblerInfo(Records, OS);
+ case GenOptParserDefs:
+ EmitOptParser(Records, OS);
break;
case PrintEnums:
{
@@ -162,6 +164,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
}
break;
}
+ case GenCTags:
+ EmitCTags(Records, OS);
+ break;
}
return false;
diff --git a/contrib/llvm/utils/TableGen/TableGenBackends.h b/contrib/llvm/utils/TableGen/TableGenBackends.h
index f0d25d8a2c81..28b626e17e89 100644
--- a/contrib/llvm/utils/TableGen/TableGenBackends.h
+++ b/contrib/llvm/utils/TableGen/TableGenBackends.h
@@ -68,12 +68,13 @@ void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS);
void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS);
void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS);
void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS);
-void EmitEnhancedDisassemblerInfo(RecordKeeper &RK, raw_ostream &OS);
void EmitFastISel(RecordKeeper &RK, raw_ostream &OS);
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS);
void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS);
void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS);
void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS);
void EmitMapTable(RecordKeeper &RK, raw_ostream &OS);
+void EmitOptParser(RecordKeeper &RK, raw_ostream &OS);
+void EmitCTags(RecordKeeper &RK, raw_ostream &OS);
} // End llvm namespace
diff --git a/contrib/llvm/utils/TableGen/X86DisassemblerShared.h b/contrib/llvm/utils/TableGen/X86DisassemblerShared.h
index c13a0cc467e1..3ff922b8225c 100644
--- a/contrib/llvm/utils/TableGen/X86DisassemblerShared.h
+++ b/contrib/llvm/utils/TableGen/X86DisassemblerShared.h
@@ -10,8 +10,8 @@
#ifndef X86DISASSEMBLERSHARED_H
#define X86DISASSEMBLERSHARED_H
-#include <string>
#include <string.h>
+#include <string>
#define INSTRUCTION_SPECIFIER_FIELDS \
struct OperandSpecifier operands[X86_MAX_OPERANDS]; \
diff --git a/contrib/llvm/utils/TableGen/X86DisassemblerTables.cpp b/contrib/llvm/utils/TableGen/X86DisassemblerTables.cpp
index 468a1f81c719..40a0c1b260b7 100644
--- a/contrib/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/contrib/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -14,13 +14,12 @@
//
//===----------------------------------------------------------------------===//
-#include "X86DisassemblerShared.h"
#include "X86DisassemblerTables.h"
-
-#include "llvm/TableGen/TableGenBackend.h"
+#include "X86DisassemblerShared.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <map>
using namespace llvm;
diff --git a/contrib/llvm/utils/TableGen/X86DisassemblerTables.h b/contrib/llvm/utils/TableGen/X86DisassemblerTables.h
index ea006c05b991..01aeaaf0bf90 100644
--- a/contrib/llvm/utils/TableGen/X86DisassemblerTables.h
+++ b/contrib/llvm/utils/TableGen/X86DisassemblerTables.h
@@ -19,9 +19,7 @@
#include "X86DisassemblerShared.h"
#include "X86ModRMFilters.h"
-
#include "llvm/Support/raw_ostream.h"
-
#include <vector>
namespace llvm {
diff --git a/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp b/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
index d6ed2fe2c615..61b9813b06b8 100644
--- a/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/contrib/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -14,12 +14,10 @@
//
//===----------------------------------------------------------------------===//
-#include "X86DisassemblerShared.h"
#include "X86RecognizableInstr.h"
+#include "X86DisassemblerShared.h"
#include "X86ModRMFilters.h"
-
#include "llvm/Support/ErrorHandling.h"
-
#include <string>
using namespace llvm;
@@ -39,14 +37,15 @@ using namespace llvm;
MAP(D1, 46) \
MAP(D4, 47) \
MAP(D5, 48) \
- MAP(D8, 49) \
- MAP(D9, 50) \
- MAP(DA, 51) \
- MAP(DB, 52) \
- MAP(DC, 53) \
- MAP(DD, 54) \
- MAP(DE, 55) \
- MAP(DF, 56)
+ MAP(D6, 49) \
+ MAP(D8, 50) \
+ MAP(D9, 51) \
+ MAP(DA, 52) \
+ MAP(DB, 53) \
+ MAP(DC, 54) \
+ MAP(DD, 55) \
+ MAP(DE, 56) \
+ MAP(DF, 57)
// A clone of X86 since we can't depend on something that is generated.
namespace X86Local {
@@ -121,6 +120,7 @@ namespace X86Local {
#define TWO_BYTE_EXTENSION_TABLES \
EXTENSION_TABLE(00) \
EXTENSION_TABLE(01) \
+ EXTENSION_TABLE(0d) \
EXTENSION_TABLE(18) \
EXTENSION_TABLE(71) \
EXTENSION_TABLE(72) \
@@ -765,6 +765,17 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
HANDLE_OPERAND(immediate)
HANDLE_OPERAND(immediate)
break;
+ case X86Local::MRM_F8:
+ if (Opcode == 0xc6) {
+ assert(numPhysicalOperands == 1 &&
+ "Unexpected number of operands for X86Local::MRM_F8");
+ HANDLE_OPERAND(immediate)
+ } else if (Opcode == 0xc7) {
+ assert(numPhysicalOperands == 1 &&
+ "Unexpected number of operands for X86Local::MRM_F8");
+ HANDLE_OPERAND(relocation)
+ }
+ break;
case X86Local::MRMInitReg:
// Ignored.
break;
diff --git a/contrib/llvm/utils/TableGen/X86RecognizableInstr.h b/contrib/llvm/utils/TableGen/X86RecognizableInstr.h
index 9feb3c3c7d3b..9ec36a39df45 100644
--- a/contrib/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/contrib/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -17,13 +17,11 @@
#ifndef X86RECOGNIZABLEINSTR_H
#define X86RECOGNIZABLEINSTR_H
-#include "X86DisassemblerTables.h"
-
#include "CodeGenTarget.h"
-
-#include "llvm/TableGen/Record.h"
-#include "llvm/Support/DataTypes.h"
+#include "X86DisassemblerTables.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/TableGen/Record.h"
namespace llvm {