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