aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp13
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp6
-rw-r--r--utils/TableGen/CodeGenTarget.cpp11
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp9
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp3
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp79
6 files changed, 113 insertions, 8 deletions
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
index ae4a6aa445..912617bc01 100644
--- a/utils/TableGen/CodeEmitterGen.cpp
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -33,8 +33,9 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
R->getName() == "EXTRACT_SUBREG" ||
R->getName() == "INSERT_SUBREG" ||
R->getName() == "IMPLICIT_DEF" ||
- R->getName() == "SUBREG_TO_REG") continue;
-
+ R->getName() == "SUBREG_TO_REG" ||
+ R->getName() == "COPY_TO_SUBCLASS") continue;
+
BitsInit *BI = R->getValueAsBitsInit("Inst");
unsigned numBits = BI->getNumBits();
@@ -109,7 +110,8 @@ void CodeEmitterGen::run(std::ostream &o) {
R->getName() == "EXTRACT_SUBREG" ||
R->getName() == "INSERT_SUBREG" ||
R->getName() == "IMPLICIT_DEF" ||
- R->getName() == "SUBREG_TO_REG") {
+ R->getName() == "SUBREG_TO_REG" ||
+ R->getName() == "COPY_TO_SUBCLASS") {
o << " 0U,\n";
continue;
}
@@ -146,8 +148,9 @@ void CodeEmitterGen::run(std::ostream &o) {
InstName == "EXTRACT_SUBREG" ||
InstName == "INSERT_SUBREG" ||
InstName == "IMPLICIT_DEF" ||
- InstName == "SUBREG_TO_REG") continue;
-
+ InstName == "SUBREG_TO_REG" ||
+ InstName == "COPY_TO_SUBCLASS") continue;
+
BitsInit *BI = R->getValueAsBitsInit("Inst");
const std::vector<RecordVal> &Vals = R->getValues();
CodeGenInstruction &CGI = Target.getInstruction(InstName);
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 5bb4ddb223..eb0b099048 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -884,6 +884,12 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
MadeChange = getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
MadeChange |= UpdateNodeType(MVT::isVoid, TP);
return MadeChange;
+ } else if (getOperator()->getName() == "COPY_TO_SUBCLASS") {
+ bool MadeChange = false;
+ MadeChange |= getChild(0)->ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= getChild(1)->ApplyTypeConstraints(TP, NotRegisters);
+ MadeChange |= UpdateNodeType(getChild(1)->getTypeNum(0), TP);
+ return MadeChange;
} else if (const CodeGenIntrinsic *Int = getIntrinsicInfo(CDP)) {
bool MadeChange = false;
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 9ef64d66b5..c5d4c494c0 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -344,7 +344,12 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
if (I == Instructions.end())
throw "Could not find 'SUBREG_TO_REG' instruction!";
const CodeGenInstruction *SUBREG_TO_REG = &I->second;
-
+
+ I = getInstructions().find("COPY_TO_SUBCLASS");
+ if (I == Instructions.end())
+ throw "Could not find 'COPY_TO_SUBCLASS' instruction!";
+ const CodeGenInstruction *COPY_TO_SUBCLASS = &I->second;
+
// Print out the rest of the instructions now.
NumberedInstructions.push_back(PHI);
NumberedInstructions.push_back(INLINEASM);
@@ -356,6 +361,7 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
NumberedInstructions.push_back(INSERT_SUBREG);
NumberedInstructions.push_back(IMPLICIT_DEF);
NumberedInstructions.push_back(SUBREG_TO_REG);
+ NumberedInstructions.push_back(COPY_TO_SUBCLASS);
for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II)
if (&II->second != PHI &&
&II->second != INLINEASM &&
@@ -366,7 +372,8 @@ getInstructionsByEnumValue(std::vector<const CodeGenInstruction*>
&II->second != EXTRACT_SUBREG &&
&II->second != INSERT_SUBREG &&
&II->second != IMPLICIT_DEF &&
- &II->second != SUBREG_TO_REG)
+ &II->second != SUBREG_TO_REG &&
+ &II->second != COPY_TO_SUBCLASS)
NumberedInstructions.push_back(&II->second);
}
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 63912a1e4e..3335d00f72 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -918,6 +918,15 @@ public:
getEnumName(N->getTypeNum(0)) + ");");
NodeOps.push_back("Tmp" + utostr(ResNo));
return NodeOps;
+ } else if (DI->getDef()->isSubClassOf("RegisterClass")) {
+ // Handle a reference to a register class. This is used
+ // in COPY_TO_SUBREG instructions.
+ emitCode("SDValue Tmp" + utostr(ResNo) +
+ " = CurDAG->getTargetConstant(" +
+ getQualifiedName(DI->getDef()) + "RegClassID, " +
+ "MVT::i32);");
+ NodeOps.push_back("Tmp" + utostr(ResNo));
+ return NodeOps;
}
} else if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
unsigned ResNo = TmpNo++;
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 6201690b10..1a32828e7d 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -340,7 +340,8 @@ void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
R->getName() != "EXTRACT_SUBREG" &&
R->getName() != "INSERT_SUBREG" &&
R->getName() != "IMPLICIT_DEF" &&
- R->getName() != "SUBREG_TO_REG")
+ R->getName() != "SUBREG_TO_REG" &&
+ R->getName() != "COPY_TO_SUBCLASS")
throw R->getName() + " doesn't have a field named '" +
Val->getValue() + "'!";
return;
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index d45f565e25..3c3b2e8ff4 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -240,8 +240,85 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
<< RegisterClasses[i].getName() << "RegClass;\n";
std::map<unsigned, std::set<unsigned> > SuperClassMap;
+ std::map<unsigned, std::set<unsigned> > SuperRegClassMap;
OS << "\n";
+ // Emit the sub-register classes for each RegisterClass
+ for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+ const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+ // Give the register class a legal C name if it's anonymous.
+ std::string Name = RC.TheDef->getName();
+
+ OS << " // " << Name
+ << " Sub-register Classes...\n"
+ << " static const TargetRegisterClass* const "
+ << Name << "SubRegClasses [] = {\n ";
+
+ bool Empty = true;
+
+ for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size();
+ subrc != subrcMax; ++subrc) {
+ unsigned rc2 = 0, e2 = RegisterClasses.size();
+ for (; rc2 != e2; ++rc2) {
+ const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
+ if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
+ if (!Empty)
+ OS << ", ";
+ OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+ Empty = false;
+
+ std::map<unsigned, std::set<unsigned> >::iterator SCMI =
+ SuperRegClassMap.find(rc2);
+ if (SCMI == SuperRegClassMap.end()) {
+ SuperRegClassMap.insert(std::make_pair(rc2,
+ std::set<unsigned>()));
+ SCMI = SuperRegClassMap.find(rc2);
+ }
+ SCMI->second.insert(rc);
+ break;
+ }
+ }
+ if (rc2 == e2)
+ throw "Register Class member '" +
+ RC.SubRegClasses[subrc]->getName() +
+ "' is not a valid RegisterClass!";
+ }
+
+ OS << (!Empty ? ", " : "") << "NULL";
+ OS << "\n };\n\n";
+ }
+
+ // Emit the super-register classes for each RegisterClass
+ for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+ const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+ // Give the register class a legal C name if it's anonymous.
+ std::string Name = RC.TheDef->getName();
+
+ OS << " // " << Name
+ << " Super-register Classes...\n"
+ << " static const TargetRegisterClass* const "
+ << Name << "SuperRegClasses [] = {\n ";
+
+ bool Empty = true;
+ std::map<unsigned, std::set<unsigned> >::iterator I =
+ SuperRegClassMap.find(rc);
+ if (I != SuperRegClassMap.end()) {
+ for (std::set<unsigned>::iterator II = I->second.begin(),
+ EE = I->second.end(); II != EE; ++II) {
+ const CodeGenRegisterClass &RC2 = RegisterClasses[*II];
+ if (!Empty)
+ OS << ", ";
+ OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+ Empty = false;
+ }
+ }
+
+ OS << (!Empty ? ", " : "") << "NULL";
+ OS << "\n };\n\n";
+ }
+
// Emit the sub-classes array for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
@@ -323,6 +400,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
<< RC.getName() + "VTs" << ", "
<< RC.getName() + "Subclasses" << ", "
<< RC.getName() + "Superclasses" << ", "
+ << RC.getName() + "SubRegClasses" << ", "
+ << RC.getName() + "SuperRegClasses" << ", "
<< RC.SpillSize/8 << ", "
<< RC.SpillAlignment/8 << ", "
<< RC.CopyCost << ", "