Add two newlines in ParseSubtargetFeatures's debug output after the CPU is printed.
[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     // Skip default
426     if (Name == "NoItineraries") continue;
427
428     // Create and expand processor itinerary to cover all itinerary classes
429     std::vector<InstrItinerary> ItinList;
430     ItinList.resize(NItinClasses);
431
432     // Get itinerary data list
433     std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
434
435     // For each itinerary data
436     for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
437       // Next itinerary data
438       Record *ItinData = ItinDataList[j];
439
440       // Get string and stage count
441       std::string ItinStageString;
442       unsigned NStages;
443       FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
444
445       // Get string and operand cycle count
446       std::string ItinOperandCycleString;
447       unsigned NOperandCycles;
448       FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
449                                       NOperandCycles);
450
451       std::string ItinBypassString;
452       FormItineraryBypassString(Name, ItinData, ItinBypassString,
453                                 NOperandCycles);
454
455       // Check to see if stage already exists and create if it doesn't
456       unsigned FindStage = 0;
457       if (NStages > 0) {
458         FindStage = ItinStageMap[ItinStageString];
459         if (FindStage == 0) {
460           // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
461           StageTable += ItinStageString + ", // " + itostr(StageCount);
462           if (NStages > 1)
463             StageTable += "-" + itostr(StageCount + NStages - 1);
464           StageTable += "\n";
465           // Record Itin class number.
466           ItinStageMap[ItinStageString] = FindStage = StageCount;
467           StageCount += NStages;
468         }
469       }
470
471       // Check to see if operand cycle already exists and create if it doesn't
472       unsigned FindOperandCycle = 0;
473       if (NOperandCycles > 0) {
474         std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
475         FindOperandCycle = ItinOperandMap[ItinOperandString];
476         if (FindOperandCycle == 0) {
477           // Emit as  cycle, // index
478           OperandCycleTable += ItinOperandCycleString + ", // ";
479           std::string OperandIdxComment = itostr(OperandCycleCount);
480           if (NOperandCycles > 1)
481             OperandIdxComment += "-"
482               + itostr(OperandCycleCount + NOperandCycles - 1);
483           OperandCycleTable += OperandIdxComment + "\n";
484           // Record Itin class number.
485           ItinOperandMap[ItinOperandCycleString] =
486             FindOperandCycle = OperandCycleCount;
487           // Emit as bypass, // index
488           BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
489           OperandCycleCount += NOperandCycles;
490         }
491       }
492
493       // Locate where to inject into processor itinerary table
494       const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
495       unsigned Find = ItinClassesMap[Name];
496
497       // Set up itinerary as location and location + stage count
498       unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps");
499       InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
500                                     FindOperandCycle,
501                                     FindOperandCycle + NOperandCycles};
502
503       // Inject - empty slots will be 0, 0
504       ItinList[Find] = Intinerary;
505     }
506
507     // Add process itinerary to list
508     ProcList.push_back(ItinList);
509   }
510
511   // Closing stage
512   StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
513   StageTable += "};\n";
514
515   // Closing operand cycles
516   OperandCycleTable += "  0 // End itinerary\n";
517   OperandCycleTable += "};\n";
518
519   BypassTable += "  0 // End itinerary\n";
520   BypassTable += "};\n";
521
522   // Emit tables.
523   OS << StageTable;
524   OS << OperandCycleTable;
525   OS << BypassTable;
526 }
527
528 void SubtargetEmitter::EmitItineraryProp(raw_ostream &OS, const Record *R,
529                                          const char *Name, char Separator) {
530   OS << "  ";
531   int V = R->getValueAsInt(Name);
532   if (V >= 0)
533     OS << V << Separator << " // " << Name;
534   else
535     OS << "InstrItineraryProps::Default" << Name << Separator;
536   OS << '\n';
537 }
538
539 //
540 // EmitProcessorData - Generate data for processor itineraries.
541 //
542 void SubtargetEmitter::
543 EmitProcessorData(raw_ostream &OS,
544                   std::vector<Record*> &ItinClassList,
545                   std::vector<std::vector<InstrItinerary> > &ProcList) {
546
547   // Get an iterator for processor itinerary stages
548   std::vector<std::vector<InstrItinerary> >::iterator
549       ProcListIter = ProcList.begin();
550
551   // For each processor itinerary
552   std::vector<Record*> Itins =
553                        Records.getAllDerivedDefinitions("ProcessorItineraries");
554   for (unsigned i = 0, N = Itins.size(); i < N; i++) {
555     // Next record
556     Record *Itin = Itins[i];
557
558     // Get processor itinerary name
559     const std::string &Name = Itin->getName();
560
561     // Skip default
562     if (Name == "NoItineraries") continue;
563
564     // Begin processor itinerary properties
565     OS << "\n";
566     OS << "static const llvm::InstrItineraryProps " << Name << "Props(\n";
567     EmitItineraryProp(OS, Itin, "IssueWidth", ',');
568     EmitItineraryProp(OS, Itin, "MinLatency", ',');
569     EmitItineraryProp(OS, Itin, "LoadLatency", ',');
570     EmitItineraryProp(OS, Itin, "HighLatency", ' ');
571     OS << ");\n";
572
573     // Begin processor itinerary table
574     OS << "\n";
575     OS << "static const llvm::InstrItinerary " << Name << "Entries"
576        << "[] = {\n";
577
578     // For each itinerary class
579     std::vector<InstrItinerary> &ItinList = *ProcListIter++;
580     assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
581     for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
582       InstrItinerary &Intinerary = ItinList[j];
583
584       // Emit in the form of
585       // { firstStage, lastStage, firstCycle, lastCycle } // index
586       if (Intinerary.FirstStage == 0) {
587         OS << "  { 1, 0, 0, 0, 0 }";
588       } else {
589         OS << "  { " <<
590           Intinerary.NumMicroOps << ", " <<
591           Intinerary.FirstStage << ", " <<
592           Intinerary.LastStage << ", " <<
593           Intinerary.FirstOperandCycle << ", " <<
594           Intinerary.LastOperandCycle << " }";
595       }
596
597       OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
598     }
599
600     // End processor itinerary table
601     OS << "  { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
602     OS << "};\n";
603
604     OS << '\n';
605     OS << "static const llvm::InstrItinerarySubtargetValue "
606        << Name << " = {\n";
607     OS << "  &" << Name << "Props,\n";
608     OS << "  " << Name << "Entries\n";
609     OS << "};\n";
610   }
611 }
612
613 //
614 // EmitProcessorLookup - generate cpu name to itinerary lookup table.
615 //
616 void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
617   // Gather and sort processor information
618   std::vector<Record*> ProcessorList =
619                           Records.getAllDerivedDefinitions("Processor");
620   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
621
622   // Begin processor table
623   OS << "\n";
624   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
625      << "extern const llvm::SubtargetInfoKV "
626      << Target << "ProcItinKV[] = {\n";
627
628   // For each processor
629   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
630     // Next processor
631     Record *Processor = ProcessorList[i];
632
633     const std::string &Name = Processor->getValueAsString("Name");
634     const std::string &ProcItin =
635       Processor->getValueAsDef("ProcItin")->getName();
636
637     // Emit as { "cpu", procinit },
638     OS << "  { "
639        << "\"" << Name << "\", "
640        << "(void *)&" << ProcItin;
641
642     OS << " }";
643
644     // Depending on ''if more in the list'' emit comma
645     if (++i < N) OS << ",";
646
647     OS << "\n";
648   }
649
650   // End processor table
651   OS << "};\n";
652 }
653
654 //
655 // EmitData - Emits all stages and itineries, folding common patterns.
656 //
657 void SubtargetEmitter::EmitData(raw_ostream &OS) {
658   std::map<std::string, unsigned> ItinClassesMap;
659   // Gather and sort all itinerary classes
660   std::vector<Record*> ItinClassList =
661     Records.getAllDerivedDefinitions("InstrItinClass");
662   std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
663
664   // Enumerate all the itinerary classes
665   unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
666                                                 ItinClassList);
667   // Make sure the rest is worth the effort
668   HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
669
670   if (HasItineraries) {
671     std::vector<std::vector<InstrItinerary> > ProcList;
672     // Emit the stage data
673     EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
674                                  ItinClassList, ProcList);
675     // Emit the processor itinerary data
676     EmitProcessorData(OS, ItinClassList, ProcList);
677     // Emit the processor lookup data
678     EmitProcessorLookup(OS);
679   }
680 }
681
682 //
683 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
684 // the subtarget features string.
685 //
686 void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
687                                              unsigned NumFeatures,
688                                              unsigned NumProcs) {
689   std::vector<Record*> Features =
690                        Records.getAllDerivedDefinitions("SubtargetFeature");
691   std::sort(Features.begin(), Features.end(), LessRecord());
692
693   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
694      << "// subtarget options.\n"
695      << "void llvm::";
696   OS << Target;
697   OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
698      << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
699      << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n";
700
701   if (Features.empty()) {
702     OS << "}\n";
703     return;
704   }
705
706   OS << "  uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n";
707
708   for (unsigned i = 0; i < Features.size(); i++) {
709     // Next record
710     Record *R = Features[i];
711     const std::string &Instance = R->getName();
712     const std::string &Value = R->getValueAsString("Value");
713     const std::string &Attribute = R->getValueAsString("Attribute");
714
715     if (Value=="true" || Value=="false")
716       OS << "  if ((Bits & " << Target << "::"
717          << Instance << ") != 0) "
718          << Attribute << " = " << Value << ";\n";
719     else
720       OS << "  if ((Bits & " << Target << "::"
721          << Instance << ") != 0 && "
722          << Attribute << " < " << Value << ") "
723          << Attribute << " = " << Value << ";\n";
724   }
725
726   OS << "}\n";
727 }
728
729 //
730 // SubtargetEmitter::run - Main subtarget enumeration emitter.
731 //
732 void SubtargetEmitter::run(raw_ostream &OS) {
733   Target = CodeGenTarget(Records).getName();
734
735   emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
736
737   OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
738   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
739
740   OS << "namespace llvm {\n";
741   Enumeration(OS, "SubtargetFeature", true);
742   OS << "} // End llvm namespace \n";
743   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
744
745   OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
746   OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
747
748   OS << "namespace llvm {\n";
749 #if 0
750   OS << "namespace {\n";
751 #endif
752   unsigned NumFeatures = FeatureKeyValues(OS);
753   OS << "\n";
754   unsigned NumProcs = CPUKeyValues(OS);
755   OS << "\n";
756   EmitData(OS);
757   OS << "\n";
758 #if 0
759   OS << "}\n";
760 #endif
761
762   // MCInstrInfo initialization routine.
763   OS << "static inline void Init" << Target
764      << "MCSubtargetInfo(MCSubtargetInfo *II, "
765      << "StringRef TT, StringRef CPU, StringRef FS) {\n";
766   OS << "  II->InitMCSubtargetInfo(TT, CPU, FS, ";
767   if (NumFeatures)
768     OS << Target << "FeatureKV, ";
769   else
770     OS << "0, ";
771   if (NumProcs)
772     OS << Target << "SubTypeKV, ";
773   else
774     OS << "0, ";
775   if (HasItineraries) {
776     OS << Target << "ProcItinKV, "
777        << Target << "Stages, "
778        << Target << "OperandCycles, "
779        << Target << "ForwardingPathes, ";
780   } else
781     OS << "0, 0, 0, 0, ";
782   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
783
784   OS << "} // End llvm namespace \n";
785
786   OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
787
788   OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
789   OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
790
791   OS << "#include \"llvm/Support/Debug.h\"\n";
792   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
793   ParseFeaturesFunction(OS, NumFeatures, NumProcs);
794
795   OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
796
797   // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
798   OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
799   OS << "#undef GET_SUBTARGETINFO_HEADER\n";
800
801   std::string ClassName = Target + "GenSubtargetInfo";
802   OS << "namespace llvm {\n";
803   OS << "class DFAPacketizer;\n";
804   OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
805      << "  explicit " << ClassName << "(StringRef TT, StringRef CPU, "
806      << "StringRef FS);\n"
807      << "public:\n"
808      << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
809      << " const;\n"
810      << "};\n";
811   OS << "} // End llvm namespace \n";
812
813   OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
814
815   OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
816   OS << "#undef GET_SUBTARGETINFO_CTOR\n";
817
818   OS << "namespace llvm {\n";
819   OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
820   OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
821   if (HasItineraries) {
822     OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcItinKV[];\n";
823     OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
824     OS << "extern const unsigned " << Target << "OperandCycles[];\n";
825     OS << "extern const unsigned " << Target << "ForwardingPathes[];\n";
826   }
827
828   OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, "
829      << "StringRef FS)\n"
830      << "  : TargetSubtargetInfo() {\n"
831      << "  InitMCSubtargetInfo(TT, CPU, FS, ";
832   if (NumFeatures)
833     OS << Target << "FeatureKV, ";
834   else
835     OS << "0, ";
836   if (NumProcs)
837     OS << Target << "SubTypeKV, ";
838   else
839     OS << "0, ";
840   if (HasItineraries) {
841     OS << Target << "ProcItinKV, "
842        << Target << "Stages, "
843        << Target << "OperandCycles, "
844        << Target << "ForwardingPathes, ";
845   } else
846     OS << "0, 0, 0, 0, ";
847   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
848   OS << "} // End llvm namespace \n";
849
850   OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
851 }
852
853 namespace llvm {
854
855 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
856   SubtargetEmitter(RK).run(OS);
857 }
858
859 } // End llvm namespace