blob: 30d27c17454ec612e192b60bd241d7acb7d166ec [file] [log] [blame]
Jim Laskey4bb9cbb2005-10-21 19:00:04 +00001//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by James M. Laskey and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This tablegen backend emits subtarget enumerations.
11//
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"
19#include <algorithm>
20#include <set>
21using namespace llvm;
22
Jim Laskey7dc02042005-10-22 07:59:56 +000023//
24// Convenience types.
25//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000026typedef std::vector<Record*> RecordList;
27typedef std::vector<Record*>::iterator RecordListIter;
28
Jim Laskey7dc02042005-10-22 07:59:56 +000029//
30// Record sort by name function.
31//
32struct LessRecord {
33 bool operator()(const Record *Rec1, const Record *Rec2) const {
34 return Rec1->getName() < Rec2->getName();
35 }
36};
Jim Laskey4bb9cbb2005-10-21 19:00:04 +000037
Jim Laskey7dc02042005-10-22 07:59:56 +000038//
39// Record sort by field "Name" function.
40//
41struct LessRecordFieldName {
42 bool operator()(const Record *Rec1, const Record *Rec2) const {
43 return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
44 }
45};
46
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000047//
Jim Laskey581a8f72005-10-26 17:30:34 +000048// Enumeration - Emit the specified class as an enumeration.
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000049//
Jim Laskey581a8f72005-10-26 17:30:34 +000050void SubtargetEmitter::Enumeration(std::ostream &OS,
51 const char *ClassName,
52 bool isBits) {
53 RecordList Defs = Records.getAllDerivedDefinitions(ClassName);
54 sort(Defs.begin(), Defs.end(), LessRecord());
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000055
56 int i = 0;
57
58 OS << "enum {\n";
59
Jim Laskey581a8f72005-10-26 17:30:34 +000060 for (RecordListIter RI = Defs.begin(), E = Defs.end(); RI != E;) {
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000061 Record *R = *RI++;
62 std::string Instance = R->getName();
63 OS << " "
Jim Laskey581a8f72005-10-26 17:30:34 +000064 << Instance;
65 if (isBits) {
66 OS << " = "
67 << " 1 << " << i++;
68 }
69 OS << ((RI != E) ? ",\n" : "\n");
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000070 }
71
72 OS << "};\n";
73}
74
75//
76// FeatureKeyValues - Emit data of all the subtarget features. Used by command
77// line.
78//
79void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
80 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
81 sort(Features.begin(), Features.end(), LessRecord());
82
Jim Laskey581a8f72005-10-26 17:30:34 +000083 OS << "// Sorted (by key) array of values for CPU features.\n"
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +000084 << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
85 for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;) {
86 Record *R = *RI++;
87 std::string Instance = R->getName();
88 std::string Name = R->getValueAsString("Name");
89 std::string Desc = R->getValueAsString("Desc");
90 OS << " { "
91 << "\"" << Name << "\", "
92 << "\"" << Desc << "\", "
93 << Instance
94 << ((RI != E) ? " },\n" : " }\n");
95 }
96 OS << "};\n";
97
98 OS<<"\nenum {\n";
99 OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n";
100 OS<<"};\n";
101}
102
103//
104// CPUKeyValues - Emit data of all the subtarget processors. Used by command
105// line.
106//
107void SubtargetEmitter::CPUKeyValues(std::ostream &OS) {
108 RecordList Processors = Records.getAllDerivedDefinitions("Processor");
109 sort(Processors.begin(), Processors.end(), LessRecordFieldName());
110
Jim Laskey581a8f72005-10-26 17:30:34 +0000111 OS << "// Sorted (by key) array of values for CPU subtype.\n"
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000112 << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
113 for (RecordListIter RI = Processors.begin(), E = Processors.end();
114 RI != E;) {
115 Record *R = *RI++;
116 std::string Name = R->getValueAsString("Name");
117 Record *ProcItin = R->getValueAsDef("ProcItin");
118 ListInit *Features = R->getValueAsListInit("Features");
119 unsigned N = Features->getSize();
120 OS << " { "
121 << "\"" << Name << "\", "
122 << "\"Select the " << Name << " processor\", ";
123
124
125 if (N == 0) {
126 OS << "0";
127 } else {
128 for (unsigned i = 0; i < N; ) {
129 if (DefInit *DI = dynamic_cast<DefInit*>(Features->getElement(i++))) {
130 Record *Feature = DI->getDef();
131 std::string Name = Feature->getName();
132 OS << Name;
133 if (i != N) OS << " | ";
134 } else {
135 throw "Feature: " + Name +
136 " expected feature in processor feature list!";
137 }
138 }
139 }
140
141 OS << ((RI != E) ? " },\n" : " }\n");
142 }
143 OS << "};\n";
144
145 OS<<"\nenum {\n";
146 OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
147 OS<<"};\n";
148}
Jim Laskey7dc02042005-10-22 07:59:56 +0000149
Jim Laskey581a8f72005-10-26 17:30:34 +0000150//
151// ParseFeaturesFunction - Produces a subtarget specific function for parsing
152// the subtarget features string.
153//
154void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
155 RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
156 sort(Features.begin(), Features.end(), LessRecord());
157
158 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
159 "// subtarget options.\n"
160 "void llvm::";
161 OS << Target;
162 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
163 " const std::string &CPU) {\n"
164 " SubtargetFeatures Features(FS);\n"
165 " Features.setCPUIfNone(CPU);\n"
166 " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
167 " FeatureKV, FeatureKVSize);\n";
168
169 for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;) {
170 Record *R = *RI++;
171 std::string Instance = R->getName();
172 std::string Name = R->getValueAsString("Name");
173 std::string Type = R->getValueAsString("Type");
174 std::string Attribute = R->getValueAsString("Attribute");
175
176 OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n";
177 }
178 OS << "}\n";
179}
180
Jim Laskey7dc02042005-10-22 07:59:56 +0000181//
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000182// SubtargetEmitter::run - Main subtarget enumeration emitter.
183//
184void SubtargetEmitter::run(std::ostream &OS) {
Jim Laskey6c302fc2005-10-26 17:49:21 +0000185 Target = CodeGenTarget().getName();
Jim Laskey581a8f72005-10-26 17:30:34 +0000186
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000187 EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000188
Chris Lattnerd4d07972005-10-23 22:33:08 +0000189 OS << "#include \"llvm/Target/SubtargetFeature.h\"\n\n";
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000190
Jim Laskey581a8f72005-10-26 17:30:34 +0000191 Enumeration(OS, "FuncUnit", true);
192 OS<<"\n";
193 Enumeration(OS, "InstrItinClass", false);
194 OS<<"\n";
195 Enumeration(OS, "SubtargetFeature", true);
196 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000197 FeatureKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000198 OS<<"\n";
Jim Laskeyb3b1d5f2005-10-25 15:16:36 +0000199 CPUKeyValues(OS);
Jim Laskey581a8f72005-10-26 17:30:34 +0000200 OS<<"\n";
201 ParseFeaturesFunction(OS);
Jim Laskey4bb9cbb2005-10-21 19:00:04 +0000202}