blob: a55836faa2268929ba1c14f56244b816a64625f4 [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
Evan Chengb6a63882011-04-15 19:35:46 +000032 unsigned N = DefList.size();
Evan Cheng94214702011-07-01 20:45:01 +000033 if (N == 0)
34 return;
Evan Chengb6a63882011-04-15 19:35:46 +000035 if (N > 64) {
36 errs() << "Too many (> 64) subtarget features!\n";
37 exit(1);
38 }
39
Evan Cheng94214702011-07-01 20:45:01 +000040 OS << "namespace " << Target << " {\n";
41
42 // Open enumeration
43 OS << "enum {\n";
44
45 // For each record
Evan Chengb6a63882011-04-15 19:35:46 +000046 for (unsigned i = 0; i < N;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +000047 // Next record
48 Record *Def = DefList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +000049
Jim Laskey908ae272005-10-28 15:20:43 +000050 // Get and emit name
Bill Wendling4222d802007-05-04 20:38:40 +000051 OS << " " << Def->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +000052
Jim Laskey908ae272005-10-28 15:20:43 +000053 // If bit flags then emit expression (1 << i)
Evan Chengb6a63882011-04-15 19:35:46 +000054 if (isBits) OS << " = " << " 1ULL << " << i;
Jim Laskey908ae272005-10-28 15:20:43 +000055
Jim Laskey10b1dd92005-10-31 17:16:01 +000056 // Depending on 'if more in the list' emit comma
Jim Laskeyf7bcde02005-10-28 21:47:29 +000057 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +000058
Jim Laskeyf7bcde02005-10-28 21:47:29 +000059 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000060 }
Andrew Trickda96cf22011-04-01 01:56:55 +000061
Jim Laskey908ae272005-10-28 15:20:43 +000062 // Close enumeration
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000063 OS << "};\n";
Evan Cheng94214702011-07-01 20:45:01 +000064
65 OS << "}\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000066}
67
68//
Bill Wendling4222d802007-05-04 20:38:40 +000069// FeatureKeyValues - Emit data of all the subtarget features. Used by the
70// command line.
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000071//
Evan Cheng94214702011-07-01 20:45:01 +000072unsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +000073 // Gather and sort all the features
Jim Laskeyf7bcde02005-10-28 21:47:29 +000074 std::vector<Record*> FeatureList =
75 Records.getAllDerivedDefinitions("SubtargetFeature");
Evan Cheng94214702011-07-01 20:45:01 +000076
77 if (FeatureList.empty())
78 return 0;
79
Jim Grosbach7c9a7722008-09-11 17:05:32 +000080 std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000081
Jim Laskey908ae272005-10-28 15:20:43 +000082 // Begin feature table
Jim Laskey581a8f72005-10-26 17:30:34 +000083 OS << "// Sorted (by key) array of values for CPU features.\n"
Evan Cheng94214702011-07-01 20:45:01 +000084 << "static const llvm::SubtargetFeatureKV "
85 << Target << "FeatureKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +000086
Jim Laskey908ae272005-10-28 15:20:43 +000087 // For each feature
Evan Cheng94214702011-07-01 20:45:01 +000088 unsigned NumFeatures = 0;
Jim Laskeydbe40062006-12-12 20:55:58 +000089 for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +000090 // Next feature
91 Record *Feature = FeatureList[i];
92
Bill Wendling4222d802007-05-04 20:38:40 +000093 const std::string &Name = Feature->getName();
94 const std::string &CommandLineName = Feature->getValueAsString("Name");
95 const std::string &Desc = Feature->getValueAsString("Desc");
Andrew Trickda96cf22011-04-01 01:56:55 +000096
Jim Laskeydbe40062006-12-12 20:55:58 +000097 if (CommandLineName.empty()) continue;
Andrew Trickda96cf22011-04-01 01:56:55 +000098
Jim Grosbachda4231f2009-03-26 16:17:51 +000099 // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in }
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000100 OS << " { "
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000101 << "\"" << CommandLineName << "\", "
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000102 << "\"" << Desc << "\", "
Evan Cheng94214702011-07-01 20:45:01 +0000103 << Target << "::" << Name << ", ";
Bill Wendling4222d802007-05-04 20:38:40 +0000104
Andrew Trickda96cf22011-04-01 01:56:55 +0000105 const std::vector<Record*> &ImpliesList =
Bill Wendling4222d802007-05-04 20:38:40 +0000106 Feature->getValueAsListOfDefs("Implies");
Andrew Trickda96cf22011-04-01 01:56:55 +0000107
Bill Wendling4222d802007-05-04 20:38:40 +0000108 if (ImpliesList.empty()) {
Evan Chengb6a63882011-04-15 19:35:46 +0000109 OS << "0ULL";
Bill Wendling4222d802007-05-04 20:38:40 +0000110 } else {
111 for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
Evan Cheng94214702011-07-01 20:45:01 +0000112 OS << Target << "::" << ImpliesList[j]->getName();
Bill Wendling4222d802007-05-04 20:38:40 +0000113 if (++j < M) OS << " | ";
114 }
115 }
116
117 OS << " }";
Evan Cheng94214702011-07-01 20:45:01 +0000118 ++NumFeatures;
Andrew Trickda96cf22011-04-01 01:56:55 +0000119
Jim Laskey10b1dd92005-10-31 17:16:01 +0000120 // Depending on 'if more in the list' emit comma
Jim Laskeydbe40062006-12-12 20:55:58 +0000121 if ((i + 1) < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000122
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000123 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000124 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000125
Jim Laskey908ae272005-10-28 15:20:43 +0000126 // End feature table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000127 OS << "};\n";
128
Evan Cheng94214702011-07-01 20:45:01 +0000129 return NumFeatures;
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000130}
131
132//
133// CPUKeyValues - Emit data of all the subtarget processors. Used by command
134// line.
135//
Evan Cheng94214702011-07-01 20:45:01 +0000136unsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) {
Jim Laskey908ae272005-10-28 15:20:43 +0000137 // Gather and sort processor information
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000138 std::vector<Record*> ProcessorList =
139 Records.getAllDerivedDefinitions("Processor");
Duraid Madina42d24c72005-12-30 14:56:37 +0000140 std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000141
Jim Laskey908ae272005-10-28 15:20:43 +0000142 // Begin processor table
Jim Laskey581a8f72005-10-26 17:30:34 +0000143 OS << "// Sorted (by key) array of values for CPU subtype.\n"
Evan Cheng94214702011-07-01 20:45:01 +0000144 << "static const llvm::SubtargetFeatureKV "
145 << Target << "SubTypeKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000146
Jim Laskey908ae272005-10-28 15:20:43 +0000147 // For each processor
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000148 for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
149 // Next processor
150 Record *Processor = ProcessorList[i];
151
Bill Wendling4222d802007-05-04 20:38:40 +0000152 const std::string &Name = Processor->getValueAsString("Name");
Andrew Trickda96cf22011-04-01 01:56:55 +0000153 const std::vector<Record*> &FeatureList =
Chris Lattnerb0e103d2005-10-28 22:49:02 +0000154 Processor->getValueAsListOfDefs("Features");
Andrew Trickda96cf22011-04-01 01:56:55 +0000155
Jim Laskey908ae272005-10-28 15:20:43 +0000156 // Emit as { "cpu", "description", f1 | f2 | ... fn },
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000157 OS << " { "
158 << "\"" << Name << "\", "
159 << "\"Select the " << Name << " processor\", ";
Andrew Trickda96cf22011-04-01 01:56:55 +0000160
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000161 if (FeatureList.empty()) {
Evan Chengb6a63882011-04-15 19:35:46 +0000162 OS << "0ULL";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000163 } else {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000164 for (unsigned j = 0, M = FeatureList.size(); j < M;) {
Evan Cheng94214702011-07-01 20:45:01 +0000165 OS << Target << "::" << FeatureList[j]->getName();
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000166 if (++j < M) OS << " | ";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000167 }
168 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000169
Bill Wendling4222d802007-05-04 20:38:40 +0000170 // The "0" is for the "implies" section of this data structure.
Evan Chengb6a63882011-04-15 19:35:46 +0000171 OS << ", 0ULL }";
Andrew Trickda96cf22011-04-01 01:56:55 +0000172
Jim Laskey10b1dd92005-10-31 17:16:01 +0000173 // Depending on 'if more in the list' emit comma
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000174 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000175
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000176 OS << "\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000177 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000178
Jim Laskey908ae272005-10-28 15:20:43 +0000179 // End processor table
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000180 OS << "};\n";
181
Evan Cheng94214702011-07-01 20:45:01 +0000182 return ProcessorList.size();
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000183}
Jim Laskey7dc02042005-10-22 07:59:56 +0000184
Jim Laskey581a8f72005-10-26 17:30:34 +0000185//
Jim Laskey0d841e02005-10-27 19:47:21 +0000186// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
Jim Laskey908ae272005-10-28 15:20:43 +0000187// Returns itinerary class count.
Jim Laskey0d841e02005-10-27 19:47:21 +0000188//
Evan Cheng5f54ce32010-09-09 18:18:55 +0000189unsigned SubtargetEmitter::
190CollectAllItinClasses(raw_ostream &OS,
191 std::map<std::string, unsigned> &ItinClassesMap,
192 std::vector<Record*> &ItinClassList) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000193 // For each itinerary class
194 unsigned N = ItinClassList.size();
195 for (unsigned i = 0; i < N; i++) {
196 // Next itinerary class
Bill Wendling4222d802007-05-04 20:38:40 +0000197 const Record *ItinClass = ItinClassList[i];
Jim Laskey908ae272005-10-28 15:20:43 +0000198 // Get name of itinerary class
Jim Laskey908ae272005-10-28 15:20:43 +0000199 // Assign itinerary class a unique number
Bill Wendling4222d802007-05-04 20:38:40 +0000200 ItinClassesMap[ItinClass->getName()] = i;
Jim Laskey0d841e02005-10-27 19:47:21 +0000201 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000202
Jim Laskey908ae272005-10-28 15:20:43 +0000203 // Return itinerary class count
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000204 return N;
Jim Laskey0d841e02005-10-27 19:47:21 +0000205}
206
207//
David Goodwinfac85412009-08-17 16:02:57 +0000208// FormItineraryStageString - Compose a string containing the stage
209// data initialization for the specified itinerary. N is the number
210// of stages.
Jim Laskey0d841e02005-10-27 19:47:21 +0000211//
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000212void SubtargetEmitter::FormItineraryStageString(const std::string &Name,
213 Record *ItinData,
David Goodwinfac85412009-08-17 16:02:57 +0000214 std::string &ItinString,
215 unsigned &NStages) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000216 // Get states list
Bill Wendling4222d802007-05-04 20:38:40 +0000217 const std::vector<Record*> &StageList =
218 ItinData->getValueAsListOfDefs("Stages");
Jim Laskey908ae272005-10-28 15:20:43 +0000219
220 // For each stage
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000221 unsigned N = NStages = StageList.size();
Christopher Lamb8dadf6b2007-04-22 09:04:24 +0000222 for (unsigned i = 0; i < N;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000223 // Next stage
Bill Wendling4222d802007-05-04 20:38:40 +0000224 const Record *Stage = StageList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000225
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000226 // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind }
Jim Laskey0d841e02005-10-27 19:47:21 +0000227 int Cycles = Stage->getValueAsInt("Cycles");
Jim Laskey7f39c142005-11-03 22:47:41 +0000228 ItinString += " { " + itostr(Cycles) + ", ";
Andrew Trickda96cf22011-04-01 01:56:55 +0000229
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000230 // Get unit list
Bill Wendling4222d802007-05-04 20:38:40 +0000231 const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
Andrew Trickda96cf22011-04-01 01:56:55 +0000232
Jim Laskey908ae272005-10-28 15:20:43 +0000233 // For each unit
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000234 for (unsigned j = 0, M = UnitList.size(); j < M;) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000235 // Add name and bitwise or
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000236 ItinString += Name + "FU::" + UnitList[j]->getName();
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000237 if (++j < M) ItinString += " | ";
Jim Laskey0d841e02005-10-27 19:47:21 +0000238 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000239
David Goodwin1a8f36e2009-08-12 18:31:53 +0000240 int TimeInc = Stage->getValueAsInt("TimeInc");
241 ItinString += ", " + itostr(TimeInc);
242
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000243 int Kind = Stage->getValueAsInt("Kind");
244 ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind);
245
Jim Laskey908ae272005-10-28 15:20:43 +0000246 // Close off stage
247 ItinString += " }";
Christopher Lamb8dadf6b2007-04-22 09:04:24 +0000248 if (++i < N) ItinString += ", ";
Jim Laskey0d841e02005-10-27 19:47:21 +0000249 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000250}
251
252//
David Goodwinfac85412009-08-17 16:02:57 +0000253// FormItineraryOperandCycleString - Compose a string containing the
254// operand cycle initialization for the specified itinerary. N is the
255// number of operands that has cycles specified.
Jim Laskey0d841e02005-10-27 19:47:21 +0000256//
David Goodwinfac85412009-08-17 16:02:57 +0000257void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
258 std::string &ItinString, unsigned &NOperandCycles) {
259 // Get operand cycle list
260 const std::vector<int64_t> &OperandCycleList =
261 ItinData->getValueAsListOfInts("OperandCycles");
262
263 // For each operand cycle
264 unsigned N = NOperandCycles = OperandCycleList.size();
265 for (unsigned i = 0; i < N;) {
266 // Next operand cycle
267 const int OCycle = OperandCycleList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000268
David Goodwinfac85412009-08-17 16:02:57 +0000269 ItinString += " " + itostr(OCycle);
270 if (++i < N) ItinString += ", ";
271 }
272}
273
Evan Cheng63d66ee2010-09-28 23:50:49 +0000274void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
275 Record *ItinData,
276 std::string &ItinString,
277 unsigned NOperandCycles) {
278 const std::vector<Record*> &BypassList =
279 ItinData->getValueAsListOfDefs("Bypasses");
280 unsigned N = BypassList.size();
Evan Cheng3881cb72010-09-29 22:42:35 +0000281 unsigned i = 0;
282 for (; i < N;) {
Evan Cheng63d66ee2010-09-28 23:50:49 +0000283 ItinString += Name + "Bypass::" + BypassList[i]->getName();
Evan Cheng3881cb72010-09-29 22:42:35 +0000284 if (++i < NOperandCycles) ItinString += ", ";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000285 }
Evan Cheng3881cb72010-09-29 22:42:35 +0000286 for (; i < NOperandCycles;) {
Evan Cheng63d66ee2010-09-28 23:50:49 +0000287 ItinString += " 0";
Evan Cheng3881cb72010-09-29 22:42:35 +0000288 if (++i < NOperandCycles) ItinString += ", ";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000289 }
290}
291
David Goodwinfac85412009-08-17 16:02:57 +0000292//
293// EmitStageAndOperandCycleData - Generate unique itinerary stages and
294// operand cycle tables. Record itineraries for processors.
295//
296void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000297 unsigned NItinClasses,
Evan Cheng5f54ce32010-09-09 18:18:55 +0000298 std::map<std::string, unsigned> &ItinClassesMap,
299 std::vector<Record*> &ItinClassList,
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000300 std::vector<std::vector<InstrItinerary> > &ProcList) {
Jim Laskey908ae272005-10-28 15:20:43 +0000301 // Gather processor iteraries
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000302 std::vector<Record*> ProcItinList =
303 Records.getAllDerivedDefinitions("ProcessorItineraries");
Andrew Trickda96cf22011-04-01 01:56:55 +0000304
Jim Laskey908ae272005-10-28 15:20:43 +0000305 // If just no itinerary then don't bother
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000306 if (ProcItinList.size() < 2) return;
Jim Laskey908ae272005-10-28 15:20:43 +0000307
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000308 // Emit functional units for all the itineraries.
309 for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
310 // Next record
311 Record *Proc = ProcItinList[i];
312
313 std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");
314 if (FUs.empty())
315 continue;
316
317 const std::string &Name = Proc->getName();
318 OS << "\n// Functional units for itineraries \"" << Name << "\"\n"
319 << "namespace " << Name << "FU {\n";
320
321 for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
322 OS << " const unsigned " << FUs[j]->getName()
323 << " = 1 << " << j << ";\n";
324
325 OS << "}\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000326
327 std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP");
Evan Cheng3881cb72010-09-29 22:42:35 +0000328 if (BPs.size()) {
329 OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name
330 << "\"\n" << "namespace " << Name << "Bypass {\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000331
Evan Cheng3881cb72010-09-29 22:42:35 +0000332 OS << " const unsigned NoBypass = 0;\n";
333 for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
334 OS << " const unsigned " << BPs[j]->getName()
335 << " = 1 << " << j << ";\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000336
Evan Cheng3881cb72010-09-29 22:42:35 +0000337 OS << "}\n";
338 }
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000339 }
340
Jim Laskey908ae272005-10-28 15:20:43 +0000341 // Begin stages table
Evan Cheng94214702011-07-01 20:45:01 +0000342 std::string StageTable = "\nstatic const llvm::InstrStage " + Target +
343 "Stages[] = {\n";
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000344 StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000345
David Goodwinfac85412009-08-17 16:02:57 +0000346 // Begin operand cycle table
Evan Cheng94214702011-07-01 20:45:01 +0000347 std::string OperandCycleTable = "static const unsigned " + Target +
348 "OperandCycles[] = {\n";
David Goodwinfac85412009-08-17 16:02:57 +0000349 OperandCycleTable += " 0, // No itinerary\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000350
351 // Begin pipeline bypass table
Evan Cheng94214702011-07-01 20:45:01 +0000352 std::string BypassTable = "static const unsigned " + Target +
353 "ForwardingPathes[] = {\n";
Evan Cheng63d66ee2010-09-28 23:50:49 +0000354 BypassTable += " 0, // No itinerary\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000355
David Goodwinfac85412009-08-17 16:02:57 +0000356 unsigned StageCount = 1, OperandCycleCount = 1;
Evan Cheng3881cb72010-09-29 22:42:35 +0000357 std::map<std::string, unsigned> ItinStageMap, ItinOperandMap;
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000358 for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
359 // Next record
360 Record *Proc = ProcItinList[i];
Andrew Trickda96cf22011-04-01 01:56:55 +0000361
Jim Laskey908ae272005-10-28 15:20:43 +0000362 // Get processor itinerary name
Bill Wendling4222d802007-05-04 20:38:40 +0000363 const std::string &Name = Proc->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +0000364
Jim Laskey908ae272005-10-28 15:20:43 +0000365 // Skip default
Jim Laskey0d841e02005-10-27 19:47:21 +0000366 if (Name == "NoItineraries") continue;
Andrew Trickda96cf22011-04-01 01:56:55 +0000367
Jim Laskey908ae272005-10-28 15:20:43 +0000368 // Create and expand processor itinerary to cover all itinerary classes
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000369 std::vector<InstrItinerary> ItinList;
370 ItinList.resize(NItinClasses);
Andrew Trickda96cf22011-04-01 01:56:55 +0000371
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000372 // Get itinerary data list
Chris Lattnerb0e103d2005-10-28 22:49:02 +0000373 std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
Andrew Trickda96cf22011-04-01 01:56:55 +0000374
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000375 // For each itinerary data
376 for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
377 // Next itinerary data
378 Record *ItinData = ItinDataList[j];
Andrew Trickda96cf22011-04-01 01:56:55 +0000379
Jim Laskey908ae272005-10-28 15:20:43 +0000380 // Get string and stage count
David Goodwinfac85412009-08-17 16:02:57 +0000381 std::string ItinStageString;
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000382 unsigned NStages;
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000383 FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
Jim Laskey0d841e02005-10-27 19:47:21 +0000384
David Goodwinfac85412009-08-17 16:02:57 +0000385 // Get string and operand cycle count
386 std::string ItinOperandCycleString;
387 unsigned NOperandCycles;
388 FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
389 NOperandCycles);
390
Evan Cheng63d66ee2010-09-28 23:50:49 +0000391 std::string ItinBypassString;
392 FormItineraryBypassString(Name, ItinData, ItinBypassString,
393 NOperandCycles);
394
David Goodwinfac85412009-08-17 16:02:57 +0000395 // Check to see if stage already exists and create if it doesn't
396 unsigned FindStage = 0;
397 if (NStages > 0) {
398 FindStage = ItinStageMap[ItinStageString];
399 if (FindStage == 0) {
Andrew Trick23482322011-04-01 02:22:47 +0000400 // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices
401 StageTable += ItinStageString + ", // " + itostr(StageCount);
402 if (NStages > 1)
403 StageTable += "-" + itostr(StageCount + NStages - 1);
404 StageTable += "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000405 // Record Itin class number.
406 ItinStageMap[ItinStageString] = FindStage = StageCount;
407 StageCount += NStages;
David Goodwinfac85412009-08-17 16:02:57 +0000408 }
409 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000410
David Goodwinfac85412009-08-17 16:02:57 +0000411 // Check to see if operand cycle already exists and create if it doesn't
412 unsigned FindOperandCycle = 0;
413 if (NOperandCycles > 0) {
Evan Cheng3881cb72010-09-29 22:42:35 +0000414 std::string ItinOperandString = ItinOperandCycleString+ItinBypassString;
415 FindOperandCycle = ItinOperandMap[ItinOperandString];
David Goodwinfac85412009-08-17 16:02:57 +0000416 if (FindOperandCycle == 0) {
417 // Emit as cycle, // index
Andrew Trick23482322011-04-01 02:22:47 +0000418 OperandCycleTable += ItinOperandCycleString + ", // ";
419 std::string OperandIdxComment = itostr(OperandCycleCount);
420 if (NOperandCycles > 1)
421 OperandIdxComment += "-"
422 + itostr(OperandCycleCount + NOperandCycles - 1);
423 OperandCycleTable += OperandIdxComment + "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000424 // Record Itin class number.
Andrew Trickda96cf22011-04-01 01:56:55 +0000425 ItinOperandMap[ItinOperandCycleString] =
David Goodwinfac85412009-08-17 16:02:57 +0000426 FindOperandCycle = OperandCycleCount;
Evan Cheng63d66ee2010-09-28 23:50:49 +0000427 // Emit as bypass, // index
Andrew Trick23482322011-04-01 02:22:47 +0000428 BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n";
David Goodwinfac85412009-08-17 16:02:57 +0000429 OperandCycleCount += NOperandCycles;
David Goodwinfac85412009-08-17 16:02:57 +0000430 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000431 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000432
Jim Laskey908ae272005-10-28 15:20:43 +0000433 // Locate where to inject into processor itinerary table
Bill Wendling4222d802007-05-04 20:38:40 +0000434 const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
David Goodwinfac85412009-08-17 16:02:57 +0000435 unsigned Find = ItinClassesMap[Name];
Andrew Trickda96cf22011-04-01 01:56:55 +0000436
Evan Cheng5f54ce32010-09-09 18:18:55 +0000437 // Set up itinerary as location and location + stage count
438 unsigned NumUOps = ItinClassList[Find]->getValueAsInt("NumMicroOps");
439 InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages,
440 FindOperandCycle,
441 FindOperandCycle + NOperandCycles};
442
Jim Laskey908ae272005-10-28 15:20:43 +0000443 // Inject - empty slots will be 0, 0
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000444 ItinList[Find] = Intinerary;
Jim Laskey0d841e02005-10-27 19:47:21 +0000445 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000446
Jim Laskey908ae272005-10-28 15:20:43 +0000447 // Add process itinerary to list
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000448 ProcList.push_back(ItinList);
Jim Laskey0d841e02005-10-27 19:47:21 +0000449 }
Evan Cheng63d66ee2010-09-28 23:50:49 +0000450
Jim Laskey7f39c142005-11-03 22:47:41 +0000451 // Closing stage
Anton Korobeynikov96085a32010-04-07 18:19:32 +0000452 StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
David Goodwinfac85412009-08-17 16:02:57 +0000453 StageTable += "};\n";
454
455 // Closing operand cycles
456 OperandCycleTable += " 0 // End itinerary\n";
457 OperandCycleTable += "};\n";
458
Evan Cheng63d66ee2010-09-28 23:50:49 +0000459 BypassTable += " 0 // End itinerary\n";
460 BypassTable += "};\n";
461
David Goodwinfac85412009-08-17 16:02:57 +0000462 // Emit tables.
463 OS << StageTable;
464 OS << OperandCycleTable;
Evan Cheng63d66ee2010-09-28 23:50:49 +0000465 OS << BypassTable;
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"
Evan Cheng94214702011-07-01 20:45:01 +0000536 << "static const llvm::SubtargetInfoKV "
537 << Target << "ProcItinKV[] = {\n";
Andrew Trickda96cf22011-04-01 01:56:55 +0000538
Jim Laskey10b1dd92005-10-31 17:16:01 +0000539 // For each processor
540 for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
541 // Next processor
542 Record *Processor = ProcessorList[i];
543
Bill Wendling4222d802007-05-04 20:38:40 +0000544 const std::string &Name = Processor->getValueAsString("Name");
545 const std::string &ProcItin =
546 Processor->getValueAsDef("ProcItin")->getName();
Andrew Trickda96cf22011-04-01 01:56:55 +0000547
Jim Laskey10b1dd92005-10-31 17:16:01 +0000548 // Emit as { "cpu", procinit },
549 OS << " { "
550 << "\"" << Name << "\", "
551 << "(void *)&" << ProcItin;
Andrew Trickda96cf22011-04-01 01:56:55 +0000552
Jim Laskey10b1dd92005-10-31 17:16:01 +0000553 OS << " }";
Andrew Trickda96cf22011-04-01 01:56:55 +0000554
Jim Laskey10b1dd92005-10-31 17:16:01 +0000555 // Depending on ''if more in the list'' emit comma
556 if (++i < N) OS << ",";
Andrew Trickda96cf22011-04-01 01:56:55 +0000557
Jim Laskey10b1dd92005-10-31 17:16:01 +0000558 OS << "\n";
559 }
Andrew Trickda96cf22011-04-01 01:56:55 +0000560
Jim Laskey10b1dd92005-10-31 17:16:01 +0000561 // End processor table
562 OS << "};\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000563}
564
565//
566// EmitData - Emits all stages and itineries, folding common patterns.
567//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000568void SubtargetEmitter::EmitData(raw_ostream &OS) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000569 std::map<std::string, unsigned> ItinClassesMap;
Evan Cheng5f54ce32010-09-09 18:18:55 +0000570 // Gather and sort all itinerary classes
571 std::vector<Record*> ItinClassList =
572 Records.getAllDerivedDefinitions("InstrItinClass");
573 std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
Andrew Trickda96cf22011-04-01 01:56:55 +0000574
Jim Laskey908ae272005-10-28 15:20:43 +0000575 // Enumerate all the itinerary classes
Evan Cheng5f54ce32010-09-09 18:18:55 +0000576 unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap,
577 ItinClassList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000578 // Make sure the rest is worth the effort
Chris Lattner387e4bd2006-01-27 01:41:55 +0000579 HasItineraries = NItinClasses != 1; // Ignore NoItinerary.
Andrew Trickda96cf22011-04-01 01:56:55 +0000580
Jim Laskey6cee6302005-11-01 20:06:59 +0000581 if (HasItineraries) {
Evan Cheng5f54ce32010-09-09 18:18:55 +0000582 std::vector<std::vector<InstrItinerary> > ProcList;
Jim Laskey6cee6302005-11-01 20:06:59 +0000583 // Emit the stage data
Evan Cheng5f54ce32010-09-09 18:18:55 +0000584 EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap,
585 ItinClassList, ProcList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000586 // Emit the processor itinerary data
Andrew Trick23482322011-04-01 02:22:47 +0000587 EmitProcessorData(OS, ItinClassList, ProcList);
Jim Laskey6cee6302005-11-01 20:06:59 +0000588 // Emit the processor lookup data
589 EmitProcessorLookup(OS);
590 }
Jim Laskey0d841e02005-10-27 19:47:21 +0000591}
592
593//
Jim Laskey581a8f72005-10-26 17:30:34 +0000594// ParseFeaturesFunction - Produces a subtarget specific function for parsing
595// the subtarget features string.
596//
Evan Cheng94214702011-07-01 20:45:01 +0000597void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
598 unsigned NumFeatures,
599 unsigned NumProcs) {
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000600 std::vector<Record*> Features =
601 Records.getAllDerivedDefinitions("SubtargetFeature");
Duraid Madina42d24c72005-12-30 14:56:37 +0000602 std::sort(Features.begin(), Features.end(), LessRecord());
Jim Laskey581a8f72005-10-26 17:30:34 +0000603
Andrew Trickda96cf22011-04-01 01:56:55 +0000604 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
605 << "// subtarget options.\n"
Evan Cheng276365d2011-06-30 01:53:36 +0000606 << "void llvm::";
Jim Laskey581a8f72005-10-26 17:30:34 +0000607 OS << Target;
608 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
Bill Wendling4222d802007-05-04 20:38:40 +0000609 << " const std::string &CPU) {\n"
David Greenef0fd3af2010-01-05 17:47:41 +0000610 << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n"
Evan Cheng94214702011-07-01 20:45:01 +0000611 << " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n";
612
613 if (Features.empty()) {
614 OS << "}\n";
615 return;
616 }
617
618 OS << " SubtargetFeatures Features(FS);\n"
Evan Cheng276365d2011-06-30 01:53:36 +0000619 << " uint64_t Bits = Features.getFeatureBits(CPU, "
Evan Cheng94214702011-07-01 20:45:01 +0000620 << Target << "SubTypeKV, " << NumProcs << ",\n"
621 << " " << Target << "FeatureKV, "
622 << NumFeatures << ");\n";
Bill Wendling4222d802007-05-04 20:38:40 +0000623
Jim Laskeyf7bcde02005-10-28 21:47:29 +0000624 for (unsigned i = 0; i < Features.size(); i++) {
625 // Next record
626 Record *R = Features[i];
Bill Wendling4222d802007-05-04 20:38:40 +0000627 const std::string &Instance = R->getName();
628 const std::string &Value = R->getValueAsString("Value");
629 const std::string &Attribute = R->getValueAsString("Attribute");
Evan Cheng19c95502006-01-27 08:09:42 +0000630
Dale Johannesendb01c8b2008-02-14 23:35:16 +0000631 if (Value=="true" || Value=="false")
Evan Cheng94214702011-07-01 20:45:01 +0000632 OS << " if ((Bits & " << Target << "::" << Instance << ") != 0) "
Dale Johannesendb01c8b2008-02-14 23:35:16 +0000633 << Attribute << " = " << Value << ";\n";
634 else
Evan Cheng94214702011-07-01 20:45:01 +0000635 OS << " if ((Bits & " << Target << "::" << Instance << ") != 0 && "
636 << Attribute << " < " << Value << ") "
637 << Attribute << " = " << Value << ";\n";
Jim Laskey6cee6302005-11-01 20:06:59 +0000638 }
Anton Korobeynikov41a02432009-05-23 19:50:50 +0000639
Evan Cheng276365d2011-06-30 01:53:36 +0000640 OS << "}\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000641}
642
Anton Korobeynikov41a02432009-05-23 19:50:50 +0000643//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000644// SubtargetEmitter::run - Main subtarget enumeration emitter.
645//
Daniel Dunbar1a551802009-07-03 00:10:29 +0000646void SubtargetEmitter::run(raw_ostream &OS) {
Chris Lattner67db8832010-12-13 00:23:57 +0000647 Target = CodeGenTarget(Records).getName();
Jim Laskey581a8f72005-10-26 17:30:34 +0000648
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000649 EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000650
Evan Cheng94214702011-07-01 20:45:01 +0000651 OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n";
652 OS << "#undef GET_SUBTARGETINFO_MC_DESC\n";
Anton Korobeynikov928eb492010-04-18 20:31:01 +0000653
Evan Cheng94214702011-07-01 20:45:01 +0000654 OS << "namespace llvm {\n";
Jim Laskey581a8f72005-10-26 17:30:34 +0000655 Enumeration(OS, "SubtargetFeature", true);
656 OS<<"\n";
Evan Cheng94214702011-07-01 20:45:01 +0000657 unsigned NumFeatures = FeatureKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000658 OS<<"\n";
Evan Cheng94214702011-07-01 20:45:01 +0000659 unsigned NumProcs = CPUKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000660 OS<<"\n";
Jim Laskey0d841e02005-10-27 19:47:21 +0000661 EmitData(OS);
662 OS<<"\n";
Evan Cheng94214702011-07-01 20:45:01 +0000663
664 // MCInstrInfo initialization routine.
665 OS << "static inline void Init" << Target
666 << "MCSubtargetInfo(MCSubtargetInfo *II) {\n";
667 OS << " II->InitMCSubtargetInfo(";
668 if (NumFeatures)
669 OS << Target << "FeatureKV, ";
670 else
671 OS << "0, ";
672 if (NumProcs)
673 OS << Target << "SubTypeKV, ";
674 else
675 OS << "0, ";
676 if (HasItineraries) {
677 OS << Target << "ProcItinKV, "
678 << Target << "Stages, "
679 << Target << "OperandCycles, "
680 << Target << "ForwardingPathes, ";
681 } else
682 OS << "0, 0, 0, 0, ";
683 OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
684
685 OS << "} // End llvm namespace \n";
686
687 OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n";
688
689 OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n";
690 OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n";
691
692 OS << "#include \"llvm/Support/Debug.h\"\n";
693 OS << "#include \"llvm/Support/raw_ostream.h\"\n";
694 ParseFeaturesFunction(OS, NumFeatures, NumProcs);
695
696 OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n";
697
698 // Create a TargetSubtarget subclass to hide the MC layer initialization.
699 OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n";
700 OS << "#undef GET_SUBTARGETINFO_HEADER\n";
701
702 std::string ClassName = Target + "GenSubtargetInfo";
703 OS << "namespace llvm {\n";
704 OS << "struct " << ClassName << " : public TargetSubtarget {\n"
705 << " explicit " << ClassName << "();\n"
706 << "};\n";
707 OS << "} // End llvm namespace \n";
708
709 OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n";
710
711 OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n";
712 OS << "#undef GET_SUBTARGETINFO_CTOR\n";
713
714 OS << "namespace llvm {\n";
715 OS << ClassName << "::" << ClassName << "()\n"
716 << " : TargetSubtarget() {\n"
717 << " InitMCSubtargetInfo(";
718 if (NumFeatures)
719 OS << Target << "FeatureKV, ";
720 else
721 OS << "0, ";
722 if (NumProcs)
723 OS << Target << "SubTypeKV, ";
724 else
725 OS << "0, ";
726 if (HasItineraries) {
727 OS << Target << "ProcItinKV, "
728 << Target << "Stages, "
729 << Target << "OperandCycles, "
730 << Target << "ForwardingPathes, ";
731 } else
732 OS << "0, 0, 0, 0, ";
733 OS << NumFeatures << ", " << NumProcs << ");\n}\n\n";
734 OS << "} // End llvm namespace \n";
735
736 OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n";
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000737}