I'm introducing a new machine model to simultaneously allow simple
[oota-llvm.git] / utils / TableGen / SubtargetEmitter.cpp
1 //===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This tablegen backend emits subtarget enumerations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CodeGenTarget.h"
15 #include "CodeGenSchedule.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/MC/MCInstrItineraries.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/TableGen/Record.h"
20 #include "llvm/TableGen/TableGenBackend.h"
21 #include <algorithm>
22 #include <map>
23 #include <string>
24 #include <vector>
25 using namespace llvm;
26
27 namespace {
28 class SubtargetEmitter {
29
30   RecordKeeper &Records;
31   CodeGenSchedModels &SchedModels;
32   std::string Target;
33
34   void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
35   unsigned FeatureKeyValues(raw_ostream &OS);
36   unsigned CPUKeyValues(raw_ostream &OS);
37   void FormItineraryStageString(const std::string &Names,
38                                 Record *ItinData, std::string &ItinString,
39                                 unsigned &NStages);
40   void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
41                                        unsigned &NOperandCycles);
42   void FormItineraryBypassString(const std::string &Names,
43                                  Record *ItinData,
44                                  std::string &ItinString, unsigned NOperandCycles);
45   void EmitStageAndOperandCycleData(raw_ostream &OS,
46                                     std::vector<std::vector<InstrItinerary> >
47                                       &ProcItinLists);
48   void EmitItineraries(raw_ostream &OS,
49                        std::vector<std::vector<InstrItinerary> >
50                          &ProcItinLists);
51   void EmitProcessorProp(raw_ostream &OS, const Record *R, const char *Name,
52                          char Separator);
53   void EmitProcessorModels(raw_ostream &OS);
54   void EmitProcessorLookup(raw_ostream &OS);
55   void EmitSchedModel(raw_ostream &OS);
56   void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures,
57                              unsigned NumProcs);
58
59 public:
60   SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT):
61     Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {}
62
63   void run(raw_ostream &o);
64
65 };
66 } // End anonymous namespace
67
68 //
69 // Enumeration - Emit the specified class as an enumeration.
70 //
71 void SubtargetEmitter::Enumeration(raw_ostream &OS,
72                                    const char *ClassName,
73                                    bool isBits) {
74   // Get all records of class and sort
75   std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
76   std::sort(DefList.begin(), DefList.end(), LessRecord());
77
78   unsigned N = DefList.size();
79   if (N == 0)
80     return;
81   if (N > 64) {
82     errs() << "Too many (> 64) subtarget features!\n";
83     exit(1);
84   }
85
86   OS << "namespace " << Target << " {\n";
87
88   // For bit flag enumerations with more than 32 items, emit constants.
89   // Emit an enum for everything else.
90   if (isBits && N > 32) {
91     // For each record
92     for (unsigned i = 0; i < N; i++) {
93       // Next record
94       Record *Def = DefList[i];
95
96       // Get and emit name and expression (1 << i)
97       OS << "  const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n";
98     }
99   } else {
100     // Open enumeration
101     OS << "enum {\n";
102
103     // For each record
104     for (unsigned i = 0; i < N;) {
105       // Next record
106       Record *Def = DefList[i];
107
108       // Get and emit name
109       OS << "  " << Def->getName();
110
111       // If bit flags then emit expression (1 << i)
112       if (isBits)  OS << " = " << " 1ULL << " << i;
113
114       // Depending on 'if more in the list' emit comma
115       if (++i < N) OS << ",";
116
117       OS << "\n";
118     }
119
120     // Close enumeration
121     OS << "};\n";
122   }
123
124   OS << "}\n";
125 }
126
127 //
128 // FeatureKeyValues - Emit data of all the subtarget features.  Used by the
129 // command line.
130 //
131 unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
132   // Gather and sort all the features
133   std::vector<Record*> FeatureList =
134                            Records.getAllDerivedDefinitions("SubtargetFeature");
135
136   if (FeatureList.empty())
137     return 0;
138
139   std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
140
141   // Begin feature table
142   OS << "// Sorted (by key) array of values for CPU features.\n"
143      << "extern const llvm::SubtargetFeatureKV " << Target
144      << "FeatureKV[] = {\n";
145
146   // For each feature
147   unsigned NumFeatures = 0;
148   for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
149     // Next feature
150     Record *Feature = FeatureList[i];
151
152     const std::string &Name = Feature->getName();
153     const std::string &CommandLineName = Feature->getValueAsString("Name");
154     const std::string &Desc = Feature->getValueAsString("Desc");
155
156     if (CommandLineName.empty()) continue;
157
158     // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
159     OS << "  { "
160        << "\"" << CommandLineName << "\", "
161        << "\"" << Desc << "\", "
162        << Target << "::" << Name << ", ";
163
164     const std::vector<Record*> &ImpliesList =
165       Feature->getValueAsListOfDefs("Implies");
166
167     if (ImpliesList.empty()) {
168       OS << "0ULL";
169     } else {
170       for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
171         OS << Target << "::" << ImpliesList[j]->getName();
172         if (++j < M) OS << " | ";
173       }
174     }
175
176     OS << " }";
177     ++NumFeatures;
178
179     // Depending on 'if more in the list' emit comma
180     if ((i + 1) < N) OS << ",";
181
182     OS << "\n";
183   }
184
185   // End feature table
186   OS << "};\n";
187
188   return NumFeatures;
189 }
190
191 //
192 // CPUKeyValues - Emit data of all the subtarget processors.  Used by command
193 // line.
194 //
195 unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
196   // Gather and sort processor information
197   std::vector<Record*> ProcessorList =
198                           Records.getAllDerivedDefinitions("Processor");
199   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
200
201   // Begin processor table
202   OS << "// Sorted (by key) array of values for CPU subtype.\n"
203      << "extern const llvm::SubtargetFeatureKV " << Target
204      << "SubTypeKV[] = {\n";
205
206   // For each processor
207   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
208     // Next processor
209     Record *Processor = ProcessorList[i];
210
211     const std::string &Name = Processor->getValueAsString("Name");
212     const std::vector<Record*> &FeatureList =
213       Processor->getValueAsListOfDefs("Features");
214
215     // Emit as { "cpu", "description", f1 | f2 | ... fn },
216     OS << "  { "
217        << "\"" << Name << "\", "
218        << "\"Select the " << Name << " processor\", ";
219
220     if (FeatureList.empty()) {
221       OS << "0ULL";
222     } else {
223       for (unsigned j = 0, M = FeatureList.size(); j < M;) {
224         OS << Target << "::" << FeatureList[j]->getName();
225         if (++j < M) OS << " | ";
226       }
227     }
228
229     // The "0" is for the "implies" section of this data structure.
230     OS << ", 0ULL }";
231
232     // Depending on 'if more in the list' emit comma
233     if (++i < N) OS << ",";
234
235     OS << "\n";
236   }
237
238   // End processor table
239   OS << "};\n";
240
241   return ProcessorList.size();
242 }
243
244 //
245 // FormItineraryStageString - Compose a string containing the stage
246 // data initialization for the specified itinerary.  N is the number
247 // of stages.
248 //
249 void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
250                                                 Record *ItinData,
251                                                 std::string &ItinString,
252                                                 unsigned &NStages) {
253   // Get states list
254   const std::vector<Record*> &StageList =
255     ItinData->getValueAsListOfDefs("Stages");
256
257   // For each stage
258   unsigned N = NStages = StageList.size();
259   for (unsigned i = 0; i < N;) {
260     // Next stage
261     const Record *Stage = StageList[i];
262
263     // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
264     int Cycles = Stage->getValueAsInt("Cycles");
265     ItinString += "  { " + itostr(Cycles) + ", ";
266
267     // Get unit list
268     const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
269
270     // For each unit
271     for (unsigned j = 0, M = UnitList.size(); j < M;) {
272       // Add name and bitwise or
273       ItinString += Name + "FU::" + UnitList[j]->getName();
274       if (++j < M) ItinString += " | ";
275     }
276
277     int TimeInc = Stage->getValueAsInt("TimeInc");
278     ItinString += ", " + itostr(TimeInc);
279
280     int Kind = Stage->getValueAsInt("Kind");
281     ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
282
283     // Close off stage
284     ItinString += " }";
285     if (++i < N) ItinString += ", ";
286   }
287 }
288
289 //
290 // FormItineraryOperandCycleString - Compose a string containing the
291 // operand cycle initialization for the specified itinerary.  N is the
292 // number of operands that has cycles specified.
293 //
294 void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
295                          std::string &ItinString, unsigned &NOperandCycles) {
296   // Get operand cycle list
297   const std::vector<int64_t> &OperandCycleList =
298     ItinData->getValueAsListOfInts("OperandCycles");
299
300   // For each operand cycle
301   unsigned N = NOperandCycles = OperandCycleList.size();
302   for (unsigned i = 0; i < N;) {
303     // Next operand cycle
304     const int OCycle = OperandCycleList[i];
305
306     ItinString += "  " + itostr(OCycle);
307     if (++i < N) ItinString += ", ";
308   }
309 }
310
311 void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
312                                                  Record *ItinData,
313                                                  std::string &ItinString,
314                                                  unsigned NOperandCycles) {
315   const std::vector<Record*> &BypassList =
316     ItinData->getValueAsListOfDefs("Bypasses");
317   unsigned N = BypassList.size();
318   unsigned i = 0;
319   for (; i < N;) {
320     ItinString += Name + "Bypass::" + BypassList[i]->getName();
321     if (++i < NOperandCycles) ItinString += ", ";
322   }
323   for (; i < NOperandCycles;) {
324     ItinString += " 0";
325     if (++i < NOperandCycles) ItinString += ", ";
326   }
327 }
328
329 //
330 // EmitStageAndOperandCycleData - Generate unique itinerary stages and operand
331 // cycle tables. Create a list of InstrItinerary objects (ProcItinLists) indexed
332 // by CodeGenSchedClass::Index.
333 //
334 void SubtargetEmitter::
335 EmitStageAndOperandCycleData(raw_ostream &OS,
336                              std::vector<std::vector<InstrItinerary> >
337                                &ProcItinLists) {
338
339   // Emit functional units for all the itineraries.
340   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
341          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
342
343     std::vector<Record*> FUs = PI->ItinsDef->getValueAsListOfDefs("FU");
344     if (FUs.empty())
345       continue;
346
347     const std::string &Name = PI->ItinsDef->getName();
348     OS << "\n// Functional units for \"" << Name << "\"\n"
349        << "namespace " << Name << "FU {\n";
350
351     for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
352       OS << "  const unsigned " << FUs[j]->getName()
353          << " = 1 << " << j << ";\n";
354
355     OS << "}\n";
356
357     std::vector<Record*> BPs = PI->ItinsDef->getValueAsListOfDefs("BP");
358     if (BPs.size()) {
359       OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
360          << "\"\n" << "namespace " << Name << "Bypass {\n";
361
362       OS << "  const unsigned NoBypass = 0;\n";
363       for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
364         OS << "  const unsigned " << BPs[j]->getName()
365            << " = 1 << " << j << ";\n";
366
367       OS << "}\n";
368     }
369   }
370
371   // Begin stages table
372   std::string StageTable = "\nextern const llvm::InstrStage " + Target +
373                            "Stages[] = {\n";
374   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
375
376   // Begin operand cycle table
377   std::string OperandCycleTable = "extern const unsigned " + Target +
378     "OperandCycles[] = {\n";
379   OperandCycleTable += "  0, // No itinerary\n";
380
381   // Begin pipeline bypass table
382   std::string BypassTable = "extern const unsigned " + Target +
383     "ForwardingPaths[] = {\n";
384   BypassTable += " 0, // No itinerary\n";
385
386   // For each Itinerary across all processors, add a unique entry to the stages,
387   // operand cycles, and pipepine bypess tables. Then add the new Itinerary
388   // object with computed offsets to the ProcItinLists result.
389   unsigned StageCount = 1, OperandCycleCount = 1;
390   std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
391   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
392          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
393     const CodeGenProcModel &ProcModel = *PI;
394
395     // Add process itinerary to the list.
396     ProcItinLists.resize(ProcItinLists.size()+1);
397
398     // If this processor defines no itineraries, then leave the itinerary list
399     // empty.
400     std::vector<InstrItinerary> &ItinList = ProcItinLists.back();
401     if (ProcModel.ItinDefList.empty())
402       continue;
403
404     // Reserve index==0 for NoItinerary.
405     ItinList.resize(SchedModels.numItineraryClasses()+1);
406
407     const std::string &Name = ProcModel.ItinsDef->getName();
408
409     // For each itinerary data
410     for (unsigned SchedClassIdx = 0,
411            SchedClassEnd = ProcModel.ItinDefList.size();
412          SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
413
414       // Next itinerary data
415       Record *ItinData = ProcModel.ItinDefList[SchedClassIdx];
416
417       // Get string and stage count
418       std::string ItinStageString;
419       unsigned NStages = 0;
420       if (ItinData)
421         FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
422
423       // Get string and operand cycle count
424       std::string ItinOperandCycleString;
425       unsigned NOperandCycles = 0;
426       std::string ItinBypassString;
427       if (ItinData) {
428         FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
429                                         NOperandCycles);
430
431         FormItineraryBypassString(Name, ItinData, ItinBypassString,
432                                   NOperandCycles);
433       }
434
435       // Check to see if stage already exists and create if it doesn't
436       unsigned FindStage = 0;
437       if (NStages > 0) {
438         FindStage = ItinStageMap[ItinStageString];
439         if (FindStage == 0) {
440           // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
441           StageTable += ItinStageString + ", // " + itostr(StageCount);
442           if (NStages > 1)
443             StageTable += "-" + itostr(StageCount + NStages - 1);
444           StageTable += "\n";
445           // Record Itin class number.
446           ItinStageMap[ItinStageString] = FindStage = StageCount;
447           StageCount += NStages;
448         }
449       }
450
451       // Check to see if operand cycle already exists and create if it doesn't
452       unsigned FindOperandCycle = 0;
453       if (NOperandCycles > 0) {
454         std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
455         FindOperandCycle = ItinOperandMap[ItinOperandString];
456         if (FindOperandCycle == 0) {
457           // Emit as  cycle, // index
458           OperandCycleTable += ItinOperandCycleString + ", // ";
459           std::string OperandIdxComment = itostr(OperandCycleCount);
460           if (NOperandCycles > 1)
461             OperandIdxComment += "-"
462               + itostr(OperandCycleCount + NOperandCycles - 1);
463           OperandCycleTable += OperandIdxComment + "\n";
464           // Record Itin class number.
465           ItinOperandMap[ItinOperandCycleString] =
466             FindOperandCycle = OperandCycleCount;
467           // Emit as bypass, // index
468           BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
469           OperandCycleCount += NOperandCycles;
470         }
471       }
472
473       // Set up itinerary as location and location + stage count
474       int NumUOps = ItinData ? ItinData->getValueAsInt("NumMicroOps") : 0;
475       InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
476                                     FindOperandCycle,
477                                     FindOperandCycle + NOperandCycles};
478
479       // Inject - empty slots will be 0, 0
480       ItinList[SchedClassIdx] = Intinerary;
481     }
482   }
483
484   // Closing stage
485   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End stages\n";
486   StageTable += "};\n";
487
488   // Closing operand cycles
489   OperandCycleTable += "  0 // End operand cycles\n";
490   OperandCycleTable += "};\n";
491
492   BypassTable += " 0 // End bypass tables\n";
493   BypassTable += "};\n";
494
495   // Emit tables.
496   OS << StageTable;
497   OS << OperandCycleTable;
498   OS << BypassTable;
499 }
500
501 //
502 // EmitProcessorData - Generate data for processor itineraries that were
503 // computed during EmitStageAndOperandCycleData(). ProcItinLists lists all
504 // Itineraries for each processor. The Itinerary lists are indexed on
505 // CodeGenSchedClass::Index.
506 //
507 void SubtargetEmitter::
508 EmitItineraries(raw_ostream &OS,
509                 std::vector<std::vector<InstrItinerary> > &ProcItinLists) {
510
511   // For each processor's machine model
512   std::vector<std::vector<InstrItinerary> >::iterator
513       ProcItinListsIter = ProcItinLists.begin();
514   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
515          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
516     Record *ItinsDef = PI->ItinsDef;
517
518     // Get processor itinerary name
519     const std::string &Name = ItinsDef->getName();
520
521     // Get the itinerary list for the processor.
522     assert(ProcItinListsIter != ProcItinLists.end() && "bad iterator");
523     std::vector<InstrItinerary> &ItinList = *ProcItinListsIter++;
524
525     OS << "\n";
526     OS << "static const llvm::InstrItinerary ";
527     if (ItinList.empty()) {
528       OS << '*' << Name << " = 0;\n";
529       continue;
530     }
531
532     // Begin processor itinerary table
533     OS << Name << "[] = {\n";
534
535     // For each itinerary class in CodeGenSchedClass::Index order.
536     for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
537       InstrItinerary &Intinerary = ItinList[j];
538
539       // Emit Itinerary in the form of
540       // { firstStage, lastStage, firstCycle, lastCycle } // index
541       OS << "  { " <<
542         Intinerary.NumMicroOps << ", " <<
543         Intinerary.FirstStage << ", " <<
544         Intinerary.LastStage << ", " <<
545         Intinerary.FirstOperandCycle << ", " <<
546         Intinerary.LastOperandCycle << " }" <<
547         ", // " << j << " " << SchedModels.getSchedClass(j).Name << "\n";
548     }
549     // End processor itinerary table
550     OS << "  { 0, ~0U, ~0U, ~0U, ~0U } // end marker\n";
551     OS << "};\n";
552   }
553 }
554
555 // Emit either the the value defined in the TableGen Record, or the default
556 // value defined in the C++ header. The Record is null if the processor does not
557 // define a model.
558 void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R,
559                                          const char *Name, char Separator) {
560   OS << "  ";
561   int V = R ? R->getValueAsInt(Name) : -1;
562   if (V >= 0)
563     OS << V << Separator << " // " << Name;
564   else
565     OS << "MCSchedModel::Default" << Name << Separator;
566   OS << '\n';
567 }
568
569 void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
570   // For each processor model.
571   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
572          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
573     // Skip default
574     // Begin processor itinerary properties
575     OS << "\n";
576     OS << "static const llvm::MCSchedModel " << PI->ModelName << "(\n";
577     EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ',');
578     EmitProcessorProp(OS, PI->ModelDef, "MinLatency", ',');
579     EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ',');
580     EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ',');
581     if (SchedModels.hasItineraryClasses())
582       OS << "  " << PI->ItinsDef->getName();
583     else
584       OS << "  0";
585     OS << ");\n";
586   }
587 }
588
589 //
590 // EmitProcessorLookup - generate cpu name to itinerary lookup table.
591 //
592 void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
593   // Gather and sort processor information
594   std::vector<Record*> ProcessorList =
595                           Records.getAllDerivedDefinitions("Processor");
596   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
597
598   // Begin processor table
599   OS << "\n";
600   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
601      << "extern const llvm::SubtargetInfoKV "
602      << Target << "ProcSchedKV[] = {\n";
603
604   // For each processor
605   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
606     // Next processor
607     Record *Processor = ProcessorList[i];
608
609     const std::string &Name = Processor->getValueAsString("Name");
610     const std::string &ProcModelName =
611       SchedModels.getProcModel(Processor).ModelName;
612
613     // Emit as { "cpu", procinit },
614     OS << "  { "
615        << "\"" << Name << "\", "
616        << "(void *)&" << ProcModelName;
617
618     OS << " }";
619
620     // Depending on ''if more in the list'' emit comma
621     if (++i < N) OS << ",";
622
623     OS << "\n";
624   }
625
626   // End processor table
627   OS << "};\n";
628 }
629
630 //
631 // EmitSchedModel - Emits all scheduling model tables, folding common patterns.
632 //
633 void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
634   if (SchedModels.hasItineraryClasses()) {
635     std::vector<std::vector<InstrItinerary> > ProcItinLists;
636     // Emit the stage data
637     EmitStageAndOperandCycleData(OS, ProcItinLists);
638     EmitItineraries(OS, ProcItinLists);
639   }
640   // Emit the processor machine model
641   EmitProcessorModels(OS);
642   // Emit the processor lookup data
643   EmitProcessorLookup(OS);
644 }
645
646 //
647 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
648 // the subtarget features string.
649 //
650 void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
651                                              unsigned NumFeatures,
652                                              unsigned NumProcs) {
653   std::vector<Record*> Features =
654                        Records.getAllDerivedDefinitions("SubtargetFeature");
655   std::sort(Features.begin(), Features.end(), LessRecord());
656
657   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
658      << "// subtarget options.\n"
659      << "void llvm::";
660   OS << Target;
661   OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
662      << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
663      << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n";
664
665   if (Features.empty()) {
666     OS << "}\n";
667     return;
668   }
669
670   OS << "  uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n";
671
672   for (unsigned i = 0; i < Features.size(); i++) {
673     // Next record
674     Record *R = Features[i];
675     const std::string &Instance = R->getName();
676     const std::string &Value = R->getValueAsString("Value");
677     const std::string &Attribute = R->getValueAsString("Attribute");
678
679     if (Value=="true" || Value=="false")
680       OS << "  if ((Bits & " << Target << "::"
681          << Instance << ") != 0) "
682          << Attribute << " = " << Value << ";\n";
683     else
684       OS << "  if ((Bits & " << Target << "::"
685          << Instance << ") != 0 && "
686          << Attribute << " < " << Value << ") "
687          << Attribute << " = " << Value << ";\n";
688   }
689
690   OS << "}\n";
691 }
692
693 //
694 // SubtargetEmitter::run - Main subtarget enumeration emitter.
695 //
696 void SubtargetEmitter::run(raw_ostream &OS) {
697   emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
698
699   OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
700   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
701
702   OS << "namespace llvm {\n";
703   Enumeration(OS, "SubtargetFeature", true);
704   OS << "} // End llvm namespace \n";
705   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
706
707   OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
708   OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
709
710   OS << "namespace llvm {\n";
711 #if 0
712   OS << "namespace {\n";
713 #endif
714   unsigned NumFeatures = FeatureKeyValues(OS);
715   OS << "\n";
716   unsigned NumProcs = CPUKeyValues(OS);
717   OS << "\n";
718   EmitSchedModel(OS);
719   OS << "\n";
720 #if 0
721   OS << "}\n";
722 #endif
723
724   // MCInstrInfo initialization routine.
725   OS << "static inline void Init" << Target
726      << "MCSubtargetInfo(MCSubtargetInfo *II, "
727      << "StringRef TT, StringRef CPU, StringRef FS) {\n";
728   OS << "  II->InitMCSubtargetInfo(TT, CPU, FS, ";
729   if (NumFeatures)
730     OS << Target << "FeatureKV, ";
731   else
732     OS << "0, ";
733   if (NumProcs)
734     OS << Target << "SubTypeKV, ";
735   else
736     OS << "0, ";
737   if (SchedModels.hasItineraryClasses()) {
738     OS << Target << "ProcSchedKV, "
739        << Target << "Stages, "
740        << Target << "OperandCycles, "
741        << Target << "ForwardingPaths, ";
742   } else
743     OS << "0, 0, 0, 0, ";
744   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
745
746   OS << "} // End llvm namespace \n";
747
748   OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
749
750   OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
751   OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
752
753   OS << "#include \"llvm/Support/Debug.h\"\n";
754   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
755   ParseFeaturesFunction(OS, NumFeatures, NumProcs);
756
757   OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
758
759   // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
760   OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
761   OS << "#undef GET_SUBTARGETINFO_HEADER\n";
762
763   std::string ClassName = Target + "GenSubtargetInfo";
764   OS << "namespace llvm {\n";
765   OS << "class DFAPacketizer;\n";
766   OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
767      << "  explicit " << ClassName << "(StringRef TT, StringRef CPU, "
768      << "StringRef FS);\n"
769      << "public:\n"
770      << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
771      << " const;\n"
772      << "};\n";
773   OS << "} // End llvm namespace \n";
774
775   OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
776
777   OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
778   OS << "#undef GET_SUBTARGETINFO_CTOR\n";
779
780   OS << "namespace llvm {\n";
781   OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
782   OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
783   if (SchedModels.hasItineraryClasses()) {
784     OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n";
785     OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
786     OS << "extern const unsigned " << Target << "OperandCycles[];\n";
787     OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
788   }
789
790   OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, "
791      << "StringRef FS)\n"
792      << "  : TargetSubtargetInfo() {\n"
793      << "  InitMCSubtargetInfo(TT, CPU, FS, ";
794   if (NumFeatures)
795     OS << Target << "FeatureKV, ";
796   else
797     OS << "0, ";
798   if (NumProcs)
799     OS << Target << "SubTypeKV, ";
800   else
801     OS << "0, ";
802   if (SchedModels.hasItineraryClasses()) {
803     OS << Target << "ProcSchedKV, "
804        << Target << "Stages, "
805        << Target << "OperandCycles, "
806        << Target << "ForwardingPaths, ";
807   } else
808     OS << "0, 0, 0, 0, ";
809   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
810   OS << "} // End llvm namespace \n";
811
812   OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
813 }
814
815 namespace llvm {
816
817 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
818   CodeGenTarget CGTarget(RK);
819   SubtargetEmitter(RK, CGTarget).run(OS);
820 }
821
822 } // End llvm namespace