SubtargetEmitter.cpp revision a11a6287a504d1d7503e744d14314df1e696f506
14bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
24bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
34bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//                     The LLVM Compiler Infrastructure
44bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source
63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details.
74bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
84bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===//
94bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
103d87811ce0381c3364ce10aed77de8231a03bc48Chris Lattner// This tablegen backend emits subtarget enumerations.
114bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
124bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===//
134bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
144bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "CodeGenTarget.h"
154bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/ADT/StringExtras.h"
166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/MC/MCInstrItineraries.h"
174bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/Support/Debug.h"
186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Record.h"
196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h"
209489c04efc47a68af65e226e50f03d488094ffceJeff Cohen#include <algorithm>
216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <map>
226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <string>
236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector>
244bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm;
254bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace {
276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass SubtargetEmitter {
286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  RecordKeeper &Records;
306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  std::string Target;
316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  bool HasItineraries;
326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits);
346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  unsigned FeatureKeyValues(raw_ostream &OS);
356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  unsigned CPUKeyValues(raw_ostream &OS);
366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  unsigned CollectAllItinClasses(raw_ostream &OS,
376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                 std::map<std::string,unsigned> &ItinClassesMap,
386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                 std::vector<Record*> &ItinClassList);
396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void FormItineraryStageString(const std::string &Names,
406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                Record *ItinData, std::string &ItinString,
416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                unsigned &NStages);
426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                       unsigned &NOperandCycles);
446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void FormItineraryBypassString(const std::string &Names,
456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                 Record *ItinData,
466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                                 std::string &ItinString, unsigned NOperandCycles);
476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                     std::map<std::string, unsigned> &ItinClassesMap,
496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                     std::vector<Record*> &ItinClassList,
506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                     std::vector<std::vector<InstrItinerary> > &ProcList);
516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitItineraryProp(raw_ostream &OS, const Record *R, const char *Name,
526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                         char Separator);
536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitProcessorData(raw_ostream &OS,
546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                         std::vector<Record*> &ItinClassList,
556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                         std::vector<std::vector<InstrItinerary> > &ProcList);
566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitProcessorLookup(raw_ostream &OS);
576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void EmitData(raw_ostream &OS);
586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures,
596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen                             unsigned NumProcs);
606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic:
626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {}
636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
646f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  void run(raw_ostream &o);
656f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
666f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen};
676f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace
686f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
697dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
70581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration.
71b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
721a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::Enumeration(raw_ostream &OS,
73581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   const char *ClassName,
74581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   bool isBits) {
75908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get all records of class and sort
76f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
7742d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(DefList.begin(), DefList.end(), LessRecord());
784bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
79b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng  unsigned N = DefList.size();
8094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (N == 0)
8194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    return;
82b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng  if (N > 64) {
83b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng    errs() << "Too many (> 64) subtarget features!\n";
84b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng    exit(1);
85b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng  }
86b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng
8794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace " << Target << " {\n";
8894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
89ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen  // For bit flag enumerations with more than 32 items, emit constants.
90ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen  // Emit an enum for everything else.
91ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen  if (isBits && N > 32) {
92ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    // For each record
93ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    for (unsigned i = 0; i < N; i++) {
94ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // Next record
95ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      Record *Def = DefList[i];
9694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
97ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // Get and emit name and expression (1 << i)
98ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      OS << "  const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n";
99ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    }
100ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen  } else {
101ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    // Open enumeration
102ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    OS << "enum {\n";
103da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
104ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    // For each record
105ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    for (unsigned i = 0; i < N;) {
106ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // Next record
107ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      Record *Def = DefList[i];
108da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
109ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // Get and emit name
110ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      OS << "  " << Def->getName();
111908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
112ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // If bit flags then emit expression (1 << i)
113ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      if (isBits)  OS << " = " << " 1ULL << " << i;
114da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
115ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      // Depending on 'if more in the list' emit comma
116ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      if (++i < N) OS << ",";
117ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen
118ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen      OS << "\n";
119ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    }
120da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
121ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    // Close enumeration
122ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen    OS << "};\n";
123ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen  }
12494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
12594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "}\n";
126b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
127b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
1294222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// FeatureKeyValues - Emit data of all the subtarget features.  Used by the
1304222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// command line.
131b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
13294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengunsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
133908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort all the features
134f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> FeatureList =
135f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                           Records.getAllDerivedDefinitions("SubtargetFeature");
13694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
13794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (FeatureList.empty())
13894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    return 0;
13994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
1407c9a7728d9dd248ebee8f2dd969d303711d487a9Jim Grosbach  std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
142908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin feature table
143581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU features.\n"
1441a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer     << "extern const llvm::SubtargetFeatureKV " << Target
1451a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer     << "FeatureKV[] = {\n";
146da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
147908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each feature
14894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  unsigned NumFeatures = 0;
149dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey  for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
150f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next feature
151f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Feature = FeatureList[i];
152f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Feature->getName();
1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &CommandLineName = Feature->getValueAsString("Name");
1554222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Desc = Feature->getValueAsString("Desc");
156da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
157dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if (CommandLineName.empty()) continue;
158da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
159da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
160b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
161f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       << "\"" << CommandLineName << "\", "
162b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Desc << "\", "
16394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng       << Target << "::" << Name << ", ";
1644222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
165da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick    const std::vector<Record*> &ImpliesList =
1664222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Feature->getValueAsListOfDefs("Implies");
167da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
1684222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    if (ImpliesList.empty()) {
169b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng      OS << "0ULL";
1704222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    } else {
1714222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
17294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng        OS << Target << "::" << ImpliesList[j]->getName();
1734222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        if (++j < M) OS << " | ";
1744222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      }
1754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    }
1764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
1774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << " }";
17894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    ++NumFeatures;
179da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
18010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
181dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if ((i + 1) < N) OS << ",";
182da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
183f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
184b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  }
185da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
186908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End feature table
187b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
188b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
18994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  return NumFeatures;
190b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
191b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
192b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
193b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors.  Used by command
194b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line.
195b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
19694214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengunsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
197908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort processor information
198f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcessorList =
199f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                          Records.getAllDerivedDefinitions("Processor");
20042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
201b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
202908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin processor table
203581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU subtype.\n"
2041a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer     << "extern const llvm::SubtargetFeatureKV " << Target
2051a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer     << "SubTypeKV[] = {\n";
206da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
207908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor
208f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
209f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next processor
210f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Processor = ProcessorList[i];
211f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
2124222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
213da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick    const std::vector<Record*> &FeatureList =
214b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner      Processor->getValueAsListOfDefs("Features");
215da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
216908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Emit as { "cpu", "description", f1 | f2 | ... fn },
217b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
218b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
219b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"Select the " << Name << " processor\", ";
220da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
221f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (FeatureList.empty()) {
222b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng      OS << "0ULL";
223b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    } else {
224f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      for (unsigned j = 0, M = FeatureList.size(); j < M;) {
22594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng        OS << Target << "::" << FeatureList[j]->getName();
226f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey        if (++j < M) OS << " | ";
2274bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey      }
2284bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey    }
229da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
2304222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    // The "0" is for the "implies" section of this data structure.
231b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng    OS << ", 0ULL }";
232da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
23310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
234f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
235da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
236f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
2374bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
238da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
239908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End processor table
240b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
241b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
24294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  return ProcessorList.size();
2434bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey}
244b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
245581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
247908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Returns itinerary class count.
2480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2495f54ce347368105260be2cec497b6a4199dc5789Evan Chengunsigned SubtargetEmitter::
2505f54ce347368105260be2cec497b6a4199dc5789Evan ChengCollectAllItinClasses(raw_ostream &OS,
2515f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                      std::map<std::string, unsigned> &ItinClassesMap,
2525f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                      std::vector<Record*> &ItinClassList) {
253f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // For each itinerary class
254f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = ItinClassList.size();
255f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < N; i++) {
256f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next itinerary class
2574222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *ItinClass = ItinClassList[i];
258908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get name of itinerary class
259908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Assign itinerary class a unique number
2604222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinClassesMap[ItinClass->getName()] = i;
2610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
262da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
263908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Return itinerary class count
264f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  return N;
2650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
268fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryStageString - Compose a string containing the stage
269fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// data initialization for the specified itinerary.  N is the number
270fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// of stages.
2710d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
272928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikovvoid SubtargetEmitter::FormItineraryStageString(const std::string &Name,
273928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov                                                Record *ItinData,
274fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                std::string &ItinString,
275fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                unsigned &NStages) {
276f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // Get states list
2774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling  const std::vector<Record*> &StageList =
2784222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinData->getValueAsListOfDefs("Stages");
279908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
280908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each stage
281f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = NStages = StageList.size();
2828dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb  for (unsigned i = 0; i < N;) {
283f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next stage
2844222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *Stage = StageList[i];
285da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
28696085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
2870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    int Cycles = Stage->getValueAsInt("Cycles");
2887f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey    ItinString += "  { " + itostr(Cycles) + ", ";
289da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
290f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get unit list
2914222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
292da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
293908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each unit
294f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = UnitList.size(); j < M;) {
295f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Add name and bitwise or
296928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      ItinString += Name + "FU::" + UnitList[j]->getName();
297f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      if (++j < M) ItinString += " | ";
2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
299da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
3001a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    int TimeInc = Stage->getValueAsInt("TimeInc");
3011a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    ItinString += ", " + itostr(TimeInc);
3021a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin
30396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    int Kind = Stage->getValueAsInt("Kind");
30496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
30596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov
306908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Close off stage
307908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    ItinString += " }";
3088dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb    if (++i < N) ItinString += ", ";
3090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
3100d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
3110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
313fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryOperandCycleString - Compose a string containing the
314fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle initialization for the specified itinerary.  N is the
315fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// number of operands that has cycles specified.
3160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
317fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
318fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                         std::string &ItinString, unsigned &NOperandCycles) {
319fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Get operand cycle list
320fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  const std::vector<int64_t> &OperandCycleList =
321fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinData->getValueAsListOfInts("OperandCycles");
322fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
323fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // For each operand cycle
324fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned N = NOperandCycles = OperandCycleList.size();
325fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  for (unsigned i = 0; i < N;) {
326fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    // Next operand cycle
327fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    const int OCycle = OperandCycleList[i];
328da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
329fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinString += "  " + itostr(OCycle);
330fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    if (++i < N) ItinString += ", ";
331fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  }
332fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin}
333fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
33463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Chengvoid SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
33563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 Record *ItinData,
33663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 std::string &ItinString,
33763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 unsigned NOperandCycles) {
33863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  const std::vector<Record*> &BypassList =
33963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinData->getValueAsListOfDefs("Bypasses");
34063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  unsigned N = BypassList.size();
3413881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  unsigned i = 0;
3423881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  for (; i < N;) {
34363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinString += Name + "Bypass::" + BypassList[i]->getName();
3443881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (++i < NOperandCycles) ItinString += ", ";
34563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  }
3463881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  for (; i < NOperandCycles;) {
34763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinString += " 0";
3483881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (++i < NOperandCycles) ItinString += ", ";
34963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  }
35063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng}
35163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
352fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
353fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// EmitStageAndOperandCycleData - Generate unique itinerary stages and
354fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle tables.  Record itineraries for processors.
355fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
356fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
357f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       unsigned NItinClasses,
3585f54ce347368105260be2cec497b6a4199dc5789Evan Cheng       std::map<std::string, unsigned> &ItinClassesMap,
3595f54ce347368105260be2cec497b6a4199dc5789Evan Cheng       std::vector<Record*> &ItinClassList,
360f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::vector<std::vector<InstrItinerary> > &ProcList) {
361908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather processor iteraries
362f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcItinList =
363f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
364da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
365908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // If just no itinerary then don't bother
366f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  if (ProcItinList.size() < 2) return;
367908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
368928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  // Emit functional units for all the itineraries.
369928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
370928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    // Next record
371928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    Record *Proc = ProcItinList[i];
372928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
373928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
374928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    if (FUs.empty())
375928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      continue;
376928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
377928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    const std::string &Name = Proc->getName();
378928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
379928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov       << "namespace " << Name << "FU {\n";
380928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
381928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
382b460a3382961c5be9952a75d46228f624edbd39fHal Finkel      OS << "  const unsigned " << FUs[j]->getName()
383b460a3382961c5be9952a75d46228f624edbd39fHal Finkel         << " = 1 << " << j << ";\n";
384928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
385928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    OS << "}\n";
38663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
38763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP");
3883881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (BPs.size()) {
3893881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
3903881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng         << "\"\n" << "namespace " << Name << "Bypass {\n";
39163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
3921a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      OS << "  const unsigned NoBypass = 0;\n";
3933881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
3941a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer        OS << "  const unsigned " << BPs[j]->getName()
3953881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng           << " = 1 << " << j << ";\n";
39663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
3973881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      OS << "}\n";
3983881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    }
399928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  }
400928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
401908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin stages table
4021a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  std::string StageTable = "\nextern const llvm::InstrStage " + Target +
4031a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer                           "Stages[] = {\n";
40496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
405da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
406fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Begin operand cycle table
4071a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  std::string OperandCycleTable = "extern const unsigned " + Target +
40894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    "OperandCycles[] = {\n";
409fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0, // No itinerary\n";
41063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
41163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  // Begin pipeline bypass table
4121a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  std::string BypassTable = "extern const unsigned " + Target +
413a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick    "ForwardingPaths[] = {\n";
41463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "  0, // No itinerary\n";
415da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
416fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned StageCount = 1, OperandCycleCount = 1;
4173881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
418f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
419f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
420f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Proc = ProcItinList[i];
421da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
422908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
4234222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Proc->getName();
424da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
425f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get itinerary data list
426b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
427d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    std::vector<InstrItinerary> ItinList;
428d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick
429d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    // Add an empty itinerary.
430d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    if (ItinDataList.empty()) {
431d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      ProcList.push_back(ItinList);
432d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      continue;
433d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    }
434d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick
435d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    // Expand processor itinerary to cover all itinerary classes
436d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    ItinList.resize(NItinClasses);
437da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
438f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // For each itinerary data
439f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
440f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Next itinerary data
441f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      Record *ItinData = ItinDataList[j];
442da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
443908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Get string and stage count
444fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinStageString;
445f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      unsigned NStages;
446928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
447fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
448fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Get string and operand cycle count
449fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinOperandCycleString;
450fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned NOperandCycles;
451fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
452fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                      NOperandCycles);
453fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
45463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng      std::string ItinBypassString;
45563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng      FormItineraryBypassString(Name, ItinData, ItinBypassString,
45663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                NOperandCycles);
45763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
458fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if stage already exists and create if it doesn't
459fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindStage = 0;
460fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NStages > 0) {
461fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        FindStage = ItinStageMap[ItinStageString];
462fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindStage == 0) {
463234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
464234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          StageTable += ItinStageString + ", // " + itostr(StageCount);
465234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          if (NStages > 1)
466234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick            StageTable += "-" + itostr(StageCount + NStages - 1);
467234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          StageTable += "\n";
468fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
469fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinStageMap[ItinStageString] = FindStage = StageCount;
470fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          StageCount += NStages;
471fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
472fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      }
473da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
474fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if operand cycle already exists and create if it doesn't
475fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindOperandCycle = 0;
476fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NOperandCycles > 0) {
4773881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng        std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
4783881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng        FindOperandCycle = ItinOperandMap[ItinOperandString];
479fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindOperandCycle == 0) {
480fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Emit as  cycle, // index
481234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          OperandCycleTable += ItinOperandCycleString + ", // ";
482234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          std::string OperandIdxComment = itostr(OperandCycleCount);
483234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          if (NOperandCycles > 1)
484234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick            OperandIdxComment += "-"
485234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick              + itostr(OperandCycleCount + NOperandCycles - 1);
486234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          OperandCycleTable += OperandIdxComment + "\n";
487fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
488da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          ItinOperandMap[ItinOperandCycleString] =
489fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin            FindOperandCycle = OperandCycleCount;
49063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng          // Emit as bypass, // index
491234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick          BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
492fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          OperandCycleCount += NOperandCycles;
493fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
4940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
495da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
496908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Locate where to inject into processor itinerary table
4974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
498fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned Find = ItinClassesMap[Name];
499da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
5005f54ce347368105260be2cec497b6a4199dc5789Evan Cheng      // Set up itinerary as location and location + stage count
501506bb19d10fd3f1a9486e9c8bef632f13da8fe4aChandler Carruth      int NumUOps = ItinData->getValueAsInt("NumMicroOps");
5025f54ce347368105260be2cec497b6a4199dc5789Evan Cheng      InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
5035f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                    FindOperandCycle,
5045f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                    FindOperandCycle + NOperandCycles};
5055f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
506908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Inject - empty slots will be 0, 0
507f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ItinList[Find] = Intinerary;
5080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
509da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
510908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Add process itinerary to list
511f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ProcList.push_back(ItinList);
5120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
51363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
5147f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  // Closing stage
51596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
516fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  StageTable += "};\n";
517fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
518fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Closing operand cycles
519fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0 // End itinerary\n";
520fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "};\n";
521fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
52263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "  0 // End itinerary\n";
52363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "};\n";
52463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
525fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Emit tables.
526fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << StageTable;
527fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << OperandCycleTable;
52863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  OS << BypassTable;
5290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
5300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
531fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trickvoid SubtargetEmitter::EmitItineraryProp(raw_ostream &OS, const Record *R,
532fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick                                         const char *Name, char Separator) {
533fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick  OS << "  ";
534fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick  int V = R->getValueAsInt(Name);
535fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick  if (V >= 0)
536fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << V << Separator << " // " << Name;
537fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick  else
5380076ad7eebb46c07288eec20e385dd8eaff736fbAndrew Trick    OS << "InstrItineraryProps::Default" << Name << Separator;
539fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick  OS << '\n';
540fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick}
541fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick
5420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
54310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries.
5440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
545234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trickvoid SubtargetEmitter::
546234823297e0fc0babddd2ab84054bf68f64a54d1Andrew TrickEmitProcessorData(raw_ostream &OS,
547234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick                  std::vector<Record*> &ItinClassList,
548234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick                  std::vector<std::vector<InstrItinerary> > &ProcList) {
549fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick
550908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get an iterator for processor itinerary stages
551f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> >::iterator
552f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ProcListIter = ProcList.begin();
553da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
554908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor itinerary
555f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Itins =
556f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
557f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
558f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
559f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Itin = Itins[i];
560f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
561908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
5624222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Itin->getName();
563da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
564908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
565fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    // Begin processor itinerary properties
566fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << "\n";
567fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << "static const llvm::InstrItineraryProps " << Name << "Props(\n";
568fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    EmitItineraryProp(OS, Itin, "IssueWidth", ',');
569fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    EmitItineraryProp(OS, Itin, "MinLatency", ',');
570fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    EmitItineraryProp(OS, Itin, "LoadLatency", ',');
571fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    EmitItineraryProp(OS, Itin, "HighLatency", ' ');
572fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << ");\n";
573fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick
574908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each itinerary class
575f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
576d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    if (!ItinList.empty()) {
577d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
578da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
579d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      // Begin processor itinerary table
580d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "\n";
581d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "static const llvm::InstrItinerary " << Name << "Entries"
582d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick         << "[] = {\n";
583d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick
584d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
585d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        InstrItinerary &Intinerary = ItinList[j];
586d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick
587d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        // Emit in the form of
588d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        // { firstStage, lastStage, firstCycle, lastCycle } // index
589d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        if (Intinerary.FirstStage == 0) {
590d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick          OS << "  { 1, 0, 0, 0, 0 }";
591d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        } else {
592d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick          OS << "  { " <<
593d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick            Intinerary.NumMicroOps << ", " <<
594d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick            Intinerary.FirstStage << ", " <<
595d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick            Intinerary.LastStage << ", " <<
596d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick            Intinerary.FirstOperandCycle << ", " <<
597d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick            Intinerary.LastOperandCycle << " }";
598d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        }
599d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick        OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
600d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      }
601d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      // End processor itinerary table
602d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "  { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
603d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "};\n";
6040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
605fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << '\n';
606fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << "static const llvm::InstrItinerarySubtargetValue "
607fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick       << Name << " = {\n";
608fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << "  &" << Name << "Props,\n";
609d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    if (ItinList.empty())
610d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "  0\n";
611d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick    else
612d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick      OS << "  " << Name << "Entries\n";
613fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick    OS << "};\n";
6140d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
61510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey}
61610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
61710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
61810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table.
61910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
6201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
62110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Gather and sort processor information
62210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  std::vector<Record*> ProcessorList =
62310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                          Records.getAllDerivedDefinitions("Processor");
62442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
62510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
62610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Begin processor table
62710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "\n";
62810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
6291a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer     << "extern const llvm::SubtargetInfoKV "
63094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng     << Target << "ProcItinKV[] = {\n";
631da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
63210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // For each processor
63310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
63410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Next processor
63510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    Record *Processor = ProcessorList[i];
63610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
6374222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
6384222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &ProcItin =
6394222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Processor->getValueAsDef("ProcItin")->getName();
640da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
64110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Emit as { "cpu", procinit },
64210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "  { "
64310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "\"" << Name << "\", "
64410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "(void *)&" << ProcItin;
645da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
64610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << " }";
647da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
64810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on ''if more in the list'' emit comma
64910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    if (++i < N) OS << ",";
650da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
65110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "\n";
65210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  }
653da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
65410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // End processor table
65510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "};\n";
6560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
6570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
6580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
6590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns.
6600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
6611a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitData(raw_ostream &OS) {
662f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::map<std::string, unsigned> ItinClassesMap;
6635f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  // Gather and sort all itinerary classes
6645f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  std::vector<Record*> ItinClassList =
6655f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    Records.getAllDerivedDefinitions("InstrItinClass");
6665f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
667da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
668908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Enumerate all the itinerary classes
6695f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
6705f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                                ItinClassList);
6716cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Make sure the rest is worth the effort
672387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
673da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
6746cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
6755f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    std::vector<std::vector<InstrItinerary> > ProcList;
6766cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the stage data
6775f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
6785f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                 ItinClassList, ProcList);
6796cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor itinerary data
680234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick    EmitProcessorData(OS, ItinClassList, ProcList);
6816cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor lookup data
6826cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorLookup(OS);
6836cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
6840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
6850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
6860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
687581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing
688581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string.
689581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
69094214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengvoid SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
69194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng                                             unsigned NumFeatures,
69294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng                                             unsigned NumProcs) {
693f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Features =
694f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("SubtargetFeature");
69542d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(Features.begin(), Features.end(), LessRecord());
696581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
697da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
698da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick     << "// subtarget options.\n"
699276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng     << "void llvm::";
700581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << Target;
7010ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n"
702f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene     << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
7033f696e568bae8afa5986e7af48156c2bac041ba7Hal Finkel     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n";
70494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
70594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (Features.empty()) {
70694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "}\n";
70794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    return;
70894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  }
70994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
7100ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  OS << "  uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n";
7114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
712f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < Features.size(); i++) {
713f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
714f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *R = Features[i];
7154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Instance = R->getName();
7164222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Value = R->getValueAsString("Value");
7174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Attribute = R->getValueAsString("Attribute");
71819c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng
719db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    if (Value=="true" || Value=="false")
7200ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng      OS << "  if ((Bits & " << Target << "::"
7210ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng         << Instance << ") != 0) "
722db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen         << Attribute << " = " << Value << ";\n";
723db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    else
7240ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng      OS << "  if ((Bits & " << Target << "::"
7250ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng         << Instance << ") != 0 && "
72694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng         << Attribute << " < " << Value << ") "
72794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng         << Attribute << " = " << Value << ";\n";
7286cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
72941a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov
730276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng  OS << "}\n";
731581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey}
732581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
73341a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov//
734b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter.
735b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
7361a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::run(raw_ostream &OS) {
73767db883487fca3472fdde51e931657e22d4d0495Chris Lattner  Target = CodeGenTarget(Records).getName();
738581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
7396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
740b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
741ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n";
742ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "#undef GET_SUBTARGETINFO_ENUM\n";
743ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
744ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "namespace llvm {\n";
745ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  Enumeration(OS, "SubtargetFeature", true);
746ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "} // End llvm namespace \n";
747ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n";
748ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
74994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
75094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
751928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
75294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
753c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#if 0
754c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  OS << "namespace {\n";
755c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#endif
75694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  unsigned NumFeatures = FeatureKeyValues(OS);
757c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  OS << "\n";
75894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  unsigned NumProcs = CPUKeyValues(OS);
759c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  OS << "\n";
7600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitData(OS);
761c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  OS << "\n";
762c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#if 0
763c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  OS << "}\n";
764c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#endif
76594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
76694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  // MCInstrInfo initialization routine.
76794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "static inline void Init" << Target
76859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng     << "MCSubtargetInfo(MCSubtargetInfo *II, "
76959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng     << "StringRef TT, StringRef CPU, StringRef FS) {\n";
77059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng  OS << "  II->InitMCSubtargetInfo(TT, CPU, FS, ";
77194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (NumFeatures)
77294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "FeatureKV, ";
77394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  else
77494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, ";
77594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (NumProcs)
77694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "SubTypeKV, ";
77794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  else
77894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, ";
77994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (HasItineraries) {
78094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "ProcItinKV, "
78194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng       << Target << "Stages, "
78294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng       << Target << "OperandCycles, "
783a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick       << Target << "ForwardingPaths, ";
78494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  } else
78594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, 0, 0, 0, ";
78694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
78794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
78894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "} // End llvm namespace \n";
78994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
79094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
79194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
79294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
79394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
79494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
79594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#include \"llvm/Support/Debug.h\"\n";
79694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#include \"llvm/Support/raw_ostream.h\"\n";
79794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  ParseFeaturesFunction(OS, NumFeatures, NumProcs);
79894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
79994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
80094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
8015b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng  // Create a TargetSubtargetInfo subclass to hide the MC layer initialization.
80294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
80394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#undef GET_SUBTARGETINFO_HEADER\n";
80494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
80594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  std::string ClassName = Target + "GenSubtargetInfo";
80694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
807dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  OS << "class DFAPacketizer;\n";
8085b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng  OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
8090ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng     << "  explicit " << ClassName << "(StringRef TT, StringRef CPU, "
8100ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng     << "StringRef FS);\n"
811dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta     << "public:\n"
812464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop     << "  DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
813dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta     << " const;\n"
81494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng     << "};\n";
81594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "} // End llvm namespace \n";
81694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
81794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
81894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
81994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
82094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#undef GET_SUBTARGETINFO_CTOR\n";
82194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
82294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "namespace llvm {\n";
8231a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n";
8241a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n";
825c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  if (HasItineraries) {
8261a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcItinKV[];\n";
8271a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    OS << "extern const llvm::InstrStage " << Target << "Stages[];\n";
8281a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    OS << "extern const unsigned " << Target << "OperandCycles[];\n";
829a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick    OS << "extern const unsigned " << Target << "ForwardingPaths[];\n";
830c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng  }
831c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng
8320ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng  OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, "
8330ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng     << "StringRef FS)\n"
8345b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng     << "  : TargetSubtargetInfo() {\n"
83559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng     << "  InitMCSubtargetInfo(TT, CPU, FS, ";
83694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (NumFeatures)
83794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "FeatureKV, ";
83894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  else
83994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, ";
84094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (NumProcs)
84194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "SubTypeKV, ";
84294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  else
84394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, ";
84494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  if (HasItineraries) {
84594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << Target << "ProcItinKV, "
84694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng       << Target << "Stages, "
84794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng       << Target << "OperandCycles, "
848a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick       << Target << "ForwardingPaths, ";
84994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  } else
85094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng    OS << "0, 0, 0, 0, ";
85194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
85294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "} // End llvm namespace \n";
85394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng
85494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng  OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
855b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
8566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
8576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm {
8586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
8596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) {
8606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen  SubtargetEmitter(RK).run(OS);
8616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}
8626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen
8636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace
864