Fix a typo (the the => the)
[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   // Multiple processor models may share an itinerary record. Emit it once.
340   SmallPtrSet<Record*, 8> ItinsDefSet;
341
342   // Emit functional units for all the itineraries.
343   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
344          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
345
346     if (!ItinsDefSet.insert(PI->ItinsDef))
347       continue;
348
349     std::vector<Record*> FUs = PI->ItinsDef->getValueAsListOfDefs("FU");
350     if (FUs.empty())
351       continue;
352
353     const std::string &Name = PI->ItinsDef->getName();
354     OS << "\n// Functional units for \"" << Name << "\"\n"
355        << "namespace " << Name << "FU {\n";
356
357     for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
358       OS << "  const unsigned " << FUs[j]->getName()
359          << " = 1 << " << j << ";\n";
360
361     OS << "}\n";
362
363     std::vector<Record*> BPs = PI->ItinsDef->getValueAsListOfDefs("BP");
364     if (BPs.size()) {
365       OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
366          << "\"\n" << "namespace " << Name << "Bypass {\n";
367
368       OS << "  const unsigned NoBypass = 0;\n";
369       for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
370         OS << "  const unsigned " << BPs[j]->getName()
371            << " = 1 << " << j << ";\n";
372
373       OS << "}\n";
374     }
375   }
376
377   // Begin stages table
378   std::string StageTable = "\nextern const llvm::InstrStage " + Target +
379                            "Stages[] = {\n";
380   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
381
382   // Begin operand cycle table
383   std::string OperandCycleTable = "extern const unsigned " + Target +
384     "OperandCycles[] = {\n";
385   OperandCycleTable += "  0, // No itinerary\n";
386
387   // Begin pipeline bypass table
388   std::string BypassTable = "extern const unsigned " + Target +
389     "ForwardingPaths[] = {\n";
390   BypassTable += " 0, // No itinerary\n";
391
392   // For each Itinerary across all processors, add a unique entry to the stages,
393   // operand cycles, and pipepine bypess tables. Then add the new Itinerary
394   // object with computed offsets to the ProcItinLists result.
395   unsigned StageCount = 1, OperandCycleCount = 1;
396   std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
397   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
398          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
399     const CodeGenProcModel &ProcModel = *PI;
400
401     // Add process itinerary to the list.
402     ProcItinLists.resize(ProcItinLists.size()+1);
403
404     // If this processor defines no itineraries, then leave the itinerary list
405     // empty.
406     std::vector<InstrItinerary> &ItinList = ProcItinLists.back();
407     if (ProcModel.ItinDefList.empty())
408       continue;
409
410     // Reserve index==0 for NoItinerary.
411     ItinList.resize(SchedModels.numItineraryClasses()+1);
412
413     const std::string &Name = ProcModel.ItinsDef->getName();
414
415     // For each itinerary data
416     for (unsigned SchedClassIdx = 0,
417            SchedClassEnd = ProcModel.ItinDefList.size();
418          SchedClassIdx < SchedClassEnd; ++SchedClassIdx) {
419
420       // Next itinerary data
421       Record *ItinData = ProcModel.ItinDefList[SchedClassIdx];
422
423       // Get string and stage count
424       std::string ItinStageString;
425       unsigned NStages = 0;
426       if (ItinData)
427         FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
428
429       // Get string and operand cycle count
430       std::string ItinOperandCycleString;
431       unsigned NOperandCycles = 0;
432       std::string ItinBypassString;
433       if (ItinData) {
434         FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
435                                         NOperandCycles);
436
437         FormItineraryBypassString(Name, ItinData, ItinBypassString,
438                                   NOperandCycles);
439       }
440
441       // Check to see if stage already exists and create if it doesn't
442       unsigned FindStage = 0;
443       if (NStages > 0) {
444         FindStage = ItinStageMap[ItinStageString];
445         if (FindStage == 0) {
446           // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
447           StageTable += ItinStageString + ", // " + itostr(StageCount);
448           if (NStages > 1)
449             StageTable += "-" + itostr(StageCount + NStages - 1);
450           StageTable += "\n";
451           // Record Itin class number.
452           ItinStageMap[ItinStageString] = FindStage = StageCount;
453           StageCount += NStages;
454         }
455       }
456
457       // Check to see if operand cycle already exists and create if it doesn't
458       unsigned FindOperandCycle = 0;
459       if (NOperandCycles > 0) {
460         std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
461         FindOperandCycle = ItinOperandMap[ItinOperandString];
462         if (FindOperandCycle == 0) {
463           // Emit as  cycle, // index
464           OperandCycleTable += ItinOperandCycleString + ", // ";
465           std::string OperandIdxComment = itostr(OperandCycleCount);
466           if (NOperandCycles > 1)
467             OperandIdxComment += "-"
468               + itostr(OperandCycleCount + NOperandCycles - 1);
469           OperandCycleTable += OperandIdxComment + "\n";
470           // Record Itin class number.
471           ItinOperandMap[ItinOperandCycleString] =
472             FindOperandCycle = OperandCycleCount;
473           // Emit as bypass, // index
474           BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
475           OperandCycleCount += NOperandCycles;
476         }
477       }
478
479       // Set up itinerary as location and location + stage count
480       int NumUOps = ItinData ? ItinData->getValueAsInt("NumMicroOps") : 0;
481       InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
482                                     FindOperandCycle,
483                                     FindOperandCycle + NOperandCycles};
484
485       // Inject - empty slots will be 0, 0
486       ItinList[SchedClassIdx] = Intinerary;
487     }
488   }
489
490   // Closing stage
491   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End stages\n";
492   StageTable += "};\n";
493
494   // Closing operand cycles
495   OperandCycleTable += "  0 // End operand cycles\n";
496   OperandCycleTable += "};\n";
497
498   BypassTable += " 0 // End bypass tables\n";
499   BypassTable += "};\n";
500
501   // Emit tables.
502   OS << StageTable;
503   OS << OperandCycleTable;
504   OS << BypassTable;
505 }
506
507 //
508 // EmitProcessorData - Generate data for processor itineraries that were
509 // computed during EmitStageAndOperandCycleData(). ProcItinLists lists all
510 // Itineraries for each processor. The Itinerary lists are indexed on
511 // CodeGenSchedClass::Index.
512 //
513 void SubtargetEmitter::
514 EmitItineraries(raw_ostream &OS,
515                 std::vector<std::vector<InstrItinerary> > &ProcItinLists) {
516
517   // Multiple processor models may share an itinerary record. Emit it once.
518   SmallPtrSet<Record*, 8> ItinsDefSet;
519
520   // For each processor's machine model
521   std::vector<std::vector<InstrItinerary> >::iterator
522       ProcItinListsIter = ProcItinLists.begin();
523   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
524          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
525
526     Record *ItinsDef = PI->ItinsDef;
527     if (!ItinsDefSet.insert(ItinsDef))
528       continue;
529
530     // Get processor itinerary name
531     const std::string &Name = ItinsDef->getName();
532
533     // Get the itinerary list for the processor.
534     assert(ProcItinListsIter != ProcItinLists.end() && "bad iterator");
535     std::vector<InstrItinerary> &ItinList = *ProcItinListsIter++;
536
537     OS << "\n";
538     OS << "static const llvm::InstrItinerary ";
539     if (ItinList.empty()) {
540       OS << '*' << Name << " = 0;\n";
541       continue;
542     }
543
544     // Begin processor itinerary table
545     OS << Name << "[] = {\n";
546
547     // For each itinerary class in CodeGenSchedClass::Index order.
548     for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
549       InstrItinerary &Intinerary = ItinList[j];
550
551       // Emit Itinerary in the form of
552       // { firstStage, lastStage, firstCycle, lastCycle } // index
553       OS << "  { " <<
554         Intinerary.NumMicroOps << ", " <<
555         Intinerary.FirstStage << ", " <<
556         Intinerary.LastStage << ", " <<
557         Intinerary.FirstOperandCycle << ", " <<
558         Intinerary.LastOperandCycle << " }" <<
559         ", // " << j << " " << SchedModels.getSchedClass(j).Name << "\n";
560     }
561     // End processor itinerary table
562     OS << "  { 0, ~0U, ~0U, ~0U, ~0U } // end marker\n";
563     OS << "};\n";
564   }
565 }
566
567 // Emit either the value defined in the TableGen Record, or the default
568 // value defined in the C++ header. The Record is null if the processor does not
569 // define a model.
570 void SubtargetEmitter::EmitProcessorProp(raw_ostream &OS, const Record *R,
571                                          const char *Name, char Separator) {
572   OS << "  ";
573   int V = R ? R->getValueAsInt(Name) : -1;
574   if (V >= 0)
575     OS << V << Separator << " // " << Name;
576   else
577     OS << "MCSchedModel::Default" << Name << Separator;
578   OS << '\n';
579 }
580
581 void SubtargetEmitter::EmitProcessorModels(raw_ostream &OS) {
582   // For each processor model.
583   for (CodeGenSchedModels::ProcIter PI = SchedModels.procModelBegin(),
584          PE = SchedModels.procModelEnd(); PI != PE; ++PI) {
585     // Skip default
586     // Begin processor itinerary properties
587     OS << "\n";
588     OS << "static const llvm::MCSchedModel " << PI->ModelName << "(\n";
589     EmitProcessorProp(OS, PI->ModelDef, "IssueWidth", ',');
590     EmitProcessorProp(OS, PI->ModelDef, "MinLatency", ',');
591     EmitProcessorProp(OS, PI->ModelDef, "LoadLatency", ',');
592     EmitProcessorProp(OS, PI->ModelDef, "HighLatency", ',');
593     if (SchedModels.hasItineraryClasses())
594       OS << "  " << PI->ItinsDef->getName();
595     else
596       OS << "  0";
597     OS << ");\n";
598   }
599 }
600
601 //
602 // EmitProcessorLookup - generate cpu name to itinerary lookup table.
603 //
604 void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
605   // Gather and sort processor information
606   std::vector<Record*> ProcessorList =
607                           Records.getAllDerivedDefinitions("Processor");
608   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
609
610   // Begin processor table
611   OS << "\n";
612   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
613      << "extern const llvm::SubtargetInfoKV "
614      << Target << "ProcSchedKV[] = {\n";
615
616   // For each processor
617   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
618     // Next processor
619     Record *Processor = ProcessorList[i];
620
621     const std::string &Name = Processor->getValueAsString("Name");
622     const std::string &ProcModelName =
623       SchedModels.getProcModel(Processor).ModelName;
624
625     // Emit as { "cpu", procinit },
626     OS << "  { "
627        << "\"" << Name << "\", "
628        << "(void *)&" << ProcModelName;
629
630     OS << " }";
631
632     // Depending on ''if more in the list'' emit comma
633     if (++i < N) OS << ",";
634
635     OS << "\n";
636   }
637
638   // End processor table
639   OS << "};\n";
640 }
641
642 //
643 // EmitSchedModel - Emits all scheduling model tables, folding common patterns.
644 //
645 void SubtargetEmitter::EmitSchedModel(raw_ostream &OS) {
646   if (SchedModels.hasItineraryClasses()) {
647     std::vector<std::vector<InstrItinerary> > ProcItinLists;
648     // Emit the stage data
649     EmitStageAndOperandCycleData(OS, ProcItinLists);
650     EmitItineraries(OS, ProcItinLists);
651   }
652   // Emit the processor machine model
653   EmitProcessorModels(OS);
654   // Emit the processor lookup data
655   EmitProcessorLookup(OS);
656 }
657
658 //
659 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
660 // the subtarget features string.
661 //
662 void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
663                                              unsigned NumFeatures,
664                                              unsigned NumProcs) {
665   std::vector<Record*> Features =
666                        Records.getAllDerivedDefinitions("SubtargetFeature");
667   std::sort(Features.begin(), Features.end(), LessRecord());
668
669   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
670      << "// subtarget options.\n"
671      << "void llvm::";
672   OS << Target;
673   OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
674      << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
675      << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n";
676
677   if (Features.empty()) {
678     OS << "}\n";
679     return;
680   }
681
682   OS << "  uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n";
683
684   for (unsigned i = 0; i < Features.size(); i++) {
685     // Next record
686     Record *R = Features[i];
687     const std::string &Instance = R->getName();
688     const std::string &Value = R->getValueAsString("Value");
689     const std::string &Attribute = R->getValueAsString("Attribute");
690
691     if (Value=="true" || Value=="false")
692       OS << "  if ((Bits & " << Target << "::"
693          << Instance << ") != 0) "
694          << Attribute << " = " << Value << ";\n";
695     else
696       OS << "  if ((Bits & " << Target << "::"
697          << Instance << ") != 0 && "
698          << Attribute << " < " << Value << ") "
699          << Attribute << " = " << Value << ";\n";
700   }
701
702   OS << "}\n";
703 }
704
705 //
706 // SubtargetEmitter::run - Main subtarget enumeration emitter.
707 //
708 void SubtargetEmitter::run(raw_ostream &OS) {
709   emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
710
711   OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
712   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
713
714   OS << "namespace llvm {\n";
715   Enumeration(OS, "SubtargetFeature", true);
716   OS << "} // End llvm namespace \n";
717   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
718
719   OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
720   OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
721
722   OS << "namespace llvm {\n";
723 #if 0
724   OS << "namespace {\n";
725 #endif
726   unsigned NumFeatures = FeatureKeyValues(OS);
727   OS << "\n";
728   unsigned NumProcs = CPUKeyValues(OS);
729   OS << "\n";
730   EmitSchedModel(OS);
731   OS << "\n";
732 #if 0
733   OS << "}\n";
734 #endif
735
736   // MCInstrInfo initialization routine.
737   OS << "static inline void Init" << Target
738      << "MCSubtargetInfo(MCSubtargetInfo *II, "
739      << "StringRef TT, StringRef CPU, StringRef FS) {\n";
740   OS << "  II->InitMCSubtargetInfo(TT, CPU, FS, ";
741   if (NumFeatures)
742     OS << Target << "FeatureKV, ";
743   else
744     OS << "0, ";
745   if (NumProcs)
746     OS << Target << "SubTypeKV, ";
747   else
748     OS << "0, ";
749   if (SchedModels.hasItineraryClasses()) {
750     OS << Target << "ProcSchedKV, "
751        << Target << "Stages, "
752        << Target << "OperandCycles, "
753        << Target << "ForwardingPaths, ";
754   } else
755     OS << "0, 0, 0, 0, ";
756   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
757
758   OS << "} // End llvm namespace \n";
759
760   OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
761
762   OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
763   OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
764
765   OS << "#include \"llvm/Support/Debug.h\"\n";
766   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
767   ParseFeaturesFunction(OS, NumFeatures, NumProcs);
768
769   OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
770
771   // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
772   OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
773   OS << "#undef GET_SUBTARGETINFO_HEADER\n";
774
775   std::string ClassName = Target + "GenSubtargetInfo";
776   OS << "namespace llvm {\n";
777   OS << "class DFAPacketizer;\n";
778   OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
779      << "  explicit " << ClassName << "(StringRef TT, StringRef CPU, "
780      << "StringRef FS);\n"
781      << "public:\n"
782      << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
783      << " const;\n"
784      << "};\n";
785   OS << "} // End llvm namespace \n";
786
787   OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
788
789   OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
790   OS << "#undef GET_SUBTARGETINFO_CTOR\n";
791
792   OS << "namespace llvm {\n";
793   OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
794   OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
795   if (SchedModels.hasItineraryClasses()) {
796     OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcSchedKV[];\n";
797     OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
798     OS << "extern const unsigned " << Target << "OperandCycles[];\n";
799     OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
800   }
801
802   OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, "
803      << "StringRef FS)\n"
804      << "  : TargetSubtargetInfo() {\n"
805      << "  InitMCSubtargetInfo(TT, CPU, FS, ";
806   if (NumFeatures)
807     OS << Target << "FeatureKV, ";
808   else
809     OS << "0, ";
810   if (NumProcs)
811     OS << Target << "SubTypeKV, ";
812   else
813     OS << "0, ";
814   if (SchedModels.hasItineraryClasses()) {
815     OS << Target << "ProcSchedKV, "
816        << Target << "Stages, "
817        << Target << "OperandCycles, "
818        << Target << "ForwardingPaths, ";
819   } else
820     OS << "0, 0, 0, 0, ";
821   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
822   OS << "} // End llvm namespace \n";
823
824   OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
825 }
826
827 namespace llvm {
828
829 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
830   CodeGenTarget CGTarget(RK);
831   SubtargetEmitter(RK, CGTarget).run(OS);
832 }
833
834 } // End llvm namespace