blob: c823cb16fc51879e43b31efe8190c8cd6629d813 [file] [log] [blame]
Jim Laskey4bb9cbb2005-10-21 19:00:04 +00001//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner30609102007-12-29 20:37:13 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Jim Laskey4bb9cbb2005-10-21 19:00:04 +00007//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner3d878112006-03-03 02:04:07 +000010// This tablegen backend emits subtarget enumerations.
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000011//
12//===----------------------------------------------------------------------===//
13
14#include "SubtargetEmitter.h"
15#include "CodeGenTarget.h"
16#include "Record.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/Support/Debug.h"
Jeff Cohen9489c042005-10-28 01:43:09 +000019#include <algorithm>
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000020using namespace llvm;
21
Jim Laskey7dc02042005-10-22 07:59:56 +000022//
Jim Laskey581a8f72005-10-26 17:30:34 +000023// Enumeration - Emit the specified class as an enumeration.
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000024//
Daniel Dunbar1a551802009-07-03 00:10:29 +000025void SubtargetEmitter::Enumeration(raw_ostream &OS,
Jim Laskey581a8f72005-10-26 17:30:34 +000026 const char *ClassName,
27 bool isBits) {
Jim Laskey908ae272005-10-28 15:20:43 +000028 // Get all records of class and sort
Jim Laskeyf7bcde02005-10-28 21:47:29 +000029 std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
Duraid Madina42d24c72005-12-30 14:56:37 +000030 std::sort(DefList.begin(), DefList.end(), LessRecord());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000031
Jim Laskey908ae272005-10-28 15:20:43 +000032 // Open enumeration
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000033 OS << "enum {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +000034
Jim Laskey908ae272005-10-28 15:20:43 +000035 // For each record
Evan Chengb6a63882011-04-15 19:35:46 +000036 unsigned N = DefList.size();
37 if (N > 64) {
38 errs() << "Too many (> 64) subtarget features!\n";
39 exit(1);
40 }
41
42 for (unsigned i = 0; i < N;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +000043 // Next record
44 Record *Def = DefList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +000045
Jim Laskey908ae272005-10-28 15:20:43 +000046 // Get and emit name
Bill Wendling4222d802007-05-04 20:38:40 +000047 OS << " " << Def->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +000048
Jim Laskey908ae272005-10-28 15:20:43 +000049 // If bit flags then emit expression (1 << i)
Evan Chengb6a63882011-04-15 19:35:46 +000050 if (isBits) OS << " = " << " 1ULL << " << i;
Jim Laskey908ae272005-10-28 15:20:43 +000051
Jim Laskey10b1dd92005-10-31 17:16:01 +000052 // Depending on 'if more in the list' emit comma
Jim Laskeyf7bcde02005-10-28 21:47:29 +000053 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +000054
Jim Laskeyf7bcde02005-10-28 21:47:29 +000055 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000056 }
Andrew Trickda96cf22011-04-01 01:56:55 +000057
Jim Laskey908ae272005-10-28 15:20:43 +000058 // Close enumeration
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000059 OS << "};\n";
60}
61
62//
Bill Wendling4222d802007-05-04 20:38:40 +000063// FeatureKeyValues - Emit data of all the subtarget features. Used by the
64// command line.
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000065//
Daniel Dunbar1a551802009-07-03 00:10:29 +000066void SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +000067 // Gather and sort all the features
Jim Laskeyf7bcde02005-10-28 21:47:29 +000068 std::vector<Record*> FeatureList =
69 Records.getAllDerivedDefinitions("SubtargetFeature");
Jim Grosbach7c9a7722008-09-11 17:05:32 +000070 std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000071
Jim Laskey908ae272005-10-28 15:20:43 +000072 // Begin feature table
Jim Laskey581a8f72005-10-26 17:30:34 +000073 OS << "// Sorted (by key) array of values for CPU features.\n"
Dan Gohmancfbb2f02008-03-25 21:45:14 +000074 << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +000075
Jim Laskey908ae272005-10-28 15:20:43 +000076 // For each feature
Jim Laskeydbe40062006-12-12 20:55:58 +000077 for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +000078 // Next feature
79 Record *Feature = FeatureList[i];
80
Bill Wendling4222d802007-05-04 20:38:40 +000081 const std::string &Name = Feature->getName();
82 const std::string &CommandLineName = Feature->getValueAsString("Name");
83 const std::string &Desc = Feature->getValueAsString("Desc");
Andrew Trickda96cf22011-04-01 01:56:55 +000084
Jim Laskeydbe40062006-12-12 20:55:58 +000085 if (CommandLineName.empty()) continue;
Andrew Trickda96cf22011-04-01 01:56:55 +000086
Jim Grosbachda4231f2009-03-26 16:17:51 +000087 // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000088 OS << " { "
Jim Laskeyf7bcde02005-10-28 21:47:29 +000089 << "\"" << CommandLineName << "\", "
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000090 << "\"" << Desc << "\", "
Bill Wendling4222d802007-05-04 20:38:40 +000091 << Name << ", ";
92
Andrew Trickda96cf22011-04-01 01:56:55 +000093 const std::vector<Record*> &ImpliesList =
Bill Wendling4222d802007-05-04 20:38:40 +000094 Feature->getValueAsListOfDefs("Implies");
Andrew Trickda96cf22011-04-01 01:56:55 +000095
Bill Wendling4222d802007-05-04 20:38:40 +000096 if (ImpliesList.empty()) {
Evan Chengb6a63882011-04-15 19:35:46 +000097 OS << "0ULL";
Bill Wendling4222d802007-05-04 20:38:40 +000098 } else {
99 for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
100 OS << ImpliesList[j]->getName();
101 if (++j < M) OS << " | ";
102 }
103 }
104
105 OS << " }";
Andrew Trickda96cf22011-04-01 01:56:55 +0000106
Jim Laskey10b1dd92005-10-31 17:16:01 +0000107 // Depending on 'if more in the list' emit comma
Jim Laskeydbe40062006-12-12 20:55:58 +0000108 if ((i + 1) < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000109
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000110 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000111 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000112
Jim Laskey908ae272005-10-28 15:20:43 +0000113 // End feature table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000114 OS << "};\n";
115
Jim Laskey908ae272005-10-28 15:20:43 +0000116 // Emit size of table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000117 OS<<"\nenum {\n";
118 OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
119 OS<<"};\n";
120}
121
122//
123// CPUKeyValues - Emit data of all the subtarget processors. Used by command
124// line.
125//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000126void SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +0000127 // Gather and sort processor information
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000128 std::vector<Record*> ProcessorList =
129 Records.getAllDerivedDefinitions("Processor");
Duraid Madina42d24c72005-12-30 14:56:37 +0000130 std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000131
Jim Laskey908ae272005-10-28 15:20:43 +0000132 // Begin processor table
Jim Laskey581a8f72005-10-26 17:30:34 +0000133 OS << "// Sorted (by key) array of values for CPU subtype.\n"
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000134 << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000135
Jim Laskey908ae272005-10-28 15:20:43 +0000136 // For each processor
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000137 for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
138 // Next processor
139 Record *Processor = ProcessorList[i];
140
Bill Wendling4222d802007-05-04 20:38:40 +0000141 const std::string &Name = Processor->getValueAsString("Name");
Andrew Trickda96cf22011-04-01 01:56:55 +0000142 const std::vector<Record*> &FeatureList =
Chris Lattnerb0e103d2005-10-28 22:49:02 +0000143 Processor->getValueAsListOfDefs("Features");
Andrew Trickda96cf22011-04-01 01:56:55 +0000144
Jim Laskey908ae272005-10-28 15:20:43 +0000145 // Emit as { "cpu", "description", f1 | f2 | ... fn },
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000146 OS << " { "
147 << "\"" << Name << "\", "
148 << "\"Select the " << Name << " processor\", ";
Andrew Trickda96cf22011-04-01 01:56:55 +0000149
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000150 if (FeatureList.empty()) {
Evan Chengb6a63882011-04-15 19:35:46 +0000151 OS << "0ULL";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000152 } else {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000153 for (unsigned j = 0, M = FeatureList.size(); j < M;) {
Bill Wendling4222d802007-05-04 20:38:40 +0000154 OS << FeatureList[j]->getName();
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000155 if (++j < M) OS << " | ";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000156 }
157 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000158
Bill Wendling4222d802007-05-04 20:38:40 +0000159 // The "0" is for the "implies" section of this data structure.
Evan Chengb6a63882011-04-15 19:35:46 +0000160 OS << ", 0ULL }";
Andrew Trickda96cf22011-04-01 01:56:55 +0000161
Jim Laskey10b1dd92005-10-31 17:16:01 +0000162 // Depending on 'if more in the list' emit comma
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000163 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000164
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000165 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000166 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000167
Jim Laskey908ae272005-10-28 15:20:43 +0000168 // End processor table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000169 OS << "};\n";
170
Jim Laskey908ae272005-10-28 15:20:43 +0000171 // Emit size of table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000172 OS<<"\nenum {\n";
173 OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
174 OS<<"};\n";
175}
Jim Laskey7dc02042005-10-22 07:59:56 +0000176
Jim Laskey581a8f72005-10-26 17:30:34 +0000177//
Jim Laskey0d841e02005-10-27 19:47:21 +0000178// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
Jim Laskey908ae272005-10-28 15:20:43 +0000179// Returns itinerary class count.
Jim Laskey0d841e02005-10-27 19:47:21 +0000180//
Evan Cheng5f54ce32010-09-09 18:18:55 +0000181unsigned SubtargetEmitter::
182CollectAllItinClasses(raw_ostream &OS,
183 std::map<std::string, unsigned> &ItinClassesMap,
184 std::vector<Record*> &ItinClassList) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000185 // For each itinerary class
186 unsigned N = ItinClassList.size();
187 for (unsigned i = 0; i < N; i++) {
188 // Next itinerary class
Bill Wendling4222d802007-05-04 20:38:40 +0000189 const Record *ItinClass = ItinClassList[i];
Jim Laskey908ae272005-10-28 15:20:43 +0000190 // Get name of itinerary class
Jim Laskey908ae272005-10-28 15:20:43 +0000191 // Assign itinerary class a unique number
Bill Wendling4222d802007-05-04 20:38:40 +0000192 ItinClassesMap[ItinClass->getName()] = i;
Jim Laskey0d841e02005-10-27 19:47:21 +0000193 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000194
Jim Laskey6cee6302005-11-01 20:06:59 +0000195 // Emit size of table
196 OS<<"\nenum {\n";
197 OS<<" ItinClassesSize = " << N << "\n";
198 OS<<"};\n";
199
Jim Laskey908ae272005-10-28 15:20:43 +0000200 // Return itinerary class count
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000201 return N;
Jim Laskey0d841e02005-10-27 19:47:21 +0000202}
203
204//
David Goodwinfac85412009-08-17 16:02:57 +0000205// FormItineraryStageString - Compose a string containing the stage
206// data initialization for the specified itinerary. N is the number
207// of stages.
Jim Laskey0d841e02005-10-27 19:47:21 +0000208//
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000209void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
210 Record *ItinData,
David Goodwinfac85412009-08-17 16:02:57 +0000211 std::string &ItinString,
212 unsigned &NStages) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000213 // Get states list
Bill Wendling4222d802007-05-04 20:38:40 +0000214 const std::vector<Record*> &StageList =
215 ItinData->getValueAsListOfDefs("Stages");
Jim Laskey908ae272005-10-28 15:20:43 +0000216
217 // For each stage
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000218 unsigned N = NStages = StageList.size();
Christopher Lamb8dadf6b2007-04-22 09:04:24 +0000219 for (unsigned i = 0; i < N;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000220 // Next stage
Bill Wendling4222d802007-05-04 20:38:40 +0000221 const Record *Stage = StageList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000222
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000223 // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
Jim Laskey0d841e02005-10-27 19:47:21 +0000224 int Cycles = Stage->getValueAsInt("Cycles");
Jim Laskey7f39c142005-11-03 22:47:41 +0000225 ItinString += " { " + itostr(Cycles) + ", ";
Andrew Trickda96cf22011-04-01 01:56:55 +0000226
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000227 // Get unit list
Bill Wendling4222d802007-05-04 20:38:40 +0000228 const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
Andrew Trickda96cf22011-04-01 01:56:55 +0000229
Jim Laskey908ae272005-10-28 15:20:43 +0000230 // For each unit
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000231 for (unsigned j = 0, M = UnitList.size(); j < M;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000232 // Add name and bitwise or
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000233 ItinString += Name + "FU::" + UnitList[j]->getName();
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000234 if (++j < M) ItinString += " | ";
Jim Laskey0d841e02005-10-27 19:47:21 +0000235 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000236
David Goodwin1a8f36e2009-08-12 18:31:53 +0000237 int TimeInc = Stage->getValueAsInt("TimeInc");
238 ItinString += ", " + itostr(TimeInc);
239
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000240 int Kind = Stage->getValueAsInt("Kind");
241 ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
242
Jim Laskey908ae272005-10-28 15:20:43 +0000243 // Close off stage
244 ItinString += " }";
Christopher Lamb8dadf6b2007-04-22 09:04:24 +0000245 if (++i < N) ItinString += ", ";
Jim Laskey0d841e02005-10-27 19:47:21 +0000246 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000247}
248
249//
David Goodwinfac85412009-08-17 16:02:57 +0000250// FormItineraryOperandCycleString - Compose a string containing the
251// operand cycle initialization for the specified itinerary. N is the
252// number of operands that has cycles specified.
Jim Laskey0d841e02005-10-27 19:47:21 +0000253//
David Goodwinfac85412009-08-17 16:02:57 +0000254void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
255 std::string &ItinString, unsigned &NOperandCycles) {
256 // Get operand cycle list
257 const std::vector<int64_t> &OperandCycleList =
258 ItinData->getValueAsListOfInts("OperandCycles");
259
260 // For each operand cycle
261 unsigned N = NOperandCycles = OperandCycleList.size();
262 for (unsigned i = 0; i < N;) {
263 // Next operand cycle
264 const int OCycle = OperandCycleList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000265
David Goodwinfac85412009-08-17 16:02:57 +0000266 ItinString += " " + itostr(OCycle);
267 if (++i < N) ItinString += ", ";
268 }
269}
270
Evan Cheng63d66ee2010-09-28 23:50:49 +0000271void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
272 Record *ItinData,
273 std::string &ItinString,
274 unsigned NOperandCycles) {
275 const std::vector<Record*> &BypassList =
276 ItinData->getValueAsListOfDefs("Bypasses");
277 unsigned N = BypassList.size();
Evan Cheng3881cb72010-09-29 22:42:35 +0000278 unsigned i = 0;
279 for (; i < N;) {
Evan Cheng63d66ee2010-09-28 23:50:49 +0000280 ItinString += Name + "Bypass::" + BypassList[i]->getName();
Evan Cheng3881cb72010-09-29 22:42:35 +0000281 if (++i < NOperandCycles) ItinString += ", ";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000282 }
Evan Cheng3881cb72010-09-29 22:42:35 +0000283 for (; i < NOperandCycles;) {
Evan Cheng63d66ee2010-09-28 23:50:49 +0000284 ItinString += " 0";
Evan Cheng3881cb72010-09-29 22:42:35 +0000285 if (++i < NOperandCycles) ItinString += ", ";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000286 }
287}
288
David Goodwinfac85412009-08-17 16:02:57 +0000289//
290// EmitStageAndOperandCycleData - Generate unique itinerary stages and
291// operand cycle tables. Record itineraries for processors.
292//
293void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000294 unsigned NItinClasses,
Evan Cheng5f54ce32010-09-09 18:18:55 +0000295 std::map<std::string, unsigned> &ItinClassesMap,
296 std::vector<Record*> &ItinClassList,
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000297 std::vector<std::vector<InstrItinerary> > &ProcList) {
Jim Laskey908ae272005-10-28 15:20:43 +0000298 // Gather processor iteraries
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000299 std::vector<Record*> ProcItinList =
300 Records.getAllDerivedDefinitions("ProcessorItineraries");
Andrew Trickda96cf22011-04-01 01:56:55 +0000301
Jim Laskey908ae272005-10-28 15:20:43 +0000302 // If just no itinerary then don't bother
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000303 if (ProcItinList.size() < 2) return;
Jim Laskey908ae272005-10-28 15:20:43 +0000304
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000305 // Emit functional units for all the itineraries.
306 for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
307 // Next record
308 Record *Proc = ProcItinList[i];
309
310 std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
311 if (FUs.empty())
312 continue;
313
314 const std::string &Name = Proc->getName();
315 OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
316 << "namespace " << Name << "FU {\n";
317
318 for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
319 OS << " const unsigned " << FUs[j]->getName()
320 << " = 1 << " << j << ";\n";
321
322 OS << "}\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000323
324 std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP");
Evan Cheng3881cb72010-09-29 22:42:35 +0000325 if (BPs.size()) {
326 OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
327 << "\"\n" << "namespace " << Name << "Bypass {\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000328
Evan Cheng3881cb72010-09-29 22:42:35 +0000329 OS << " const unsigned NoBypass = 0;\n";
330 for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
331 OS << " const unsigned " << BPs[j]->getName()
332 << " = 1 << " << j << ";\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000333
Evan Cheng3881cb72010-09-29 22:42:35 +0000334 OS << "}\n";
335 }
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000336 }
337
Jim Laskey908ae272005-10-28 15:20:43 +0000338 // Begin stages table
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000339 std::string StageTable = "\nstatic const llvm::InstrStage Stages[] = {\n";
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000340 StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000341
David Goodwinfac85412009-08-17 16:02:57 +0000342 // Begin operand cycle table
343 std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
344 OperandCycleTable += " 0, // No itinerary\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000345
346 // Begin pipeline bypass table
Evan Cheng3881cb72010-09-29 22:42:35 +0000347 std::string BypassTable = "static const unsigned ForwardingPathes[] = {\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000348 BypassTable += " 0, // No itinerary\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000349
David Goodwinfac85412009-08-17 16:02:57 +0000350 unsigned StageCount = 1, OperandCycleCount = 1;
Evan Cheng3881cb72010-09-29 22:42:35 +0000351 std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000352 for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
353 // Next record
354 Record *Proc = ProcItinList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000355
Jim Laskey908ae272005-10-28 15:20:43 +0000356 // Get processor itinerary name
Bill Wendling4222d802007-05-04 20:38:40 +0000357 const std::string &Name = Proc->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +0000358
Jim Laskey908ae272005-10-28 15:20:43 +0000359 // Skip default
Jim Laskey0d841e02005-10-27 19:47:21 +0000360 if (Name == "NoItineraries") continue;
Andrew Trickda96cf22011-04-01 01:56:55 +0000361
Jim Laskey908ae272005-10-28 15:20:43 +0000362 // Create and expand processor itinerary to cover all itinerary classes
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000363 std::vector<InstrItinerary> ItinList;
364 ItinList.resize(NItinClasses);
Andrew Trickda96cf22011-04-01 01:56:55 +0000365
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000366 // Get itinerary data list
Chris Lattnerb0e103d2005-10-28 22:49:02 +0000367 std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
Andrew Trickda96cf22011-04-01 01:56:55 +0000368
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000369 // For each itinerary data
370 for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
371 // Next itinerary data
372 Record *ItinData = ItinDataList[j];
Andrew Trickda96cf22011-04-01 01:56:55 +0000373
Jim Laskey908ae272005-10-28 15:20:43 +0000374 // Get string and stage count
David Goodwinfac85412009-08-17 16:02:57 +0000375 std::string ItinStageString;
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000376 unsigned NStages;
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000377 FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
Jim Laskey0d841e02005-10-27 19:47:21 +0000378
David Goodwinfac85412009-08-17 16:02:57 +0000379 // Get string and operand cycle count
380 std::string ItinOperandCycleString;
381 unsigned NOperandCycles;
382 FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
383 NOperandCycles);
384
Evan Cheng63d66ee2010-09-28 23:50:49 +0000385 std::string ItinBypassString;
386 FormItineraryBypassString(Name, ItinData, ItinBypassString,
387 NOperandCycles);
388
David Goodwinfac85412009-08-17 16:02:57 +0000389 // Check to see if stage already exists and create if it doesn't
390 unsigned FindStage = 0;
391 if (NStages > 0) {
392 FindStage = ItinStageMap[ItinStageString];
393 if (FindStage == 0) {
Andrew Trick23482322011-04-01 02:22:47 +0000394 // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
395 StageTable += ItinStageString + ", // " + itostr(StageCount);
396 if (NStages > 1)
397 StageTable += "-" + itostr(StageCount + NStages - 1);
398 StageTable += "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000399 // Record Itin class number.
400 ItinStageMap[ItinStageString] = FindStage = StageCount;
401 StageCount += NStages;
David Goodwinfac85412009-08-17 16:02:57 +0000402 }
403 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000404
David Goodwinfac85412009-08-17 16:02:57 +0000405 // Check to see if operand cycle already exists and create if it doesn't
406 unsigned FindOperandCycle = 0;
407 if (NOperandCycles > 0) {
Evan Cheng3881cb72010-09-29 22:42:35 +0000408 std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
409 FindOperandCycle = ItinOperandMap[ItinOperandString];
David Goodwinfac85412009-08-17 16:02:57 +0000410 if (FindOperandCycle == 0) {
411 // Emit as cycle, // index
Andrew Trick23482322011-04-01 02:22:47 +0000412 OperandCycleTable += ItinOperandCycleString + ", // ";
413 std::string OperandIdxComment = itostr(OperandCycleCount);
414 if (NOperandCycles > 1)
415 OperandIdxComment += "-"
416 + itostr(OperandCycleCount + NOperandCycles - 1);
417 OperandCycleTable += OperandIdxComment + "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000418 // Record Itin class number.
Andrew Trickda96cf22011-04-01 01:56:55 +0000419 ItinOperandMap[ItinOperandCycleString] =
David Goodwinfac85412009-08-17 16:02:57 +0000420 FindOperandCycle = OperandCycleCount;
Evan Cheng63d66ee2010-09-28 23:50:49 +0000421 // Emit as bypass, // index
Andrew Trick23482322011-04-01 02:22:47 +0000422 BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000423 OperandCycleCount += NOperandCycles;
David Goodwinfac85412009-08-17 16:02:57 +0000424 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000425 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000426
Jim Laskey908ae272005-10-28 15:20:43 +0000427 // Locate where to inject into processor itinerary table
Bill Wendling4222d802007-05-04 20:38:40 +0000428 const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
David Goodwinfac85412009-08-17 16:02:57 +0000429 unsigned Find = ItinClassesMap[Name];
Andrew Trickda96cf22011-04-01 01:56:55 +0000430
Evan Cheng5f54ce32010-09-09 18:18:55 +0000431 // Set up itinerary as location and location + stage count
432 unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps");
433 InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
434 FindOperandCycle,
435 FindOperandCycle + NOperandCycles};
436
Jim Laskey908ae272005-10-28 15:20:43 +0000437 // Inject - empty slots will be 0, 0
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000438 ItinList[Find] = Intinerary;
Jim Laskey0d841e02005-10-27 19:47:21 +0000439 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000440
Jim Laskey908ae272005-10-28 15:20:43 +0000441 // Add process itinerary to list
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000442 ProcList.push_back(ItinList);
Jim Laskey0d841e02005-10-27 19:47:21 +0000443 }
Evan Cheng63d66ee2010-09-28 23:50:49 +0000444
Jim Laskey7f39c142005-11-03 22:47:41 +0000445 // Closing stage
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000446 StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
David Goodwinfac85412009-08-17 16:02:57 +0000447 StageTable += "};\n";
448
449 // Closing operand cycles
450 OperandCycleTable += " 0 // End itinerary\n";
451 OperandCycleTable += "};\n";
452
Evan Cheng63d66ee2010-09-28 23:50:49 +0000453 BypassTable += " 0 // End itinerary\n";
454 BypassTable += "};\n";
455
David Goodwinfac85412009-08-17 16:02:57 +0000456 // Emit tables.
457 OS << StageTable;
458 OS << OperandCycleTable;
Evan Cheng63d66ee2010-09-28 23:50:49 +0000459 OS << BypassTable;
Andrew Trickda96cf22011-04-01 01:56:55 +0000460
David Goodwinfac85412009-08-17 16:02:57 +0000461 // Emit size of tables
Jim Laskey6cee6302005-11-01 20:06:59 +0000462 OS<<"\nenum {\n";
David Goodwinfac85412009-08-17 16:02:57 +0000463 OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n";
464 OS<<" OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n";
Jim Laskey6cee6302005-11-01 20:06:59 +0000465 OS<<"};\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000466}
467
468//
Jim Laskey10b1dd92005-10-31 17:16:01 +0000469// EmitProcessorData - Generate data for processor itineraries.
Jim Laskey0d841e02005-10-27 19:47:21 +0000470//
Andrew Trick23482322011-04-01 02:22:47 +0000471void SubtargetEmitter::
472EmitProcessorData(raw_ostream &OS,
473 std::vector<Record*> &ItinClassList,
474 std::vector<std::vector<InstrItinerary> > &ProcList) {
Jim Laskey908ae272005-10-28 15:20:43 +0000475 // Get an iterator for processor itinerary stages
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000476 std::vector<std::vector<InstrItinerary> >::iterator
477 ProcListIter = ProcList.begin();
Andrew Trickda96cf22011-04-01 01:56:55 +0000478
Jim Laskey908ae272005-10-28 15:20:43 +0000479 // For each processor itinerary
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000480 std::vector<Record*> Itins =
481 Records.getAllDerivedDefinitions("ProcessorItineraries");
482 for (unsigned i = 0, N = Itins.size(); i < N; i++) {
483 // Next record
484 Record *Itin = Itins[i];
485
Jim Laskey908ae272005-10-28 15:20:43 +0000486 // Get processor itinerary name
Bill Wendling4222d802007-05-04 20:38:40 +0000487 const std::string &Name = Itin->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +0000488
Jim Laskey908ae272005-10-28 15:20:43 +0000489 // Skip default
Jim Laskey0d841e02005-10-27 19:47:21 +0000490 if (Name == "NoItineraries") continue;
491
Jim Laskey908ae272005-10-28 15:20:43 +0000492 // Begin processor itinerary table
Jim Laskey0d841e02005-10-27 19:47:21 +0000493 OS << "\n";
Dan Gohmancfbb2f02008-03-25 21:45:14 +0000494 OS << "static const llvm::InstrItinerary " << Name << "[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000495
Jim Laskey908ae272005-10-28 15:20:43 +0000496 // For each itinerary class
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000497 std::vector<InstrItinerary> &ItinList = *ProcListIter++;
Andrew Trick23482322011-04-01 02:22:47 +0000498 assert(ItinList.size() == ItinClassList.size() && "bad itinerary");
David Goodwin1f528952009-09-24 20:22:50 +0000499 for (unsigned j = 0, M = ItinList.size(); j < M; ++j) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000500 InstrItinerary &Intinerary = ItinList[j];
Andrew Trickda96cf22011-04-01 01:56:55 +0000501
502 // Emit in the form of
David Goodwinfac85412009-08-17 16:02:57 +0000503 // { firstStage, lastStage, firstCycle, lastCycle } // index
504 if (Intinerary.FirstStage == 0) {
Evan Cheng5f54ce32010-09-09 18:18:55 +0000505 OS << " { 1, 0, 0, 0, 0 }";
Jim Laskey0d841e02005-10-27 19:47:21 +0000506 } else {
Evan Cheng5f54ce32010-09-09 18:18:55 +0000507 OS << " { " <<
508 Intinerary.NumMicroOps << ", " <<
Andrew Trickda96cf22011-04-01 01:56:55 +0000509 Intinerary.FirstStage << ", " <<
510 Intinerary.LastStage << ", " <<
511 Intinerary.FirstOperandCycle << ", " <<
David Goodwinfac85412009-08-17 16:02:57 +0000512 Intinerary.LastOperandCycle << " }";
Jim Laskey0d841e02005-10-27 19:47:21 +0000513 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000514
Andrew Trick23482322011-04-01 02:22:47 +0000515 OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000516 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000517
Jim Laskey908ae272005-10-28 15:20:43 +0000518 // End processor itinerary table
Evan Cheng5f54ce32010-09-09 18:18:55 +0000519 OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000520 OS << "};\n";
521 }
Jim Laskey10b1dd92005-10-31 17:16:01 +0000522}
523
524//
525// EmitProcessorLookup - generate cpu name to itinerary lookup table.
526//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000527void SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) {
Jim Laskey10b1dd92005-10-31 17:16:01 +0000528 // Gather and sort processor information
529 std::vector<Record*> ProcessorList =
530 Records.getAllDerivedDefinitions("Processor");
Duraid Madina42d24c72005-12-30 14:56:37 +0000531 std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
Jim Laskey10b1dd92005-10-31 17:16:01 +0000532
533 // Begin processor table
534 OS << "\n";
535 OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
Jim Laskey7f39c142005-11-03 22:47:41 +0000536 << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000537
Jim Laskey10b1dd92005-10-31 17:16:01 +0000538 // For each processor
539 for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
540 // Next processor
541 Record *Processor = ProcessorList[i];
542
Bill Wendling4222d802007-05-04 20:38:40 +0000543 const std::string &Name = Processor->getValueAsString("Name");
544 const std::string &ProcItin =
545 Processor->getValueAsDef("ProcItin")->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +0000546
Jim Laskey10b1dd92005-10-31 17:16:01 +0000547 // Emit as { "cpu", procinit },
548 OS << " { "
549 << "\"" << Name << "\", "
550 << "(void *)&" << ProcItin;
Andrew Trickda96cf22011-04-01 01:56:55 +0000551
Jim Laskey10b1dd92005-10-31 17:16:01 +0000552 OS << " }";
Andrew Trickda96cf22011-04-01 01:56:55 +0000553
Jim Laskey10b1dd92005-10-31 17:16:01 +0000554 // Depending on ''if more in the list'' emit comma
555 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000556
Jim Laskey10b1dd92005-10-31 17:16:01 +0000557 OS << "\n";
558 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000559
Jim Laskey10b1dd92005-10-31 17:16:01 +0000560 // End processor table
561 OS << "};\n";
562
563 // Emit size of table
564 OS<<"\nenum {\n";
Jim Laskey7f39c142005-11-03 22:47:41 +0000565 OS<<" ProcItinKVSize = sizeof(ProcItinKV)/"
Jim Laskey10b1dd92005-10-31 17:16:01 +0000566 "sizeof(llvm::SubtargetInfoKV)\n";
567 OS<<"};\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000568}
569
570//
571// EmitData - Emits all stages and itineries, folding common patterns.
572//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000573void SubtargetEmitter::EmitData(raw_ostream &OS) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000574 std::map<std::string, unsigned> ItinClassesMap;
Evan Cheng5f54ce32010-09-09 18:18:55 +0000575 // Gather and sort all itinerary classes
576 std::vector<Record*> ItinClassList =
577 Records.getAllDerivedDefinitions("InstrItinClass");
578 std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
Andrew Trickda96cf22011-04-01 01:56:55 +0000579
Jim Laskey908ae272005-10-28 15:20:43 +0000580 // Enumerate all the itinerary classes
Evan Cheng5f54ce32010-09-09 18:18:55 +0000581 unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
582 ItinClassList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000583 // Make sure the rest is worth the effort
Chris Lattner387e4bd2006-01-27 01:41:55 +0000584 HasItineraries = NItinClasses != 1; // Ignore NoItinerary.
Andrew Trickda96cf22011-04-01 01:56:55 +0000585
Jim Laskey6cee6302005-11-01 20:06:59 +0000586 if (HasItineraries) {
Evan Cheng5f54ce32010-09-09 18:18:55 +0000587 std::vector<std::vector<InstrItinerary> > ProcList;
Jim Laskey6cee6302005-11-01 20:06:59 +0000588 // Emit the stage data
Evan Cheng5f54ce32010-09-09 18:18:55 +0000589 EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
590 ItinClassList, ProcList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000591 // Emit the processor itinerary data
Andrew Trick23482322011-04-01 02:22:47 +0000592 EmitProcessorData(OS, ItinClassList, ProcList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000593 // Emit the processor lookup data
594 EmitProcessorLookup(OS);
595 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000596}
597
598//
Jim Laskey581a8f72005-10-26 17:30:34 +0000599// ParseFeaturesFunction - Produces a subtarget specific function for parsing
600// the subtarget features string.
601//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000602void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000603 std::vector<Record*> Features =
604 Records.getAllDerivedDefinitions("SubtargetFeature");
Duraid Madina42d24c72005-12-30 14:56:37 +0000605 std::sort(Features.begin(), Features.end(), LessRecord());
Jim Laskey581a8f72005-10-26 17:30:34 +0000606
Andrew Trickda96cf22011-04-01 01:56:55 +0000607 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
608 << "// subtarget options.\n"
Evan Cheng276365d2011-06-30 01:53:36 +0000609 << "void llvm::";
Jim Laskey581a8f72005-10-26 17:30:34 +0000610 OS << Target;
611 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
Bill Wendling4222d802007-05-04 20:38:40 +0000612 << " const std::string &CPU) {\n"
David Greenef0fd3af2010-01-05 17:47:41 +0000613 << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
614 << " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n"
Bill Wendling4222d802007-05-04 20:38:40 +0000615 << " SubtargetFeatures Features(FS);\n"
Evan Cheng276365d2011-06-30 01:53:36 +0000616 << " uint64_t Bits = Features.getFeatureBits(CPU, "
617 << "SubTypeKV, SubTypeKVSize,\n"
Bill Wendling4222d802007-05-04 20:38:40 +0000618 << " FeatureKV, FeatureKVSize);\n";
619
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000620 for (unsigned i = 0; i < Features.size(); i++) {
621 // Next record
622 Record *R = Features[i];
Bill Wendling4222d802007-05-04 20:38:40 +0000623 const std::string &Instance = R->getName();
624 const std::string &Value = R->getValueAsString("Value");
625 const std::string &Attribute = R->getValueAsString("Attribute");
Evan Cheng19c95502006-01-27 08:09:42 +0000626
Dale Johannesendb01c8b2008-02-14 23:35:16 +0000627 if (Value=="true" || Value=="false")
628 OS << " if ((Bits & " << Instance << ") != 0) "
629 << Attribute << " = " << Value << ";\n";
630 else
Andrew Trickda96cf22011-04-01 01:56:55 +0000631 OS << " if ((Bits & " << Instance << ") != 0 && " << Attribute <<
Dale Johannesendb01c8b2008-02-14 23:35:16 +0000632 " < " << Value << ") " << Attribute << " = " << Value << ";\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000633 }
Bill Wendling4222d802007-05-04 20:38:40 +0000634
Jim Laskey6cee6302005-11-01 20:06:59 +0000635 if (HasItineraries) {
636 OS << "\n"
637 << " InstrItinerary *Itinerary = (InstrItinerary *)"
Evan Cheng276365d2011-06-30 01:53:36 +0000638 << "Features.getItinerary(CPU, "
639 << "ProcItinKV, ProcItinKVSize);\n"
Evan Cheng3881cb72010-09-29 22:42:35 +0000640 << " InstrItins = InstrItineraryData(Stages, OperandCycles, "
641 << "ForwardingPathes, Itinerary);\n";
Jim Laskey6cee6302005-11-01 20:06:59 +0000642 }
Anton Korobeynikov41a02432009-05-23 19:50:50 +0000643
Evan Cheng276365d2011-06-30 01:53:36 +0000644 OS << "}\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000645}
646
Anton Korobeynikov41a02432009-05-23 19:50:50 +0000647//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000648// SubtargetEmitter::run - Main subtarget enumeration emitter.
649//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000650void SubtargetEmitter::run(raw_ostream &OS) {
Chris Lattner67db8832010-12-13 00:23:57 +0000651 Target = CodeGenTarget(Records).getName();
Jim Laskey581a8f72005-10-26 17:30:34 +0000652
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000653 EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000654
Sandeep Patelbf177ee2009-11-11 03:23:46 +0000655 OS << "#include \"llvm/Support/Debug.h\"\n";
656 OS << "#include \"llvm/Support/raw_ostream.h\"\n";
Evan Chengab8be962011-06-29 01:14:12 +0000657 OS << "#include \"llvm/MC/SubtargetFeature.h\"\n";
658 OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n";
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000659
660// Enumeration(OS, "FuncUnit", true);
661// OS<<"\n";
Jim Laskey908ae272005-10-28 15:20:43 +0000662// Enumeration(OS, "InstrItinClass", false);
663// OS<<"\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000664 Enumeration(OS, "SubtargetFeature", true);
665 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000666 FeatureKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000667 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000668 CPUKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000669 OS<<"\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000670 EmitData(OS);
671 OS<<"\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000672 ParseFeaturesFunction(OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000673}