summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-03-21 08:31:53 +0000
committerBill Wendling <isanbard@gmail.com>2011-03-21 08:31:53 +0000
commit2cf6fc6857a3544e56f1e701e826114906b1cc57 (patch)
tree5882c341b7514f7d3245fcd0f53c17fe5339aa4b /utils
parenta5c177e70a42f48e4885075c4c48aad0816a2817 (diff)
downloadllvm-2cf6fc6857a3544e56f1e701e826114906b1cc57.tar.gz
llvm-2cf6fc6857a3544e56f1e701e826114906b1cc57.tar.bz2
llvm-2cf6fc6857a3544e56f1e701e826114906b1cc57.tar.xz
* Add classes that support the "feature" information.
* Move the code that emits the reg in reg class matching into its own function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp124
-rw-r--r--utils/TableGen/AsmWriterEmitter.h1
2 files changed, 120 insertions, 5 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index cd31e0c344..1bf7f3ed6c 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -542,12 +542,116 @@ void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) {
<< "}\n\n#endif\n";
}
-void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
- CodeGenTarget Target(Records);
- Record *AsmWriter = Target.getAsmWriter();
+namespace {
- O << "\n#ifdef PRINT_ALIAS_INSTR\n";
- O << "#undef PRINT_ALIAS_INSTR\n\n";
+/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
+/// feature which participates in instruction matching.
+struct SubtargetFeatureInfo {
+ /// \brief The predicate record for this feature.
+ const Record *TheDef;
+
+ /// \brief An unique index assigned to represent this feature.
+ unsigned Index;
+
+ SubtargetFeatureInfo(const Record *D, unsigned Idx) : TheDef(D), Index(Idx) {}
+
+ /// \brief The name of the enumerated constant identifying this feature.
+ std::string getEnumName() const {
+ return "Feature_" + TheDef->getName();
+ }
+};
+
+struct AsmWriterInfo {
+ /// Map of Predicate records to their subtarget information.
+ std::map<const Record*, SubtargetFeatureInfo*> SubtargetFeatures;
+
+ /// getSubtargetFeature - Lookup or create the subtarget feature info for the
+ /// given operand.
+ SubtargetFeatureInfo *getSubtargetFeature(const Record *Def) const {
+ assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
+ std::map<const Record*, SubtargetFeatureInfo*>::const_iterator I =
+ SubtargetFeatures.find(Def);
+ return I == SubtargetFeatures.end() ? 0 : I->second;
+ }
+
+ void addReqFeatures(const std::vector<Record*> &Features) {
+ for (std::vector<Record*>::const_iterator
+ I = Features.begin(), E = Features.end(); I != E; ++I) {
+ const Record *Pred = *I;
+
+ // Ignore predicates that are not intended for the assembler.
+ if (!Pred->getValueAsBit("AssemblerMatcherPredicate"))
+ continue;
+
+ if (Pred->getName().empty())
+ throw TGError(Pred->getLoc(), "Predicate has no name!");
+
+ // Don't add the predicate again.
+ if (getSubtargetFeature(Pred))
+ continue;
+
+ unsigned FeatureNo = SubtargetFeatures.size();
+ SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo);
+ assert(FeatureNo < 32 && "Too many subtarget features!");
+ }
+ }
+
+ const SubtargetFeatureInfo *getFeatureInfo(const Record *R) {
+ return SubtargetFeatures[R];
+ }
+};
+
+} // end anonymous namespace
+
+/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
+/// definitions.
+static void EmitSubtargetFeatureFlagEnumeration(AsmWriterInfo &Info,
+ raw_ostream &O) {
+ O << "namespace {\n\n";
+ O << "// Flags for subtarget features that participate in "
+ << "alias instruction matching.\n";
+ O << "enum SubtargetFeatureFlag {\n";
+
+ for (std::map<const Record*, SubtargetFeatureInfo*>::const_iterator
+ I = Info.SubtargetFeatures.begin(),
+ E = Info.SubtargetFeatures.end(); I != E; ++I) {
+ SubtargetFeatureInfo &SFI = *I->second;
+ O << " " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n";
+ }
+
+ O << " Feature_None = 0\n";
+ O << "};\n\n";
+ O << "} // end anonymous namespace\n";
+}
+
+/// EmitComputeAvailableFeatures - Emit the function to compute the list of
+/// available features given a subtarget.
+static void EmitComputeAvailableFeatures(AsmWriterInfo &Info,
+ Record *AsmWriter,
+ CodeGenTarget &Target,
+ raw_ostream &O) {
+ std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+
+ O << "unsigned " << Target.getName() << ClassName << "::\n"
+ << "ComputeAvailableFeatures(const " << Target.getName()
+ << "Subtarget *Subtarget) const {\n";
+ O << " unsigned Features = 0;\n";
+
+ for (std::map<const Record*, SubtargetFeatureInfo*>::const_iterator
+ I = Info.SubtargetFeatures.begin(),
+ E = Info.SubtargetFeatures.end(); I != E; ++I) {
+ SubtargetFeatureInfo &SFI = *I->second;
+ O << " if (" << SFI.TheDef->getValueAsString("CondString")
+ << ")\n";
+ O << " Features |= " << SFI.getEnumName() << ";\n";
+ }
+
+ O << " return Features;\n";
+ O << "}\n\n";
+}
+
+void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) {
+ CodeGenTarget Target(Records);
// Enumerate the register classes.
const std::vector<CodeGenRegisterClass> &RegisterClasses =
@@ -606,6 +710,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " }\n\n";
O << " return false;\n";
O << "}\n\n";
+}
+
+void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
+ CodeGenTarget Target(Records);
+ Record *AsmWriter = Target.getAsmWriter();
+
+ O << "\n#ifdef PRINT_ALIAS_INSTR\n";
+ O << "#undef PRINT_ALIAS_INSTR\n\n";
+
+ EmitRegIsInRegClass(O);
// Emit the method that prints the alias instruction.
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h
index 5e8d6f5b7f..84c925b66e 100644
--- a/utils/TableGen/AsmWriterEmitter.h
+++ b/utils/TableGen/AsmWriterEmitter.h
@@ -38,6 +38,7 @@ private:
void EmitPrintInstruction(raw_ostream &o);
void EmitGetRegisterName(raw_ostream &o);
void EmitGetInstructionName(raw_ostream &o);
+ void EmitRegIsInRegClass(raw_ostream &O);
void EmitPrintAliasInstruction(raw_ostream &O);
AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {