Don't use enums larger than 1 << 31 for target features.
[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 //
482 // EmitProcessorData - Generate data for processor itineraries.
483 //
484 void SubtargetEmitter::
485 EmitProcessorData(raw_ostream &OS,
486                   std::vector<Record*> &ItinClassList,
487                   std::vector<std::vector<InstrItinerary> > &ProcList) {
488   // Get an iterator for processor itinerary stages
489   std::vector<std::vector<InstrItinerary> >::iterator
490       ProcListIter = ProcList.begin();
491
492   // For each processor itinerary
493   std::vector<Record*> Itins =
494                        Records.getAllDerivedDefinitions("ProcessorItineraries");
495   for (unsigned i = 0, N = Itins.size(); i < N; i++) {
496     // Next record
497     Record *Itin = Itins[i];
498
499     // Get processor itinerary name
500     const std::string &Name = Itin->getName();
501
502     // Skip default
503     if (Name == "NoItineraries") continue;
504
505     // Begin processor itinerary table
506     OS << "\n";
507     OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
508
509     // For each itinerary class
510     std::vector<InstrItinerary> &ItinList = *ProcListIter++;
511     assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
512     for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
513       InstrItinerary &Intinerary = ItinList[j];
514
515       // Emit in the form of
516       // { firstStage, lastStage, firstCycle, lastCycle } // index
517       if (Intinerary.FirstStage == 0) {
518         OS << "  { 1, 0, 0, 0, 0 }";
519       } else {
520         OS << "  { " <<
521           Intinerary.NumMicroOps << ", " <<
522           Intinerary.FirstStage << ", " <<
523           Intinerary.LastStage << ", " <<
524           Intinerary.FirstOperandCycle << ", " <<
525           Intinerary.LastOperandCycle << " }";
526       }
527
528       OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
529     }
530
531     // End processor itinerary table
532     OS << "  { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
533     OS << "};\n";
534   }
535 }
536
537 //
538 // EmitProcessorLookup - generate cpu name to itinerary lookup table.
539 //
540 void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
541   // Gather and sort processor information
542   std::vector<Record*> ProcessorList =
543                           Records.getAllDerivedDefinitions("Processor");
544   std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
545
546   // Begin processor table
547   OS << "\n";
548   OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
549      << "extern const llvm::SubtargetInfoKV "
550      << Target << "ProcItinKV[] = {\n";
551
552   // For each processor
553   for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
554     // Next processor
555     Record *Processor = ProcessorList[i];
556
557     const std::string &Name = Processor->getValueAsString("Name");
558     const std::string &ProcItin =
559       Processor->getValueAsDef("ProcItin")->getName();
560
561     // Emit as { "cpu", procinit },
562     OS << "  { "
563        << "\"" << Name << "\", "
564        << "(void *)&" << ProcItin;
565
566     OS << " }";
567
568     // Depending on ''if more in the list'' emit comma
569     if (++i < N) OS << ",";
570
571     OS << "\n";
572   }
573
574   // End processor table
575   OS << "};\n";
576 }
577
578 //
579 // EmitData - Emits all stages and itineries, folding common patterns.
580 //
581 void SubtargetEmitter::EmitData(raw_ostream &OS) {
582   std::map<std::string, unsigned> ItinClassesMap;
583   // Gather and sort all itinerary classes
584   std::vector<Record*> ItinClassList =
585     Records.getAllDerivedDefinitions("InstrItinClass");
586   std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
587
588   // Enumerate all the itinerary classes
589   unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
590                                                 ItinClassList);
591   // Make sure the rest is worth the effort
592   HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
593
594   if (HasItineraries) {
595     std::vector<std::vector<InstrItinerary> > ProcList;
596     // Emit the stage data
597     EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
598                                  ItinClassList, ProcList);
599     // Emit the processor itinerary data
600     EmitProcessorData(OS, ItinClassList, ProcList);
601     // Emit the processor lookup data
602     EmitProcessorLookup(OS);
603   }
604 }
605
606 //
607 // ParseFeaturesFunction - Produces a subtarget specific function for parsing
608 // the subtarget features string.
609 //
610 void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
611                                              unsigned NumFeatures,
612                                              unsigned NumProcs) {
613   std::vector<Record*> Features =
614                        Records.getAllDerivedDefinitions("SubtargetFeature");
615   std::sort(Features.begin(), Features.end(), LessRecord());
616
617   OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
618      << "// subtarget options.\n"
619      << "void llvm::";
620   OS << Target;
621   OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
622      << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
623      << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n";
624
625   if (Features.empty()) {
626     OS << "}\n";
627     return;
628   }
629
630   OS << "  uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n";
631
632   for (unsigned i = 0; i < Features.size(); i++) {
633     // Next record
634     Record *R = Features[i];
635     const std::string &Instance = R->getName();
636     const std::string &Value = R->getValueAsString("Value");
637     const std::string &Attribute = R->getValueAsString("Attribute");
638
639     if (Value=="true" || Value=="false")
640       OS << "  if ((Bits & " << Target << "::"
641          << Instance << ") != 0) "
642          << Attribute << " = " << Value << ";\n";
643     else
644       OS << "  if ((Bits & " << Target << "::"
645          << Instance << ") != 0 && "
646          << Attribute << " < " << Value << ") "
647          << Attribute << " = " << Value << ";\n";
648   }
649
650   OS << "}\n";
651 }
652
653 //
654 // SubtargetEmitter::run - Main subtarget enumeration emitter.
655 //
656 void SubtargetEmitter::run(raw_ostream &OS) {
657   Target = CodeGenTarget(Records).getName();
658
659   EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
660
661   OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
662   OS << "#undef GET_SUBTARGETINFO_ENUM\n";
663
664   OS << "namespace llvm {\n";
665   Enumeration(OS, "SubtargetFeature", true);
666   OS << "} // End llvm namespace \n";
667   OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
668
669   OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
670   OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
671
672   OS << "namespace llvm {\n";
673 #if 0
674   OS << "namespace {\n";
675 #endif
676   unsigned NumFeatures = FeatureKeyValues(OS);
677   OS << "\n";
678   unsigned NumProcs = CPUKeyValues(OS);
679   OS << "\n";
680   EmitData(OS);
681   OS << "\n";
682 #if 0
683   OS << "}\n";
684 #endif
685
686   // MCInstrInfo initialization routine.
687   OS << "static inline void Init" << Target
688      << "MCSubtargetInfo(MCSubtargetInfo *II, "
689      << "StringRef TT, StringRef CPU, StringRef FS) {\n";
690   OS << "  II->InitMCSubtargetInfo(TT, CPU, FS, ";
691   if (NumFeatures)
692     OS << Target << "FeatureKV, ";
693   else
694     OS << "0, ";
695   if (NumProcs)
696     OS << Target << "SubTypeKV, ";
697   else
698     OS << "0, ";
699   if (HasItineraries) {
700     OS << Target << "ProcItinKV, "
701        << Target << "Stages, "
702        << Target << "OperandCycles, "
703        << Target << "ForwardingPathes, ";
704   } else
705     OS << "0, 0, 0, 0, ";
706   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
707
708   OS << "} // End llvm namespace \n";
709
710   OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
711
712   OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
713   OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
714
715   OS << "#include \"llvm/Support/Debug.h\"\n";
716   OS << "#include \"llvm/Support/raw_ostream.h\"\n";
717   ParseFeaturesFunction(OS, NumFeatures, NumProcs);
718
719   OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
720
721   // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
722   OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
723   OS << "#undef GET_SUBTARGETINFO_HEADER\n";
724
725   std::string ClassName = Target + "GenSubtargetInfo";
726   OS << "namespace llvm {\n";
727   OS << "class DFAPacketizer;\n";
728   OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
729      << "  explicit " << ClassName << "(StringRef TT, StringRef CPU, "
730      << "StringRef FS);\n"
731      << "public:\n"
732      << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
733      << " const;\n"
734      << "};\n";
735   OS << "} // End llvm namespace \n";
736
737   OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
738
739   OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
740   OS << "#undef GET_SUBTARGETINFO_CTOR\n";
741
742   OS << "namespace llvm {\n";
743   OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
744   OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
745   if (HasItineraries) {
746     OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcItinKV[];\n";
747     OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
748     OS << "extern const unsigned " << Target << "OperandCycles[];\n";
749     OS << "extern const unsigned " << Target << "ForwardingPathes[];\n";
750   }
751
752   OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, "
753      << "StringRef FS)\n"
754      << "  : TargetSubtargetInfo() {\n"
755      << "  InitMCSubtargetInfo(TT, CPU, FS, ";
756   if (NumFeatures)
757     OS << Target << "FeatureKV, ";
758   else
759     OS << "0, ";
760   if (NumProcs)
761     OS << Target << "SubTypeKV, ";
762   else
763     OS << "0, ";
764   if (HasItineraries) {
765     OS << Target << "ProcItinKV, "
766        << Target << "Stages, "
767        << Target << "OperandCycles, "
768        << Target << "ForwardingPathes, ";
769   } else
770     OS << "0, 0, 0, 0, ";
771   OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
772   OS << "} // End llvm namespace \n";
773
774   OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
775 }