llvm.org GIT mirror llvm / 4222d80
Add an "implies" field to features. This indicates that, if the current feature is set, then the features in the implied list should be set also. The opposite is also enforced: if a feature in the implied list isn't set, then the feature that owns that implies list shouldn't be set either. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36756 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 13 years ago
5 changed file(s) with 132 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
3333 const char *Key; // K-V key string
3434 const char *Desc; // Help descriptor
3535 uint32_t Value; // K-V integer value
36 uint32_t Implies; // K-V bit mask
3637
3738 // Compare routine for std binary search
3839 bool operator<(const SubtargetFeatureKV &S) const {
198198 if (Features[0].empty()) setCPU(String);
199199 }
200200
201 /// SetImpliedBits - For each feature that is (transitively) implied by this
202 /// feature, set it.
203 ///
204 static
205 void SetImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry,
206 const SubtargetFeatureKV *FeatureTable,
207 size_t FeatureTableSize) {
208 for (size_t i = 0; i < FeatureTableSize; ++i) {
209 const SubtargetFeatureKV &FE = FeatureTable[i];
210
211 if (FeatureEntry->Value == FE.Value) continue;
212
213 if (FeatureEntry->Implies & FE.Value) {
214 Bits |= FE.Value;
215 SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
216 }
217 }
218 }
219
220 /// ClearImpliedBits - For each feature that (transitively) implies this
221 /// feature, clear it.
222 ///
223 static
224 void ClearImpliedBits(uint32_t &Bits, const SubtargetFeatureKV *FeatureEntry,
225 const SubtargetFeatureKV *FeatureTable,
226 size_t FeatureTableSize) {
227 for (size_t i = 0; i < FeatureTableSize; ++i) {
228 const SubtargetFeatureKV &FE = FeatureTable[i];
229
230 if (FeatureEntry->Value == FE.Value) continue;
231
232 if (FE.Implies & FeatureEntry->Value) {
233 Bits &= ~FE.Value;
234 ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
235 }
236 }
237 }
201238
202239 /// getBits - Get feature bits.
203240 ///
250287 // If there is a match
251288 if (FeatureEntry) {
252289 // Enable/disable feature in bits
253 if (isEnabled(Feature)) Bits |= FeatureEntry->Value;
254 else Bits &= ~FeatureEntry->Value;
290 if (isEnabled(Feature)) {
291 Bits |= FeatureEntry->Value;
292
293 // For each feature that this implies, set it.
294 SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
295 } else {
296 Bits &= ~FeatureEntry->Value;
297
298 // For each feature that implies this, clear it.
299 ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
300 }
255301 } else {
256302 cerr << "'" << Feature
257303 << "' is not a recognized feature for this target"
259305 << "\n";
260306 }
261307 }
308
262309 return Bits;
263310 }
264311
337337 //===----------------------------------------------------------------------===//
338338 // SubtargetFeature - A characteristic of the chip set.
339339 //
340 class SubtargetFeature> {
340 class SubtargetFeature,
341 list i = []> {
341342 // Name - Feature name. Used by command line (-mattr=) to determine the
342343 // appropriate target chip.
343344 //
355356 // information.
356357 //
357358 string Desc = d;
359
360 // Implies - Features that this feature implies are present. If one of those
361 // features isn't set, then this one shouldn't be set either.
362 //
363 list Implies = i;
358364 }
359365
360366 //===----------------------------------------------------------------------===//
1717
1818 //===----------------------------------------------------------------------===//
1919 // X86 Subtarget features.
20 //
20 //===----------------------------------------------------------------------===//
2121
22 def Feature64Bit : SubtargetFeature<"64bit", "HasX86_64", "true",
23 "Support 64-bit instructions">;
24 def FeatureMMX : SubtargetFeature<"mmx","X86SSELevel", "MMX",
25 "Enable MMX instructions">;
26 def FeatureSSE1 : SubtargetFeature<"sse", "X86SSELevel", "SSE1",
27 "Enable SSE instructions">;
28 def FeatureSSE2 : SubtargetFeature<"sse2", "X86SSELevel", "SSE2",
29 "Enable SSE2 instructions">;
30 def FeatureSSE3 : SubtargetFeature<"sse3", "X86SSELevel", "SSE3",
31 "Enable SSE3 instructions">;
32 def FeatureSSSE3 : SubtargetFeature<"ssse3", "X86SSELevel", "SSSE3",
33 "Enable SSSE3 instructions">;
34 def Feature3DNow : SubtargetFeature<"3dnow", "X863DNowLevel", "ThreeDNow",
35 "Enable 3DNow! instructions">;
36 def Feature3DNowA : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA",
37 "Enable 3DNow! Athlon instructions">;
22 def Feature64Bit : SubtargetFeature<"64bit", "HasX86_64", "true",
23 "Support 64-bit instructions">;
24 def FeatureMMX : SubtargetFeature<"mmx","X86SSELevel", "MMX",
25 "Enable MMX instructions">;
26 def FeatureSSE1 : SubtargetFeature<"sse", "X86SSELevel", "SSE1",
27 "Enable SSE instructions",
28 [FeatureMMX]>;
29 def FeatureSSE2 : SubtargetFeature<"sse2", "X86SSELevel", "SSE2",
30 "Enable SSE2 instructions",
31 [FeatureSSE1]>;
32 def FeatureSSE3 : SubtargetFeature<"sse3", "X86SSELevel", "SSE3",
33 "Enable SSE3 instructions",
34 [FeatureSSE2]>;
35 def FeatureSSSE3 : SubtargetFeature<"ssse3", "X86SSELevel", "SSSE3",
36 "Enable SSSE3 instructions",
37 [FeatureSSE3]>;
38 def Feature3DNow : SubtargetFeature<"3dnow", "X863DNowLevel", "ThreeDNow",
39 "Enable 3DNow! instructions">;
40 def Feature3DNowA : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA",
41 "Enable 3DNow! Athlon instructions">;
3842
3943 //===----------------------------------------------------------------------===//
4044 // X86 processors supported.
5555 Record *Def = DefList[i];
5656
5757 // Get and emit name
58 std::string Name = Def->getName();
59 OS << " " << Name;
58 OS << " " << Def->getName();
6059
6160 // If bit flags then emit expression (1 << i)
6261 if (isBits) OS << " = " << " 1 << " << i;
7271 }
7372
7473 //
75 // FeatureKeyValues - Emit data of all the subtarget features. Used by command
76 // line.
74 // FeatureKeyValues - Emit data of all the subtarget features. Used by the
75 // command line.
7776 //
7877 void SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
7978 // Gather and sort all the features
9089 // Next feature
9190 Record *Feature = FeatureList[i];
9291
93 std::string Name = Feature->getName();
94 std::string CommandLineName = Feature->getValueAsString("Name");
95 std::string Desc = Feature->getValueAsString("Desc");
92 const std::string &Name = Feature->getName();
93 const std::string &CommandLineName = Feature->getValueAsString("Name");
94 const std::string &Desc = Feature->getValueAsString("Desc");
9695
9796 if (CommandLineName.empty()) continue;
9897
99 // Emit as { "feature", "decription", feactureEnum }
98 // Emit as { "feature", "decription", feactureEnum, i1 | i2 | ... | in }
10099 OS << " { "
101100 << "\"" << CommandLineName << "\", "
102101 << "\"" << Desc << "\", "
103 << Name
104 << " }";
102 << Name << ", ";
103
104 const std::vector &ImpliesList =
105 Feature->getValueAsListOfDefs("Implies");
106
107 if (ImpliesList.empty()) {
108 OS << "0";
109 } else {
110 for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
111 OS << ImpliesList[j]->getName();
112 if (++j < M) OS << " | ";
113 }
114 }
115
116 OS << " }";
105117
106118 // Depending on 'if more in the list' emit comma
107119 if ((i + 1) < N) OS << ",";
137149 // Next processor
138150 Record *Processor = ProcessorList[i];
139151
140 std::string Name = Processor->getValueAsString("Name");
141 std::vector FeatureList =
152 const std::string &Name = Processor->getValueAsString("Name");
153 const std::vector &FeatureList =
142154 Processor->getValueAsListOfDefs("Features");
143155
144156 // Emit as { "cpu", "description", f1 | f2 | ... fn },
150162 OS << "0";
151163 } else {
152164 for (unsigned j = 0, M = FeatureList.size(); j < M;) {
153 Record *Feature = FeatureList[j];
154 std::string Name = Feature->getName();
155 OS << Name;
165 OS << FeatureList[j]->getName();
156166 if (++j < M) OS << " | ";
157167 }
158168 }
159169
160 OS << " }";
170 // The "0" is for the "implies" section of this data structure.
171 OS << ", 0 }";
161172
162173 // Depending on 'if more in the list' emit comma
163174 if (++i < N) OS << ",";
189200 unsigned N = ItinClassList.size();
190201 for (unsigned i = 0; i < N; i++) {
191202 // Next itinerary class
192 Record *ItinClass = ItinClassList[i];
203 const Record *ItinClass = ItinClassList[i];
193204 // Get name of itinerary class
194 std::string Name = ItinClass->getName();
195205 // Assign itinerary class a unique number
196 ItinClassesMap[Name] = i;
206 ItinClassesMap[ItinClass->getName()] = i;
197207 }
198208
199209 // Emit size of table
213223 std::string &ItinString,
214224 unsigned &NStages) {
215225 // Get states list
216 std::vector StageList = ItinData->getValueAsListOfDefs("Stages");
226 const std::vector &StageList =
227 ItinData->getValueAsListOfDefs("Stages");
217228
218229 // For each stage
219230 unsigned N = NStages = StageList.size();
220231 for (unsigned i = 0; i < N;) {
221232 // Next stage
222 Record *Stage = StageList[i];
233 const Record *Stage = StageList[i];
223234
224235 // Form string as ,{ cycles, u1 | u2 | ... | un }
225236 int Cycles = Stage->getValueAsInt("Cycles");
226237 ItinString += " { " + itostr(Cycles) + ", ";
227238
228239 // Get unit list
229 std::vector UnitList = Stage->getValueAsListOfDefs("Units");
240 const std::vector &UnitList = Stage->getValueAsListOfDefs("Units");
230241
231242 // For each unit
232243 for (unsigned j = 0, M = UnitList.size(); j < M;) {
233 // Next unit
234 Record *Unit = UnitList[j];
235
236244 // Add name and bitwise or
237 ItinString += Unit->getName();
245 ItinString += UnitList[j]->getName();
238246 if (++j < M) ItinString += " | ";
239247 }
240248
270278 Record *Proc = ProcItinList[i];
271279
272280 // Get processor itinerary name
273 std::string Name = Proc->getName();
281 const std::string &Name = Proc->getName();
274282
275283 // Skip default
276284 if (Name == "NoItineraries") continue;
307315 InstrItinerary Intinerary = { Find, Find + NStages };
308316
309317 // Locate where to inject into processor itinerary table
310 std::string Name = ItinData->getValueAsDef("TheClass")->getName();
318 const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
311319 Find = ItinClassesMap[Name];
312320
313321 // Inject - empty slots will be 0, 0
346354 Record *Itin = Itins[i];
347355
348356 // Get processor itinerary name
349 std::string Name = Itin->getName();
357 const std::string &Name = Itin->getName();
350358
351359 // Skip default
352360 if (Name == "NoItineraries") continue;
397405 // Next processor
398406 Record *Processor = ProcessorList[i];
399407
400 std::string Name = Processor->getValueAsString("Name");
401 std::string ProcItin = Processor->getValueAsDef("ProcItin")->getName();
408 const std::string &Name = Processor->getValueAsString("Name");
409 const std::string &ProcItin =
410 Processor->getValueAsDef("ProcItin")->getName();
402411
403412 // Emit as { "cpu", procinit },
404413 OS << " { "
455464 std::sort(Features.begin(), Features.end(), LessRecord());
456465
457466 OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
458 "// subtarget options.\n"
459 "void llvm::";
467 << "// subtarget options.\n"
468 << "void llvm::";
460469 OS << Target;
461470 OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
462 " const std::string &CPU) {\n"
463 " SubtargetFeatures Features(FS);\n"
464 " Features.setCPUIfNone(CPU);\n"
465 " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
466 " FeatureKV, FeatureKVSize);\n";
467
471 << " const std::string &CPU) {\n"
472 << " SubtargetFeatures Features(FS);\n"
473 << " Features.setCPUIfNone(CPU);\n"
474 << " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n"
475 << " FeatureKV, FeatureKVSize);\n";
476
468477 for (unsigned i = 0; i < Features.size(); i++) {
469478 // Next record
470479 Record *R = Features[i];
471 std::string Instance = R->getName();
472 std::string Name = R->getValueAsString("Name");
473 std::string Value = R->getValueAsString("Value");
474 std::string Attribute = R->getValueAsString("Attribute");
480 const std::string &Instance = R->getName();
481 const std::string &Value = R->getValueAsString("Value");
482 const std::string &Attribute = R->getValueAsString("Attribute");
475483
476484 OS << " if ((Bits & " << Instance << ") != 0) "
477485 << Attribute << " = " << Value << ";\n";
478486 }
479
487
480488 if (HasItineraries) {
481489 OS << "\n"
482490 << " InstrItinerary *Itinerary = (InstrItinerary *)"
483 "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
484 " InstrItins = InstrItineraryData(Stages, Itinerary);\n";
491 << "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
492 << " InstrItins = InstrItineraryData(Stages, Itinerary);\n";
485493 }
486494
487495 OS << "}\n";