blob: b341f6f760cc58b402445881e33883e59a2701fb [file] [log] [blame]
Jim Laskey4bb9cbb2005-10-21 19:00:04 +00001//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend emits subtarget enumerations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SubtargetEmitter.h"
15#include "CodeGenTarget.h"
16#include "Record.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/Support/Debug.h"
Jeff Cohen9489c042005-10-28 01:43:09 +000019#include <algorithm>
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000020using namespace llvm;
21
Jim Laskey7dc02042005-10-22 07:59:56 +000022//
23// Convenience types.
24//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000025typedef std::vector<Record*> RecordList;
Jim Laskey0d841e02005-10-27 19:47:21 +000026
Jim Laskey908ae272005-10-28 15:20:43 +000027//
28// RecordListIter - Simplify iterating through a std::vector of records.
29//
30class RecordListIter {
31 std::vector<Record*>::iterator RI; // Currect cursor
32 std::vector<Record*>::iterator E; // End point
33
34public:
Jim Laskey0d841e02005-10-27 19:47:21 +000035
Jim Laskey908ae272005-10-28 15:20:43 +000036 //
37 // Ctor.
38 //
Jim Laskey0d841e02005-10-27 19:47:21 +000039 RecordListIter(RecordList &RL)
40 : RI(RL.begin()), E(RL.end())
41 {}
42
Jim Laskey908ae272005-10-28 15:20:43 +000043
44 //
45 // isMore - Return true if more records are available.
46 //
Jim Laskey0d841e02005-10-27 19:47:21 +000047 bool isMore() const { return RI != E; }
48
Jim Laskey908ae272005-10-28 15:20:43 +000049 //
50 // next - Return the next record or NULL if none.
51 //
Jim Laskey0d841e02005-10-27 19:47:21 +000052 Record *next() { return isMore() ? *RI++ : NULL; }
53};
54
Jim Laskey908ae272005-10-28 15:20:43 +000055//
56// DefListIter - Simplify iterating through a field which is a list of records.
57//
Jim Laskey0d841e02005-10-27 19:47:21 +000058struct DefListIter {
Jim Laskey908ae272005-10-28 15:20:43 +000059 ListInit *List; // List of DefInit
60 unsigned N; // Number of elements in list
61 unsigned i; // Current index in list
Jim Laskey0d841e02005-10-27 19:47:21 +000062
Jim Laskey908ae272005-10-28 15:20:43 +000063 //
64 // Ctor - Lookup field and get list and length.
65 //
Jim Laskey0d841e02005-10-27 19:47:21 +000066 DefListIter(Record *R, const std::string &Name)
67 : List(R->getValueAsListInit(Name)), N(List->getSize()), i(0)
68 {}
69
Jim Laskey908ae272005-10-28 15:20:43 +000070 //
71 // isMore - Return true if more records are available.
72 //
Jim Laskey0d841e02005-10-27 19:47:21 +000073 bool isMore() const { return i < N; }
74
Jim Laskey908ae272005-10-28 15:20:43 +000075 //
76 // next - Return the next record or NULL if none.
77 //
Jim Laskey0d841e02005-10-27 19:47:21 +000078 Record *next() {
79 if (isMore()) {
80 if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i++))) {
81 return DI->getDef();
82 }
83 }
84 return NULL;
85 }
86};
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000087
Jim Laskey7dc02042005-10-22 07:59:56 +000088//
89// Record sort by name function.
90//
91struct LessRecord {
92 bool operator()(const Record *Rec1, const Record *Rec2) const {
93 return Rec1->getName() < Rec2->getName();
94 }
95};
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000096
Jim Laskey7dc02042005-10-22 07:59:56 +000097//
98// Record sort by field "Name" function.
99//
100struct LessRecordFieldName {
101 bool operator()(const Record *Rec1, const Record *Rec2) const {
102 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
103 }
104};
105
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000106//
Jim Laskey581a8f72005-10-26 17:30:34 +0000107// Enumeration - Emit the specified class as an enumeration.
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000108//
Jim Laskey581a8f72005-10-26 17:30:34 +0000109void SubtargetEmitter::Enumeration(std::ostream &OS,
110 const char *ClassName,
111 bool isBits) {
Jim Laskey908ae272005-10-28 15:20:43 +0000112 // Get all records of class and sort
Jim Laskey581a8f72005-10-26 17:30:34 +0000113 RecordList Defs = Records.getAllDerivedDefinitions(ClassName);
114 sort(Defs.begin(), Defs.end(), LessRecord());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000115
Jim Laskey908ae272005-10-28 15:20:43 +0000116 // Track position if isBits
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000117 int i = 0;
118
Jim Laskey908ae272005-10-28 15:20:43 +0000119 // Open enumeration
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000120 OS << "enum {\n";
121
Jim Laskey908ae272005-10-28 15:20:43 +0000122 // For each record
Jim Laskey0d841e02005-10-27 19:47:21 +0000123 RecordListIter DI(Defs);
124 while (Record *R = DI.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000125 // Get and emit name
126 std::string Name = R->getName();
127 OS << " " << Name;
128
129 // If bit flags then emit expression (1 << i)
130 if (isBits) OS << " = " << " 1 << " << i++;
131
132 // Depending on if more in the list, emit comma and new line
Jim Laskey0d841e02005-10-27 19:47:21 +0000133 OS << (DI.isMore() ? ",\n" : "\n");
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000134 }
135
Jim Laskey908ae272005-10-28 15:20:43 +0000136 // Close enumeration
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000137 OS << "};\n";
138}
139
140//
141// FeatureKeyValues - Emit data of all the subtarget features. Used by command
142// line.
143//
144void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +0000145 // Gather and sort all the features
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000146 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
147 sort(Features.begin(), Features.end(), LessRecord());
148
Jim Laskey908ae272005-10-28 15:20:43 +0000149 // Begin feature table
Jim Laskey581a8f72005-10-26 17:30:34 +0000150 OS << "// Sorted (by key) array of values for CPU features.\n"
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000151 << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
Jim Laskey908ae272005-10-28 15:20:43 +0000152
153 // For each feature
Jim Laskey0d841e02005-10-27 19:47:21 +0000154 RecordListIter FI(Features);
155 while (Record *R = FI.next()) {
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000156 std::string Instance = R->getName();
157 std::string Name = R->getValueAsString("Name");
158 std::string Desc = R->getValueAsString("Desc");
Jim Laskey908ae272005-10-28 15:20:43 +0000159
160 // Emit as { "feature", "decription", feactureEnum }
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000161 OS << " { "
162 << "\"" << Name << "\", "
163 << "\"" << Desc << "\", "
164 << Instance
Jim Laskey0d841e02005-10-27 19:47:21 +0000165 << (FI.isMore() ? " },\n" : " }\n");
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000166 }
Jim Laskey908ae272005-10-28 15:20:43 +0000167
168 // End feature table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000169 OS << "};\n";
170
Jim Laskey908ae272005-10-28 15:20:43 +0000171 // Emit size of table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000172 OS<<"\nenum {\n";
173 OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
174 OS<<"};\n";
175}
176
177//
178// CPUKeyValues - Emit data of all the subtarget processors. Used by command
179// line.
180//
181void SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +0000182 // Gather and sort processor information
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000183 RecordList Processors = Records.getAllDerivedDefinitions("Processor");
184 sort(Processors.begin(), Processors.end(), LessRecordFieldName());
185
Jim Laskey908ae272005-10-28 15:20:43 +0000186 // Begin processor table
Jim Laskey581a8f72005-10-26 17:30:34 +0000187 OS << "// Sorted (by key) array of values for CPU subtype.\n"
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000188 << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
Jim Laskey908ae272005-10-28 15:20:43 +0000189
190 // For each processor
Jim Laskey0d841e02005-10-27 19:47:21 +0000191 RecordListIter PI(Processors);
192 while (Record *R = PI.next()) {
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000193 std::string Name = R->getValueAsString("Name");
Jim Laskey0d841e02005-10-27 19:47:21 +0000194 DefListIter FI(R, "Features");
195
Jim Laskey908ae272005-10-28 15:20:43 +0000196 // Emit as { "cpu", "description", f1 | f2 | ... fn },
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000197 OS << " { "
198 << "\"" << Name << "\", "
199 << "\"Select the " << Name << " processor\", ";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000200
Jim Laskey0d841e02005-10-27 19:47:21 +0000201 if (!FI.isMore()) {
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000202 OS << "0";
203 } else {
Jim Laskey0d841e02005-10-27 19:47:21 +0000204 while (Record *Feature = FI.next()) {
205 std::string Name = Feature->getName();
206 OS << Name;
207 if (FI.isMore()) OS << " | ";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000208 }
209 }
210
Jim Laskey0d841e02005-10-27 19:47:21 +0000211 OS << (PI.isMore() ? " },\n" : " }\n");
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000212 }
Jim Laskey908ae272005-10-28 15:20:43 +0000213
214 // End processor table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000215 OS << "};\n";
216
Jim Laskey908ae272005-10-28 15:20:43 +0000217 // Emit size of table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000218 OS<<"\nenum {\n";
219 OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
220 OS<<"};\n";
221}
Jim Laskey7dc02042005-10-22 07:59:56 +0000222
Jim Laskey581a8f72005-10-26 17:30:34 +0000223//
Jim Laskey0d841e02005-10-27 19:47:21 +0000224// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
Jim Laskey908ae272005-10-28 15:20:43 +0000225// Returns itinerary class count.
Jim Laskey0d841e02005-10-27 19:47:21 +0000226//
227unsigned SubtargetEmitter::CollectAllItinClasses(IntMap &ItinClassesMap) {
Jim Laskey908ae272005-10-28 15:20:43 +0000228 // Gather and sort all itinerary classes
Jim Laskey0d841e02005-10-27 19:47:21 +0000229 RecordList ICL = Records.getAllDerivedDefinitions("InstrItinClass");
230 sort(ICL.begin(), ICL.end(), LessRecord());
Jim Laskey908ae272005-10-28 15:20:43 +0000231
232 // Track enumeration
Jim Laskey0d841e02005-10-27 19:47:21 +0000233 unsigned Index = 0;
Jim Laskey908ae272005-10-28 15:20:43 +0000234
235 // For each class
236 RecordListIter ICI(ICL);
Jim Laskey0d841e02005-10-27 19:47:21 +0000237 while (Record *ItinClass = ICI.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000238 // Get name of itinerary class
Jim Laskey0d841e02005-10-27 19:47:21 +0000239 std::string Name = ItinClass->getName();
Jim Laskey908ae272005-10-28 15:20:43 +0000240 // Assign itinerary class a unique number
Jim Laskey0d841e02005-10-27 19:47:21 +0000241 ItinClassesMap[Name] = Index++;
242 }
243
Jim Laskey908ae272005-10-28 15:20:43 +0000244 // Return itinerary class count
Jim Laskey0d841e02005-10-27 19:47:21 +0000245 return Index;
246}
247
248//
249// FormItineraryString - Compose a string containing the data initialization
250// for the specified itinerary. N is the number of stages.
251//
252void SubtargetEmitter::FormItineraryString(Record *ItinData,
253 std::string &ItinString,
254 unsigned &N) {
Jim Laskey908ae272005-10-28 15:20:43 +0000255 // Set up stages iterator
Jim Laskey0d841e02005-10-27 19:47:21 +0000256 DefListIter SLI(ItinData, "Stages");
Jim Laskey908ae272005-10-28 15:20:43 +0000257 // Get stage count
Jim Laskey0d841e02005-10-27 19:47:21 +0000258 N = SLI.N;
Jim Laskey908ae272005-10-28 15:20:43 +0000259
260 // For each stage
Jim Laskey0d841e02005-10-27 19:47:21 +0000261 while (Record *Stage = SLI.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000262 // Form string as ,{ cycles, u1 | u2 | ... | un }
Jim Laskey0d841e02005-10-27 19:47:21 +0000263 int Cycles = Stage->getValueAsInt("Cycles");
264 ItinString += " ,{ " + itostr(Cycles) + ", ";
265
Jim Laskey908ae272005-10-28 15:20:43 +0000266 // For each unit
Jim Laskey0d841e02005-10-27 19:47:21 +0000267 DefListIter ULI(Stage, "Units");
268 while (Record *Unit = ULI.next()) {
269 std::string Name = Unit->getName();
270 ItinString += Name;
271 if (ULI.isMore())ItinString += " | ";
272 }
Jim Laskey908ae272005-10-28 15:20:43 +0000273
274 // Close off stage
275 ItinString += " }";
Jim Laskey0d841e02005-10-27 19:47:21 +0000276 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000277}
278
279//
280// EmitStageData - Generate unique itinerary stages. Record itineraries for
281// processors.
282//
283void SubtargetEmitter::EmitStageData(std::ostream &OS,
284 unsigned N,
285 IntMap &ItinClassesMap,
286 ProcessorList &ProcList) {
Jim Laskey908ae272005-10-28 15:20:43 +0000287 // Gather processor iteraries
288 RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries");
289
290 // If just no itinerary then don't bother
291 if (Itins.size() < 2) return;
292
293 // Begin stages table
Jim Laskey0d841e02005-10-27 19:47:21 +0000294 OS << "static llvm::InstrStage Stages[] = {\n"
295 " { 0, 0 } // No itinerary\n";
296
297 IntMap ItinMap;
298 unsigned Index = 1;
Jim Laskey0d841e02005-10-27 19:47:21 +0000299 RecordListIter II(Itins);
300 while (Record *Itin = II.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000301 // Get processor itinerary name
Jim Laskey0d841e02005-10-27 19:47:21 +0000302 std::string Name = Itin->getName();
Jim Laskey908ae272005-10-28 15:20:43 +0000303
304 // Skip default
Jim Laskey0d841e02005-10-27 19:47:21 +0000305 if (Name == "NoItineraries") continue;
306
Jim Laskey908ae272005-10-28 15:20:43 +0000307 // Create and expand processor itinerary to cover all itinerary classes
Jim Laskey0d841e02005-10-27 19:47:21 +0000308 IntineraryList IL;
309 IL.resize(N);
310
Jim Laskey908ae272005-10-28 15:20:43 +0000311 // For each itinerary
Jim Laskey0d841e02005-10-27 19:47:21 +0000312 DefListIter IDLI(Itin, "IID");
313 while (Record *ItinData = IDLI.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000314 // Get string and stage count
Jim Laskey0d841e02005-10-27 19:47:21 +0000315 std::string ItinString;
316 unsigned M;
317 FormItineraryString(ItinData, ItinString, M);
318
Jim Laskey908ae272005-10-28 15:20:43 +0000319 // Check to see if it already exists
Jim Laskey0d841e02005-10-27 19:47:21 +0000320 unsigned Find = ItinMap[ItinString];
321
Jim Laskey908ae272005-10-28 15:20:43 +0000322 // If new itinerary
Jim Laskey0d841e02005-10-27 19:47:21 +0000323 if (Find == 0) {
Jim Laskey908ae272005-10-28 15:20:43 +0000324 // Emit as ,{ cycles, u1 | u2 | ... | un } // index
Jim Laskey0d841e02005-10-27 19:47:21 +0000325 OS << ItinString << " // " << Index << "\n";
326 ItinMap[ItinString] = Find = Index++;
327 }
328
Jim Laskey908ae272005-10-28 15:20:43 +0000329 // Set up itinerary as location and location + stage count
Jim Laskey0d841e02005-10-27 19:47:21 +0000330 InstrItinerary Intinerary = { Find, Find + M };
331
Jim Laskey908ae272005-10-28 15:20:43 +0000332 // Locate where to inject into processor itinerary table
Jim Laskey0d841e02005-10-27 19:47:21 +0000333 std::string Name = ItinData->getValueAsDef("TheClass")->getName();
334 Find = ItinClassesMap[Name];
Jim Laskey908ae272005-10-28 15:20:43 +0000335
336 // Inject - empty slots will be 0, 0
Jim Laskey0d841e02005-10-27 19:47:21 +0000337 IL[Find] = Intinerary;
338 }
339
Jim Laskey908ae272005-10-28 15:20:43 +0000340 // Add process itinerary to list
Jim Laskey0d841e02005-10-27 19:47:21 +0000341 ProcList.push_back(IL);
342 }
343
Jim Laskey908ae272005-10-28 15:20:43 +0000344 // End stages table
Jim Laskey0d841e02005-10-27 19:47:21 +0000345 OS << "};\n";
346}
347
348//
349// EmitProcessData - Generate data for processor itineraries.
350//
351void SubtargetEmitter::EmitProcessData(std::ostream &OS,
352 ProcessorList &ProcList) {
Jim Laskey908ae272005-10-28 15:20:43 +0000353 // Get an iterator for processor itinerary stages
Jim Laskey0d841e02005-10-27 19:47:21 +0000354 ProcessorList::iterator PLI = ProcList.begin();
Jim Laskey908ae272005-10-28 15:20:43 +0000355
356 // For each processor itinerary
Jim Laskey0d841e02005-10-27 19:47:21 +0000357 RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries");
358 RecordListIter II(Itins);
359 while (Record *Itin = II.next()) {
Jim Laskey908ae272005-10-28 15:20:43 +0000360 // Get processor itinerary name
Jim Laskey0d841e02005-10-27 19:47:21 +0000361 std::string Name = Itin->getName();
Jim Laskey908ae272005-10-28 15:20:43 +0000362
363 // Skip default
Jim Laskey0d841e02005-10-27 19:47:21 +0000364 if (Name == "NoItineraries") continue;
365
Jim Laskey908ae272005-10-28 15:20:43 +0000366 // Begin processor itinerary table
Jim Laskey0d841e02005-10-27 19:47:21 +0000367 OS << "\n";
368 OS << "static llvm::InstrItinerary " << Name << "[] = {\n";
369
Jim Laskey908ae272005-10-28 15:20:43 +0000370 // For each itinerary class
Jim Laskey0d841e02005-10-27 19:47:21 +0000371 IntineraryList &IL = *PLI++;
372 unsigned Index = 0;
373 for (IntineraryList::iterator ILI = IL.begin(), E = IL.end(); ILI != E;) {
374 InstrItinerary &Intinerary = *ILI++;
375
Jim Laskey908ae272005-10-28 15:20:43 +0000376 // Emit in the form of { first, last } // index
Jim Laskey0d841e02005-10-27 19:47:21 +0000377 if (Intinerary.First == 0) {
378 OS << " { 0, 0 }";
379 } else {
380 OS << " { " << Intinerary.First << ", " << Intinerary.Last << " }";
381 }
382
383 if (ILI != E) OS << ",";
384 OS << " // " << Index++ << "\n";
385 }
Jim Laskey908ae272005-10-28 15:20:43 +0000386
387 // End processor itinerary table
Jim Laskey0d841e02005-10-27 19:47:21 +0000388 OS << "};\n";
389 }
390}
391
392//
393// EmitData - Emits all stages and itineries, folding common patterns.
394//
395void SubtargetEmitter::EmitData(std::ostream &OS) {
396 IntMap ItinClassesMap;
397 ProcessorList ProcList;
398
Jim Laskey908ae272005-10-28 15:20:43 +0000399 // Enumerate all the itinerary classes
Jim Laskey0d841e02005-10-27 19:47:21 +0000400 unsigned N = CollectAllItinClasses(ItinClassesMap);
Jim Laskey908ae272005-10-28 15:20:43 +0000401 // Emit the stage data
Jim Laskey0d841e02005-10-27 19:47:21 +0000402 EmitStageData(OS, N, ItinClassesMap, ProcList);
Jim Laskey908ae272005-10-28 15:20:43 +0000403 // Emit the processor itinerary data
Jim Laskey0d841e02005-10-27 19:47:21 +0000404 EmitProcessData(OS, ProcList);
405}
406
407//
Jim Laskey581a8f72005-10-26 17:30:34 +0000408// ParseFeaturesFunction - Produces a subtarget specific function for parsing
409// the subtarget features string.
410//
411void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
412 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
413 sort(Features.begin(), Features.end(), LessRecord());
414
415 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
416 "// subtarget options.\n"
417 "void llvm::";
418 OS << Target;
419 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
420 " const std::string &CPU) {\n"
421 " SubtargetFeatures Features(FS);\n"
422 " Features.setCPUIfNone(CPU);\n"
423 " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
424 " FeatureKV, FeatureKVSize);\n";
425
Jim Laskey0d841e02005-10-27 19:47:21 +0000426 RecordListIter FI(Features);
427 while (Record *R = FI.next()) {
Jim Laskey581a8f72005-10-26 17:30:34 +0000428 std::string Instance = R->getName();
429 std::string Name = R->getValueAsString("Name");
430 std::string Type = R->getValueAsString("Type");
431 std::string Attribute = R->getValueAsString("Attribute");
432
433 OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
434 }
435 OS << "}\n";
436}
437
Jim Laskey7dc02042005-10-22 07:59:56 +0000438//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000439// SubtargetEmitter::run - Main subtarget enumeration emitter.
440//
441void SubtargetEmitter::run(std::ostream &OS) {
Jim Laskey6c302fc2005-10-26 17:49:21 +0000442 Target = CodeGenTarget().getName();
Jim Laskey581a8f72005-10-26 17:30:34 +0000443
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000444 EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000445
Jim Laskey0d841e02005-10-27 19:47:21 +0000446 OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
447 OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000448
Jim Laskey581a8f72005-10-26 17:30:34 +0000449 Enumeration(OS, "FuncUnit", true);
450 OS<<"\n";
Jim Laskey908ae272005-10-28 15:20:43 +0000451// Enumeration(OS, "InstrItinClass", false);
452// OS<<"\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000453 Enumeration(OS, "SubtargetFeature", true);
454 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000455 FeatureKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000456 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000457 CPUKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000458 OS<<"\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000459 EmitData(OS);
460 OS<<"\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000461 ParseFeaturesFunction(OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000462}