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