SubtargetEmitter.cpp revision f0fd3afeffcb41202147f755bf770061f189a42b
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";
344bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
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];
39f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
40908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get and emit name
414222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << "  " << Def->getName();
42908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
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 << ",";
48f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
49f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
504bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
514bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
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";
69908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
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");
78908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
79dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if (CommandLineName.empty()) continue;
80dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey
81da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach    // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
82b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
83f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       << "\"" << CommandLineName << "\", "
84b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Desc << "\", "
854222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       << Name << ", ";
864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
874222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &ImpliesList =
884222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Feature->getValueAsListOfDefs("Implies");
894222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
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 << " }";
100f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
10110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
102dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if ((i + 1) < N) OS << ",";
103f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
104f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
105b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  }
106908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
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";
129908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
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");
1364222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &FeatureList =
137b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner      Processor->getValueAsListOfDefs("Features");
1380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
139908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Emit as { "cpu", "description", f1 | f2 | ... fn },
140b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
142b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"Select the " << Name << " processor\", ";
143b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
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    }
152b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    // The "0" is for the "implies" section of this data structure.
1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << ", 0 }";
155f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
15610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
157f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
158f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
159f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
1604bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
161908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
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//
1751a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarunsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS,
1766cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey                              std::map<std::string, unsigned> &ItinClassesMap) {
177908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort all itinerary classes
178f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ItinClassList =
179f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                            Records.getAllDerivedDefinitions("InstrItinClass");
18042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
181f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
182f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // For each itinerary class
183f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = ItinClassList.size();
184f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < N; i++) {
185f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next itinerary class
1864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *ItinClass = ItinClassList[i];
187908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get name of itinerary class
188908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Assign itinerary class a unique number
1894222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinClassesMap[ItinClass->getName()] = i;
1900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
1910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
1926cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Emit size of table
1936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
1946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"  ItinClassesSize = " << N << "\n";
1956cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
1966cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
197908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Return itinerary class count
198f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  return N;
1990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
202fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryStageString - Compose a string containing the stage
203fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// data initialization for the specified itinerary.  N is the number
204fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// of stages.
2050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
206fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryStageString(Record *ItinData,
207fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                std::string &ItinString,
208fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                                unsigned &NStages) {
209f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // Get states list
2104222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling  const std::vector<Record*> &StageList =
2114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinData->getValueAsListOfDefs("Stages");
212908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
213908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each stage
214f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = NStages = StageList.size();
2158dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb  for (unsigned i = 0; i < N;) {
216f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next stage
2174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *Stage = StageList[i];
218f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
2191a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc }
2200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    int Cycles = Stage->getValueAsInt("Cycles");
2217f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey    ItinString += "  { " + itostr(Cycles) + ", ";
2220d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
223f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get unit list
2244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
225f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
226908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each unit
227f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = UnitList.size(); j < M;) {
228f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Add name and bitwise or
2294222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      ItinString += UnitList[j]->getName();
230f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      if (++j < M) ItinString += " | ";
2310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
232908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
2331a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    int TimeInc = Stage->getValueAsInt("TimeInc");
2341a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin    ItinString += ", " + itostr(TimeInc);
2351a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin
236908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Close off stage
237908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    ItinString += " }";
2388dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb    if (++i < N) ItinString += ", ";
2390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
243fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryOperandCycleString - Compose a string containing the
244fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle initialization for the specified itinerary.  N is the
245fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// number of operands that has cycles specified.
2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
247fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
248fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                         std::string &ItinString, unsigned &NOperandCycles) {
249fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Get operand cycle list
250fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  const std::vector<int64_t> &OperandCycleList =
251fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinData->getValueAsListOfInts("OperandCycles");
252fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
253fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // For each operand cycle
254fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned N = NOperandCycles = OperandCycleList.size();
255fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  for (unsigned i = 0; i < N;) {
256fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    // Next operand cycle
257fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    const int OCycle = OperandCycleList[i];
258fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
259fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    ItinString += "  " + itostr(OCycle);
260fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    if (++i < N) ItinString += ", ";
261fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  }
262fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin}
263fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
264fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
265fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// EmitStageAndOperandCycleData - Generate unique itinerary stages and
266fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle tables.  Record itineraries for processors.
267fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin//
268fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
269f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       unsigned NItinClasses,
270f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::map<std::string, unsigned> &ItinClassesMap,
271f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::vector<std::vector<InstrItinerary> > &ProcList) {
272908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather processor iteraries
273f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcItinList =
274f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
275908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
276908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // If just no itinerary then don't bother
277f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  if (ProcItinList.size() < 2) return;
278908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
279908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin stages table
280fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  std::string StageTable = "static const llvm::InstrStage Stages[] = {\n";
281fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  StageTable += "  { 0, 0, 0 }, // No itinerary\n";
2820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
283fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Begin operand cycle table
284fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
285fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0, // No itinerary\n";
286fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
287fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned StageCount = 1, OperandCycleCount = 1;
288fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
289fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap;
290f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
291f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
292f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Proc = ProcItinList[i];
293f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
294908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
2954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Proc->getName();
296908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
297908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
2990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
300908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Create and expand processor itinerary to cover all itinerary classes
301f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> ItinList;
302f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ItinList.resize(NItinClasses);
303f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
304f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get itinerary data list
305b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
3060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
307f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // For each itinerary data
308f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
309f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Next itinerary data
310f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      Record *ItinData = ItinDataList[j];
311f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
312908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Get string and stage count
313fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinStageString;
314f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      unsigned NStages;
315fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      FormItineraryStageString(ItinData, ItinStageString, NStages);
316fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
317fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Get string and operand cycle count
318fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      std::string ItinOperandCycleString;
319fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned NOperandCycles;
320fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
321fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                      NOperandCycles);
322fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
323fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if stage already exists and create if it doesn't
324fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindStage = 0;
325fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NStages > 0) {
326fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        FindStage = ItinStageMap[ItinStageString];
327fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindStage == 0) {
328fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index
329fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n";
330fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
331fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinStageMap[ItinStageString] = FindStage = StageCount;
332fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          StageCount += NStages;
333fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinStageEnum++;
334fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
335fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      }
3360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
337fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Check to see if operand cycle already exists and create if it doesn't
338fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned FindOperandCycle = 0;
339fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (NOperandCycles > 0) {
340fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString];
341fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        if (FindOperandCycle == 0) {
342fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Emit as  cycle, // index
343fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          OperandCycleTable += ItinOperandCycleString + ", // " +
344fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin            itostr(ItinOperandCycleEnum) + "\n";
345fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          // Record Itin class number.
346fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinOperandCycleMap[ItinOperandCycleString] =
347fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin            FindOperandCycle = OperandCycleCount;
348fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          OperandCycleCount += NOperandCycles;
349fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          ItinOperandCycleEnum++;
350fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        }
3510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
3520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
353908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Set up itinerary as location and location + stage count
354fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      InstrItinerary Intinerary = { FindStage, FindStage + NStages,
355fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin                                    FindOperandCycle, FindOperandCycle + NOperandCycles};
3560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
357908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Locate where to inject into processor itinerary table
3584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
359fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      unsigned Find = ItinClassesMap[Name];
360908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
361908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Inject - empty slots will be 0, 0
362f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ItinList[Find] = Intinerary;
3630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
3640d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
365908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Add process itinerary to list
366f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ProcList.push_back(ItinList);
3670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
3680d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3697f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  // Closing stage
370fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  StageTable += "  { 0, 0, 0 } // End itinerary\n";
371fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  StageTable += "};\n";
372fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
373fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Closing operand cycles
374fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "  0 // End itinerary\n";
375fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OperandCycleTable += "};\n";
376fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin
377fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Emit tables.
378fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << StageTable;
379fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS << OperandCycleTable;
3806cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
381fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  // Emit size of tables
3826cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
383fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
384fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin  OS<<"  OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
3856cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
3860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
3870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
38910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries.
3900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
3911a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorData(raw_ostream &OS,
392f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      std::vector<std::vector<InstrItinerary> > &ProcList) {
393908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get an iterator for processor itinerary stages
394f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> >::iterator
395f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ProcListIter = ProcList.begin();
396908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
397908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor itinerary
398f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Itins =
399f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
400f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
401f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
402f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Itin = Itins[i];
403f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
404908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
4054222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Itin->getName();
406908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
407908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
4080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
4090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
410908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Begin processor itinerary table
4110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "\n";
412cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman    OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
4130d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
414908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each itinerary class
415f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
4161f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin    for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
417f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      InstrItinerary &Intinerary = ItinList[j];
4180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
419fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // Emit in the form of
420fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      // { firstStage, lastStage, firstCycle, lastCycle } // index
421fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin      if (Intinerary.FirstStage == 0) {
422fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        OS << "  { 0, 0, 0, 0 }";
4230d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      } else {
424fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin        OS << "  { " << Intinerary.FirstStage << ", " <<
425fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          Intinerary.LastStage << ", " <<
426fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          Intinerary.FirstOperandCycle << ", " <<
427fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin          Intinerary.LastOperandCycle << " }";
4280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
4290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
4301f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin      OS << ", // " << j << "\n";
4310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
432908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
433908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // End processor itinerary table
4341f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin    OS << "  { ~0U, ~0U, ~0U, ~0U } // end marker\n";
4350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "};\n";
4360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
43710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey}
43810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
43910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
44010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table.
44110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
4421a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
44310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Gather and sort processor information
44410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  std::vector<Record*> ProcessorList =
44510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                          Records.getAllDerivedDefinitions("Processor");
44642d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
44710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
44810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Begin processor table
44910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "\n";
45010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
4517f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
45210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
45310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // For each processor
45410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
45510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Next processor
45610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    Record *Processor = ProcessorList[i];
45710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
4584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
4594222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &ProcItin =
4604222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Processor->getValueAsDef("ProcItin")->getName();
46110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
46210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Emit as { "cpu", procinit },
46310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "  { "
46410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "\"" << Name << "\", "
46510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "(void *)&" << ProcItin;
46610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
46710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << " }";
46810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
46910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on ''if more in the list'' emit comma
47010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    if (++i < N) OS << ",";
47110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
47210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "\n";
47310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  }
47410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
47510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // End processor table
47610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "};\n";
47710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
47810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Emit size of table
47910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"\nenum {\n";
4807f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
48110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                            "sizeof(llvm::SubtargetInfoKV)\n";
48210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"};\n";
4830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
4840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
4850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
4860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns.
4870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
4881a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitData(raw_ostream &OS) {
489f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::map<std::string, unsigned> ItinClassesMap;
490f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> > ProcList;
4910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
492908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Enumerate all the itinerary classes
4936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
4946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Make sure the rest is worth the effort
495387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
4966cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
4976cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
4986cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the stage data
499fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin    EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList);
5006cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor itinerary data
5016cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorData(OS, ProcList);
5026cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor lookup data
5036cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorLookup(OS);
5046cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
5050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
5060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
5070d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
508581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing
509581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string.
510581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
5111a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
512f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Features =
513f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("SubtargetFeature");
51442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(Features.begin(), Features.end(), LessRecord());
515581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
516581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
5174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "// subtarget options.\n"
51841a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov     << "std::string llvm::";
519581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << Target;
520581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
5214222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                  const std::string &CPU) {\n"
522f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene     << "  DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
523f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene     << "  DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
5244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  SubtargetFeatures Features(FS);\n"
5254222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  Features.setCPUIfNone(CPU);\n"
5264222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
5274222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                    FeatureKV, FeatureKVSize);\n";
5284222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
529f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < Features.size(); i++) {
530f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
531f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *R = Features[i];
5324222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Instance = R->getName();
5334222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Value = R->getValueAsString("Value");
5344222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Attribute = R->getValueAsString("Attribute");
53519c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng
536db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    if (Value=="true" || Value=="false")
537db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen      OS << "  if ((Bits & " << Instance << ") != 0) "
538db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen         << Attribute << " = " << Value << ";\n";
539db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    else
540db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute <<
541db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen            " < " << Value << ") " << Attribute << " = " << Value << ";\n";
542581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  }
5434222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
5446cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
5456cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    OS << "\n"
5466cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey       << "  InstrItinerary *Itinerary = (InstrItinerary *)"
5474222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
548fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin       << "  InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n";
5496cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
55041a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov
55141a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov  OS << "  return Features.getCPU();\n"
55241a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov     << "}\n";
553581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey}
554581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
55541a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov//
556b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter.
557b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
5581a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::run(raw_ostream &OS) {
5596c302fc0757c20a6de52a788ffc675e5c5980971Jim Laskey  Target = CodeGenTarget().getName();
560581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
561b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
562b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
563bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel  OS << "#include \"llvm/Support/Debug.h\"\n";
564bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel  OS << "#include \"llvm/Support/raw_ostream.h\"\n";
5650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
5660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
567b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
568581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "FuncUnit", true);
569581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
570908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  Enumeration(OS, "InstrItinClass", false);
571908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  OS<<"\n";
572581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "SubtargetFeature", true);
573581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
574b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  FeatureKeyValues(OS);
575581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
576b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  CPUKeyValues(OS);
577581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
5780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitData(OS);
5790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS<<"\n";
580581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  ParseFeaturesFunction(OS);
581b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
582