SubtargetEmitter.cpp revision da96cf2029e47baf77df5c1ce6528a04246d6462
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 "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"
199489c04efc47a68af65e226e50f03d488094ffceJeff Cohen#include <algorithm>
204bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm;
214bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
227dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
23581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration.
24b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
251a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::Enumeration(raw_ostream &OS,
26581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   const char *ClassName,
27581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   bool isBits) {
28908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get all records of class and sort
29f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
3042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(DefList.begin(), DefList.end(), LessRecord());
314bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
32908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Open enumeration
33b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "enum {\n";
34da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
35908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each record
36f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = DefList.size(); i < N;) {
37f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
38f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Def = DefList[i];
39da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
40908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get and emit name
414222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << "  " << Def->getName();
42da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
43908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // If bit flags then emit expression (1 << i)
44f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (isBits)  OS << " = " << " 1 << " << i;
45908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
4610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
47f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
48da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
49f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
504bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
51da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
52908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Close enumeration
53b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
54b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
55b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
56b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
574222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// FeatureKeyValues - Emit data of all the subtarget features.  Used by the
584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// command line.
59b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
601a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
61908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort all the features
62f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> FeatureList =
63f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                           Records.getAllDerivedDefinitions("SubtargetFeature");
647c9a7728d9dd248ebee8f2dd969d303711d487a9Jim Grosbach  std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
65b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
66908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin feature table
67581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU features.\n"
68cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman     << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n";
69da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
70908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each feature
71dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey  for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
72f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next feature
73f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Feature = FeatureList[i];
74f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Feature->getName();
764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &CommandLineName = Feature->getValueAsString("Name");
774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Desc = Feature->getValueAsString("Desc");
78da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
79dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if (CommandLineName.empty()) continue;
80da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
81da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
82b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
83f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       << "\"" << CommandLineName << "\", "
84b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Desc << "\", "
854222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       << Name << ", ";
864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
87da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick    const std::vector<Record*> &ImpliesList =
884222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Feature->getValueAsListOfDefs("Implies");
89da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
904222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    if (ImpliesList.empty()) {
914222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      OS << "0";
924222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    } else {
934222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
944222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        OS << ImpliesList[j]->getName();
954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        if (++j < M) OS << " | ";
964222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      }
974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    }
984222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
994222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << " }";
100da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
10110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
102dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if ((i + 1) < N) OS << ",";
103da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
104f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
105b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  }
106da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
107908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End feature table
108b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
109b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
110908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Emit size of table
111b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"\nenum {\n";
112b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
113b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS<<"};\n";
114b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
115b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
116b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
117b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors.  Used by command
118b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line.
119b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
1201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
121908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort processor information
122f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcessorList =
123f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                          Records.getAllDerivedDefinitions("Processor");
12442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
125b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
126908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin processor table
127581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU subtype.\n"
128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
129da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
130908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor
131f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
132f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next processor
133f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Processor = ProcessorList[i];
134f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
1354222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
136da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick    const std::vector<Record*> &FeatureList =
137b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner      Processor->getValueAsListOfDefs("Features");
138da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
139908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Emit as { "cpu", "description", f1 | f2 | ... fn },
140b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
142b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"Select the " << Name << " processor\", ";
143da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
144f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (FeatureList.empty()) {
145b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey      OS << "0";
146b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    } else {
147f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      for (unsigned j = 0, M = FeatureList.size(); j < M;) {
1484222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        OS << FeatureList[j]->getName();
149f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey        if (++j < M) OS << " | ";
1504bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey      }
1514bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey    }
152da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    // The "0" is for the "implies" section of this data structure.
1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << ", 0 }";
155da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
15610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
157f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
158da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
159f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
1604bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
161da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
162908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End processor table
163b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
164b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
165908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Emit size of table
166d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"\nenum {\n";
167d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
168d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"};\n";
1694bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey}
170b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
171581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
1720d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
173908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Returns itinerary class count.
1740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
1755f54ce347368105260be2cec497b6a4199dc5789Evan Chengunsigned SubtargetEmitter::
1765f54ce347368105260be2cec497b6a4199dc5789Evan ChengCollectAllItinClasses(raw_ostream &OS,
1775f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                      std::map<std::string, unsigned> &ItinClassesMap,
1785f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                      std::vector<Record*> &ItinClassList) {
179f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // For each itinerary class
180f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = ItinClassList.size();
181f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < N; i++) {
182f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next itinerary class
1834222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *ItinClass = ItinClassList[i];
184908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get name of itinerary class
185908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Assign itinerary class a unique number
1864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinClassesMap[ItinClass->getName()] = i;
1870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
188da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
1896cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Emit size of table
1906cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
1916cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"  ItinClassesSize = " << N << "\n";
1926cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
1936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
194908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Return itinerary class count
195f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  return N;
1960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
1970d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
1980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
199fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryStageString - Compose a string containing the stage
200fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// data initialization for the specified itinerary.  N is the number
201fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// of stages.
2020d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
203928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikovvoid SubtargetEmitter::FormItineraryStageString(const std::string &Name,
204928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov                                                Record *ItinData,
205fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                std::string &ItinString,
206fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                unsigned &NStages) {
207f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // Get states list
2084222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling  const std::vector<Record*> &StageList =
2094222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinData->getValueAsListOfDefs("Stages");
210908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
211908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each stage
212f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = NStages = StageList.size();
2138dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb  for (unsigned i = 0; i < N;) {
214f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next stage
2154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *Stage = StageList[i];
216da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
21796085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
2180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    int Cycles = Stage->getValueAsInt("Cycles");
2197f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey    ItinString += "  { " + itostr(Cycles) + ", ";
220da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
221f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get unit list
2224222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
223da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
224908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each unit
225f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = UnitList.size(); j < M;) {
226f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Add name and bitwise or
227928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      ItinString += Name + "FU::" + UnitList[j]->getName();
228f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      if (++j < M) ItinString += " | ";
2290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
230da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
2311a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    int TimeInc = Stage->getValueAsInt("TimeInc");
2321a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    ItinString += ", " + itostr(TimeInc);
2331a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin
23496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    int Kind = Stage->getValueAsInt("Kind");
23596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov    ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
23696085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov
237908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Close off stage
238908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    ItinString += " }";
2398dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb    if (++i < N) ItinString += ", ";
2400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
244fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryOperandCycleString - Compose a string containing the
245fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle initialization for the specified itinerary.  N is the
246fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// number of operands that has cycles specified.
2470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
248fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
249fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                         std::string &ItinString, unsigned &NOperandCycles) {
250fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Get operand cycle list
251fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  const std::vector<int64_t> &OperandCycleList =
252fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinData->getValueAsListOfInts("OperandCycles");
253fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
254fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // For each operand cycle
255fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned N = NOperandCycles = OperandCycleList.size();
256fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  for (unsigned i = 0; i < N;) {
257fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    // Next operand cycle
258fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    const int OCycle = OperandCycleList[i];
259da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
260fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinString += "  " + itostr(OCycle);
261fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    if (++i < N) ItinString += ", ";
262fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  }
263fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin}
264fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
26563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Chengvoid SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
26663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 Record *ItinData,
26763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 std::string &ItinString,
26863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                                 unsigned NOperandCycles) {
26963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  const std::vector<Record*> &BypassList =
27063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinData->getValueAsListOfDefs("Bypasses");
27163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  unsigned N = BypassList.size();
2723881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  unsigned i = 0;
2733881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  for (; i < N;) {
27463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinString += Name + "Bypass::" + BypassList[i]->getName();
2753881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (++i < NOperandCycles) ItinString += ", ";
27663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  }
2773881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  for (; i < NOperandCycles;) {
27863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    ItinString += " 0";
2793881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (++i < NOperandCycles) ItinString += ", ";
28063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  }
28163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng}
28263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
283fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
284fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// EmitStageAndOperandCycleData - Generate unique itinerary stages and
285fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle tables.  Record itineraries for processors.
286fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
287fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
288f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       unsigned NItinClasses,
2895f54ce347368105260be2cec497b6a4199dc5789Evan Cheng       std::map<std::string, unsigned> &ItinClassesMap,
2905f54ce347368105260be2cec497b6a4199dc5789Evan Cheng       std::vector<Record*> &ItinClassList,
291f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::vector<std::vector<InstrItinerary> > &ProcList) {
292908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather processor iteraries
293f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcItinList =
294f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
295da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
296908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // If just no itinerary then don't bother
297f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  if (ProcItinList.size() < 2) return;
298908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
299928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  // Emit functional units for all the itineraries.
300928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
301928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    // Next record
302928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    Record *Proc = ProcItinList[i];
303928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
304928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
305928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    if (FUs.empty())
306928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      continue;
307928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
308928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    const std::string &Name = Proc->getName();
309928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
310928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov       << "namespace " << Name << "FU {\n";
311928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
312928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
313928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      OS << "  const unsigned " << FUs[j]->getName()
314928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov         << " = 1 << " << j << ";\n";
315928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
316928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov    OS << "}\n";
31763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
31863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng    std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP");
3193881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    if (BPs.size()) {
3203881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
3213881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng         << "\"\n" << "namespace " << Name << "Bypass {\n";
32263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
3233881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      OS << "  const unsigned NoBypass = 0;\n";
3243881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
3253881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng        OS << "  const unsigned " << BPs[j]->getName()
3263881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng           << " = 1 << " << j << ";\n";
32763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
3283881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng      OS << "}\n";
3293881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng    }
330928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  }
331928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
332908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin stages table
333928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov  std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n";
33496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
335da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
336fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Begin operand cycle table
337fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
338fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0, // No itinerary\n";
33963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
34063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  // Begin pipeline bypass table
3413881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n";
34263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "  0, // No itinerary\n";
343da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
344fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned StageCount = 1, OperandCycleCount = 1;
345fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
3463881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng  std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
347f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
348f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
349f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Proc = ProcItinList[i];
350da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
351908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
3524222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Proc->getName();
353da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
354908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
3550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
356da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
357908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Create and expand processor itinerary to cover all itinerary classes
358f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> ItinList;
359f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ItinList.resize(NItinClasses);
360da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
361f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get itinerary data list
362b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
363da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
364f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // For each itinerary data
365f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
366f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Next itinerary data
367f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      Record *ItinData = ItinDataList[j];
368da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
369908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Get string and stage count
370fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinStageString;
371f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      unsigned NStages;
372928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov      FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
373fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
374fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Get string and operand cycle count
375fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinOperandCycleString;
376fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned NOperandCycles;
377fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
378fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                      NOperandCycles);
379fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
38063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng      std::string ItinBypassString;
38163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng      FormItineraryBypassString(Name, ItinData, ItinBypassString,
38263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng                                NOperandCycles);
38363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
384fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if stage already exists and create if it doesn't
385fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindStage = 0;
386fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NStages > 0) {
387fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        FindStage = ItinStageMap[ItinStageString];
388fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindStage == 0) {
389fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
390fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n";
391fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
392fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinStageMap[ItinStageString] = FindStage = StageCount;
393fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          StageCount += NStages;
394fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinStageEnum++;
395fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
396fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      }
397da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
398fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if operand cycle already exists and create if it doesn't
399fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindOperandCycle = 0;
400fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NOperandCycles > 0) {
4013881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng        std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
4023881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng        FindOperandCycle = ItinOperandMap[ItinOperandString];
403fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindOperandCycle == 0) {
404fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Emit as  cycle, // index
405da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          OperandCycleTable += ItinOperandCycleString + ", // " +
406fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin            itostr(ItinOperandCycleEnum) + "\n";
407fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
408da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          ItinOperandMap[ItinOperandCycleString] =
409fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin            FindOperandCycle = OperandCycleCount;
41063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
41163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng          // Emit as bypass, // index
412da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          BypassTable += ItinBypassString + ", // " +
41363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng            itostr(ItinOperandCycleEnum) + "\n";
41463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
415fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          OperandCycleCount += NOperandCycles;
416fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinOperandCycleEnum++;
417fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
4180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
419da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
420908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Locate where to inject into processor itinerary table
4214222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
422fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned Find = ItinClassesMap[Name];
423da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
4245f54ce347368105260be2cec497b6a4199dc5789Evan Cheng      // Set up itinerary as location and location + stage count
4255f54ce347368105260be2cec497b6a4199dc5789Evan Cheng      unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps");
4265f54ce347368105260be2cec497b6a4199dc5789Evan Cheng      InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
4275f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                    FindOperandCycle,
4285f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                    FindOperandCycle + NOperandCycles};
4295f54ce347368105260be2cec497b6a4199dc5789Evan Cheng
430908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Inject - empty slots will be 0, 0
431f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ItinList[Find] = Intinerary;
4320d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
433da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
434908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Add process itinerary to list
435f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ProcList.push_back(ItinList);
4360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
43763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
4387f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  // Closing stage
43996085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov  StageTable += "  { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
440fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  StageTable += "};\n";
441fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
442fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Closing operand cycles
443fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0 // End itinerary\n";
444fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "};\n";
445fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
44663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "  0 // End itinerary\n";
44763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  BypassTable += "};\n";
44863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng
449fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Emit tables.
450fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << StageTable;
451fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << OperandCycleTable;
45263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng  OS << BypassTable;
453da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
454fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Emit size of tables
4556cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
456fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
457fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
4586cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
4590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
4600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
4610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
46210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries.
4630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
4641a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorData(raw_ostream &OS,
465f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      std::vector<std::vector<InstrItinerary> > &ProcList) {
466908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get an iterator for processor itinerary stages
467f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> >::iterator
468f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ProcListIter = ProcList.begin();
469da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
470908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor itinerary
471f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Itins =
472f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
473f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
474f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
475f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Itin = Itins[i];
476f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
477908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
4784222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Itin->getName();
479da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
480908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
4810d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
4820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
483908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Begin processor itinerary table
4840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "\n";
485cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman    OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
486da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
487908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each itinerary class
488f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
4891f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin    for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
490f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      InstrItinerary &Intinerary = ItinList[j];
491da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
492da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick      // Emit in the form of
493fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // { firstStage, lastStage, firstCycle, lastCycle } // index
494fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (Intinerary.FirstStage == 0) {
4955f54ce347368105260be2cec497b6a4199dc5789Evan Cheng        OS << "  { 1, 0, 0, 0, 0 }";
4960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      } else {
4975f54ce347368105260be2cec497b6a4199dc5789Evan Cheng        OS << "  { " <<
4985f54ce347368105260be2cec497b6a4199dc5789Evan Cheng          Intinerary.NumMicroOps << ", " <<
499da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          Intinerary.FirstStage << ", " <<
500da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          Intinerary.LastStage << ", " <<
501da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick          Intinerary.FirstOperandCycle << ", " <<
502fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          Intinerary.LastOperandCycle << " }";
5030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
504da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
5051f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin      OS << ", // " << j << "\n";
5060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
507da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
508908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // End processor itinerary table
5095f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    OS << "  { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
5100d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "};\n";
5110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
51210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey}
51310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
51410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
51510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table.
51610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
5171a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
51810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Gather and sort processor information
51910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  std::vector<Record*> ProcessorList =
52010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                          Records.getAllDerivedDefinitions("Processor");
52142d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
52210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
52310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Begin processor table
52410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "\n";
52510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
5267f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
527da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
52810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // For each processor
52910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
53010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Next processor
53110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    Record *Processor = ProcessorList[i];
53210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
5334222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
5344222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &ProcItin =
5354222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Processor->getValueAsDef("ProcItin")->getName();
536da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
53710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Emit as { "cpu", procinit },
53810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "  { "
53910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "\"" << Name << "\", "
54010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "(void *)&" << ProcItin;
541da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
54210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << " }";
543da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
54410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on ''if more in the list'' emit comma
54510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    if (++i < N) OS << ",";
546da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
54710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "\n";
54810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  }
549da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
55010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // End processor table
55110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "};\n";
55210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
55310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Emit size of table
55410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"\nenum {\n";
5557f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
55610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                            "sizeof(llvm::SubtargetInfoKV)\n";
55710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"};\n";
5580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
5590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
5600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
5610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns.
5620d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
5631a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitData(raw_ostream &OS) {
564f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::map<std::string, unsigned> ItinClassesMap;
5655f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  // Gather and sort all itinerary classes
5665f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  std::vector<Record*> ItinClassList =
5675f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    Records.getAllDerivedDefinitions("InstrItinClass");
5685f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
569da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
570908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Enumerate all the itinerary classes
5715f54ce347368105260be2cec497b6a4199dc5789Evan Cheng  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
5725f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                                ItinClassList);
5736cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Make sure the rest is worth the effort
574387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
575da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick
5766cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
5775f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    std::vector<std::vector<InstrItinerary> > ProcList;
5786cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the stage data
5795f54ce347368105260be2cec497b6a4199dc5789Evan Cheng    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
5805f54ce347368105260be2cec497b6a4199dc5789Evan Cheng                                 ItinClassList, ProcList);
5816cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor itinerary data
5826cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorData(OS, ProcList);
5836cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor lookup data
5846cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorLookup(OS);
5856cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
5860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
5870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
5880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
589581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing
590581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string.
591581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
5921a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
593f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Features =
594f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("SubtargetFeature");
59542d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(Features.begin(), Features.end(), LessRecord());
596581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
597da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
598da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick     << "// subtarget options.\n"
59941a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov     << "std::string llvm::";
600581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << Target;
601581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
6024222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                  const std::string &CPU) {\n"
603f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene     << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
604f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
6054222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  SubtargetFeatures Features(FS);\n"
6064222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  Features.setCPUIfNone(CPU);\n"
6074222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
6084222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                    FeatureKV, FeatureKVSize);\n";
6094222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
610f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < Features.size(); i++) {
611f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
612f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *R = Features[i];
6134222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Instance = R->getName();
6144222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Value = R->getValueAsString("Value");
6154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Attribute = R->getValueAsString("Attribute");
61619c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng
617db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    if (Value=="true" || Value=="false")
618db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen      OS << "  if ((Bits & " << Instance << ") != 0) "
619db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen         << Attribute << " = " << Value << ";\n";
620db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    else
621da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute <<
622db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen            " < " << Value << ") " << Attribute << " = " << Value << ";\n";
623581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  }
6244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
6256cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
6266cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    OS << "\n"
6276cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey       << "  InstrItinerary *Itinerary = (InstrItinerary *)"
6284222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
6293881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, "
6303881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng       << "ForwardingPathes, Itinerary);\n";
6316cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
63241a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov
63341a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov  OS << "  return Features.getCPU();\n"
63441a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov     << "}\n";
635581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey}
636581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
63741a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov//
638b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter.
639b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
6401a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::run(raw_ostream &OS) {
64167db883487fca3472fdde51e931657e22d4d0495Chris Lattner  Target = CodeGenTarget(Records).getName();
642581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
643b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
644b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
645bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel  OS << "#include \"llvm/Support/Debug.h\"\n";
646bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel  OS << "#include \"llvm/Support/raw_ostream.h\"\n";
6470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
6480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
649928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov
650928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov//  Enumeration(OS, "FuncUnit", true);
651928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov//  OS<<"\n";
652908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  Enumeration(OS, "InstrItinClass", false);
653908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  OS<<"\n";
654581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "SubtargetFeature", true);
655581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
656b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  FeatureKeyValues(OS);
657581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
658b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  CPUKeyValues(OS);
659581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
6600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitData(OS);
6610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS<<"\n";
662581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  ParseFeaturesFunction(OS);
663b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
664