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