Home | History | Annotate | Download | only in TableGen
      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 }
    776