1 //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by James M. Laskey and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This tablegen backend emits subtarget enumerations.
12 //===----------------------------------------------------------------------===//
14 #include "SubtargetEmitter.h"
15 #include "CodeGenTarget.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Debug.h"
26 typedef std::vector<Record*> RecordList;
27 typedef std::vector<Record*>::iterator RecordListIter;
30 // Record sort by name function.
33 bool operator()(const Record *Rec1, const Record *Rec2) const {
34 return Rec1->getName() < Rec2->getName();
39 // Record sort by field "Name" function.
41 struct LessRecordFieldName {
42 bool operator()(const Record *Rec1, const Record *Rec2) const {
43 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
48 // Enumeration - Emit the specified class as an enumeration.
50 void SubtargetEmitter::Enumeration(std::ostream &OS,
51 const char *ClassName,
53 RecordList Defs = Records.getAllDerivedDefinitions(ClassName);
54 sort(Defs.begin(), Defs.end(), LessRecord());
60 for (RecordListIter RI = Defs.begin(), E = Defs.end(); RI != E;) {
62 std::string Instance = R->getName();
69 OS << ((RI != E) ? ",\n" : "\n");
76 // FeatureKeyValues - Emit data of all the subtarget features. Used by command
79 void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
80 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
81 sort(Features.begin(), Features.end(), LessRecord());
83 OS << "// Sorted (by key) array of values for CPU features.\n"
84 << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
85 for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;) {
87 std::string Instance = R->getName();
88 std::string Name = R->getValueAsString("Name");
89 std::string Desc = R->getValueAsString("Desc");
91 << "\"" << Name << "\", "
92 << "\"" << Desc << "\", "
94 << ((RI != E) ? " },\n" : " }\n");
99 OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
104 // CPUKeyValues - Emit data of all the subtarget processors. Used by command
107 void SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
108 RecordList Processors = Records.getAllDerivedDefinitions("Processor");
109 sort(Processors.begin(), Processors.end(), LessRecordFieldName());
111 OS << "// Sorted (by key) array of values for CPU subtype.\n"
112 << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
113 for (RecordListIter RI = Processors.begin(), E = Processors.end();
116 std::string Name = R->getValueAsString("Name");
117 Record *ProcItin = R->getValueAsDef("ProcItin");
118 ListInit *Features = R->getValueAsListInit("Features");
119 unsigned N = Features->getSize();
121 << "\"" << Name << "\", "
122 << "\"Select the " << Name << " processor\", ";
128 for (unsigned i = 0; i < N; ) {
129 if (DefInit *DI = dynamic_cast<DefInit*>(Features->getElement(i++))) {
130 Record *Feature = DI->getDef();
131 std::string Name = Feature->getName();
133 if (i != N) OS << " | ";
135 throw "Feature: " + Name +
136 " expected feature in processor feature list!";
141 OS << ((RI != E) ? " },\n" : " }\n");
146 OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
151 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
152 // the subtarget features string.
154 void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
155 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
156 sort(Features.begin(), Features.end(), LessRecord());
158 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
159 "// subtarget options.\n"
162 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
163 " const std::string &CPU) {\n"
164 " SubtargetFeatures Features(FS);\n"
165 " Features.setCPUIfNone(CPU);\n"
166 " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
167 " FeatureKV, FeatureKVSize);\n";
169 for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;) {
171 std::string Instance = R->getName();
172 std::string Name = R->getValueAsString("Name");
173 std::string Type = R->getValueAsString("Type");
174 std::string Attribute = R->getValueAsString("Attribute");
176 OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
182 // SubtargetEmitter::run - Main subtarget enumeration emitter.
184 void SubtargetEmitter::run(std::ostream &OS) {
185 std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
186 if (Targets.size() == 0)
187 throw std::string("ERROR: No 'Target' subclasses defined!");
188 if (Targets.size() != 1)
189 throw std::string("ERROR: Multiple subclasses of Target defined!");
190 Target = Targets[0]->getName();
192 EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
194 OS << "#include \"llvm/Target/SubtargetFeature.h\"\n\n";
196 Enumeration(OS, "FuncUnit", true);
198 Enumeration(OS, "InstrItinClass", false);
200 Enumeration(OS, "SubtargetFeature", true);
202 FeatureKeyValues(OS);
206 ParseFeaturesFunction(OS);