SubtargetEmitter.cpp revision 0d841e05677bdc55d003720e85e12d28dfe31862
14bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
24bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
34bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//                     The LLVM Compiler Infrastructure
44bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
54bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// This file was developed by James M. Laskey and is distributed under
64bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// the University of Illinois Open Source License. See LICENSE.TXT for details.
74bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
84bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===//
94bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
104bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// This tablegen backend emits subtarget enumerations.
114bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
124bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===//
134bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
144bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "SubtargetEmitter.h"
154bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "CodeGenTarget.h"
164bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "Record.h"
174bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/ADT/StringExtras.h"
184bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/Support/Debug.h"
194bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm;
204bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
217dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
227dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Convenience types.
237dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
244bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeytypedef std::vector<Record*> RecordList;
250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeystruct RecordListIter {
270d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  std::vector<Record*>::iterator RI;
280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  std::vector<Record*>::iterator E;
290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter(RecordList &RL)
310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      : RI(RL.begin()), E(RL.end())
320d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  {}
330d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
340d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  bool isMore() const { return RI != E; }
350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  Record *next() { return isMore() ? *RI++ : NULL; }
370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey};
380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeystruct DefListIter {
400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  ListInit *List;
410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  unsigned N;
420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  unsigned i;
430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  DefListIter(Record *R, const std::string &Name)
450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      : List(R->getValueAsListInit(Name)), N(List->getSize()), i(0)
460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  {}
470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  bool isMore() const { return i < N; }
490d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
500d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  Record *next() {
510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (isMore()) {
520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i++))) {
530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        return DI->getDef();
540d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    return NULL;
570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey};
594bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
607dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
617dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by name function.
627dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
637dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecord {
647dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  bool operator()(const Record *Rec1, const Record *Rec2) const {
657dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey    return Rec1->getName() < Rec2->getName();
667dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  }
677dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey};
684bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
697dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
707dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by field "Name" function.
717dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
727dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecordFieldName {
737dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  bool operator()(const Record *Rec1, const Record *Rec2) const {
747dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey    return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
757dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  }
767dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey};
777dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey
784bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
79581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration.
80b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
81581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::Enumeration(std::ostream &OS,
82581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   const char *ClassName,
83581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   bool isBits) {
84581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  RecordList Defs = Records.getAllDerivedDefinitions(ClassName);
85581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  sort(Defs.begin(), Defs.end(), LessRecord());
864bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
87b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  int i = 0;
884bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
89b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "enum {\n";
904bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter DI(Defs);
920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *R = DI.next()) {
93b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    std::string Instance = R->getName();
94b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  "
95581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey       << Instance;
96581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    if (isBits) {
97581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey      OS << " = "
98581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey         << " 1 << " << i++;
99581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    }
1000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << (DI.isMore() ? ",\n" : "\n");
1014bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
1024bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
103b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
104b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
105b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
106b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
107b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// FeatureKeyValues - Emit data of all the subtarget features.  Used by command
108b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line.
109b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
110b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
111b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
112b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  sort(Features.begin(), Features.end(), LessRecord());
113b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
114581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU features.\n"
115b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey     << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
1160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter FI(Features);
1170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *R = FI.next()) {
118b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    std::string Instance = R->getName();
119b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    std::string Name = R->getValueAsString("Name");
120b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    std::string Desc = R->getValueAsString("Desc");
121b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
122b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
123b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Desc << "\", "
124b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << Instance
1250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey       << (FI.isMore() ? " },\n" : " }\n");
126b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  }
127b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
129b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"\nenum {\n";
130b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
131b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"};\n";
132b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
133b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
134b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
135b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors.  Used by command
136b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line.
137b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
138b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
139b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  RecordList Processors = Records.getAllDerivedDefinitions("Processor");
140b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  sort(Processors.begin(), Processors.end(), LessRecordFieldName());
141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
142581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU subtype.\n"
143b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
1440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter PI(Processors);
1450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *R = PI.next()) {
146b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    std::string Name = R->getValueAsString("Name");
1470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    DefListIter FI(R, "Features");
1480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
149b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
150b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
151b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"Select the " << Name << " processor\", ";
152b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
1530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (!FI.isMore()) {
154b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey      OS << "0";
155b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    } else {
1560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      while (Record *Feature = FI.next()) {
1570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        std::string Name = Feature->getName();
1580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << Name;
1590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        if (FI.isMore()) OS << " | ";
1604bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey      }
1614bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey    }
162b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
1630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << (PI.isMore() ? " },\n" : " }\n");
1644bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
165b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
166b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
167d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"\nenum {\n";
168d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
169d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"};\n";
1704bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey}
171b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
172581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
1730d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
1740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
1750d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyunsigned SubtargetEmitter::CollectAllItinClasses(IntMap &ItinClassesMap) {
1760d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordList ICL = Records.getAllDerivedDefinitions("InstrItinClass");
1770d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  sort(ICL.begin(), ICL.end(), LessRecord());
1780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
1790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter ICI(ICL);
1800d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  unsigned Index = 0;
1810d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *ItinClass = ICI.next()) {
1820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    std::string Name = ItinClass->getName();
1830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    ItinClassesMap[Name] = Index++;
1840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
1850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
1860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  return Index;
1870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
1880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
1890d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
1900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// FormItineraryString - Compose a string containing the data initialization
1910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// for the specified itinerary.  N is the number of stages.
1920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
1930d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::FormItineraryString(Record *ItinData,
1940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                           std::string &ItinString,
1950d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                           unsigned &N) {
1960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  DefListIter SLI(ItinData, "Stages");
1970d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  N = SLI.N;
1980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *Stage = SLI.next()) {
1990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    int Cycles = Stage->getValueAsInt("Cycles");
2000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    ItinString += "  ,{ " + itostr(Cycles) + ", ";
2010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2020d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    DefListIter ULI(Stage, "Units");
2030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    while (Record *Unit = ULI.next()) {
2040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      std::string Name = Unit->getName();
2050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      ItinString += Name;
2060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (ULI.isMore())ItinString += " | ";
2070d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
2080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2100d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  ItinString += " }";
2110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2130d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2140d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitStageData - Generate unique itinerary stages.  Record itineraries for
2150d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// processors.
2160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitStageData(std::ostream &OS,
2180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                     unsigned N,
2190d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                     IntMap &ItinClassesMap,
2200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                     ProcessorList &ProcList) {
2210d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "static llvm::InstrStage Stages[] = {\n"
2220d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        "  { 0, 0 } // No itinerary\n";
2230d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2240d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  IntMap ItinMap;
2250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  unsigned Index  = 1;
2260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries");
2270d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter II(Itins);
2280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *Itin = II.next()) {
2290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    std::string Name = Itin->getName();
2300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
2310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2320d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    IntineraryList IL;
2330d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    IL.resize(N);
2340d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    DefListIter IDLI(Itin, "IID");
2360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    while (Record *ItinData = IDLI.next()) {
2370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      std::string ItinString;
2380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      unsigned M;
2390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      FormItineraryString(ItinData, ItinString, M);
2400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      unsigned Find = ItinMap[ItinString];
2420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (Find == 0) {
2440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << ItinString << " // " << Index << "\n";
2450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        ItinMap[ItinString] = Find = Index++;
2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
2470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      InstrItinerary Intinerary = { Find, Find + M };
2490d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2500d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      std::string Name = ItinData->getValueAsDef("TheClass")->getName();
2510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      Find = ItinClassesMap[Name];
2520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      IL[Find] = Intinerary;
2530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
2540d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    ProcList.push_back(IL);
2560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "};\n";
2590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2620d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitProcessData - Generate data for processor itineraries.
2630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2640d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitProcessData(std::ostream &OS,
2650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                       ProcessorList &ProcList) {
2660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  ProcessorList::iterator PLI = ProcList.begin();
2670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries");
2680d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter II(Itins);
2690d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *Itin = II.next()) {
2700d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    std::string Name = Itin->getName();
2710d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
2720d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2730d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "\n";
2740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "static llvm::InstrItinerary " << Name << "[] = {\n";
2750d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2760d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    IntineraryList &IL = *PLI++;
2770d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    unsigned Index = 0;
2780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    for (IntineraryList::iterator ILI = IL.begin(), E = IL.end(); ILI != E;) {
2790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      InstrItinerary &Intinerary = *ILI++;
2800d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2810d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (Intinerary.First == 0) {
2820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << "  { 0, 0 }";
2830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      } else {
2840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << "  { " << Intinerary.First << ", " << Intinerary.Last << " }";
2850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
2860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (ILI != E) OS << ",";
2880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      OS << " // " << Index++ << "\n";
2890d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
2900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "};\n";
2910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2930d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2950d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns.
2960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2970d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitData(std::ostream &OS) {
2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  IntMap ItinClassesMap;
2990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  ProcessorList ProcList;
3000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  unsigned N = CollectAllItinClasses(ItinClassesMap);
3020d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitStageData(OS, N, ItinClassesMap, ProcList);
3030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitProcessData(OS, ProcList);
3040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
3050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
307581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing
308581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string.
309581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
310581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
311581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
312581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  sort(Features.begin(), Features.end(), LessRecord());
313581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
314581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
315581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "// subtarget options.\n"
316581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "void llvm::";
317581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << Target;
318581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
319581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "                                  const std::string &CPU) {\n"
320581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "  SubtargetFeatures Features(FS);\n"
321581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "  Features.setCPUIfNone(CPU);\n"
322581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
323581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey        "                                    FeatureKV, FeatureKVSize);\n";
324581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
3250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  RecordListIter FI(Features);
3260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  while (Record *R = FI.next()) {
327581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    std::string Instance = R->getName();
328581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    std::string Name = R->getValueAsString("Name");
329581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    std::string Type = R->getValueAsString("Type");
330581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    std::string Attribute = R->getValueAsString("Attribute");
331581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
332581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey    OS << "  " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
333581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  }
334581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "}\n";
335581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey}
336581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
337b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
338b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter.
339b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
340b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::run(std::ostream &OS) {
3416c302fc0757c20a6de52a788ffc675e5c5980971Jim Laskey  Target = CodeGenTarget().getName();
342581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
343b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
344b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
3450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
3460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
347b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
348581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "FuncUnit", true);
349581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
350581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "InstrItinClass", false);
351581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
352581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "SubtargetFeature", true);
353581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
354b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  FeatureKeyValues(OS);
355581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
356b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  CPUKeyValues(OS);
357581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
3580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitData(OS);
3590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS<<"\n";
360581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  ParseFeaturesFunction(OS);
361b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
362