6d3542ea3e59a4f706790ca3c68151d321c70960
[oota-llvm.git] / utils / TableGen / SubtargetEmitter.cpp
1 //===- 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>
21 using namespace llvm;
22
23 //
24 // Convenience types.
25 //
26 typedef std::vector<Record*> RecordList;
27 typedef std::vector<Record*>::iterator RecordListIter;
28
29 //
30 // Record sort by name function.
31 //
32 struct LessRecord {
33   bool operator()(const Record *Rec1, const Record *Rec2) const {
34     return Rec1->getName() < Rec2->getName();
35   }
36 };
37
38 //
39 // Record sort by field "Name" function.
40 //
41 struct LessRecordFieldName {
42   bool operator()(const Record *Rec1, const Record *Rec2) const {
43     return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
44   }
45 };
46
47
48 // 
49 // SubtargetEmitter::run - Main subtarget enumeration emitter.
50 //
51 void SubtargetEmitter::run(std::ostream &OS) {
52   EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
53   
54   RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature");
55   sort(Features.begin(), Features.end(), LessRecord());
56   
57   RecordList Processors = Records.getAllDerivedDefinitions("Processor");
58   sort(Processors.begin(), Processors.end(), LessRecordFieldName());
59
60   OS << "#include \"llvm/Target/SubtargetFeature.h\"\n\n";
61   
62   { // Feature enumeration
63     int i = 0;
64     
65     OS << "enum {\n";
66     
67     for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;){
68       Record *R = *RI++;
69       std::string Instance = R->getName();
70       OS << "  "
71          << Instance
72          << " = "
73          << " 1 << " << i++
74          << ((RI != E) ? ",\n" : "\n");
75     }
76     
77     OS << "};\n";
78   }
79   
80   { // Feature key values
81     OS << "\n"
82        << "// Sorted (by key) array of values for CPU features.\n"
83        << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
84     for (RecordListIter RI = Features.begin(), E = Features.end(); RI != E;) {
85       Record *R = *RI++;
86       std::string Instance = R->getName();
87       std::string Name = R->getValueAsString("Name");
88       std::string Desc = R->getValueAsString("Desc");
89       OS << "  { "
90          << "\"" << Name << "\", "
91          << "\"" << Desc << "\", "
92          << Instance
93          << ((RI != E) ? " },\n" : " }\n");
94     }
95     OS << "};\n";
96   }
97   
98   { // CPU key values
99     OS << "\n"
100        << "// Sorted (by key) array of values for CPU subtype.\n"
101        << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
102     for (RecordListIter RI = Processors.begin(), E = Processors.end();
103          RI != E;) {
104       Record *R = *RI++;
105       std::string Name = R->getValueAsString("Name");
106       Record *ProcItin = R->getValueAsDef("ProcItin");
107       ListInit *Features = R->getValueAsListInit("Features");
108       unsigned N = Features->getSize();
109       OS << "  { "
110          << "\"" << Name << "\", "
111          << "\"Select the " << Name << " processor\", ";
112          
113       
114       if (N == 0) {
115         OS << "0";
116       } else {
117         for (unsigned i = 0; i < N; ) {
118           if (DefInit *DI = dynamic_cast<DefInit*>(Features->getElement(i++))) {
119             Record *Feature = DI->getDef();
120             std::string Name = Feature->getName();
121             OS << Name;
122             if (i != N) OS << " | ";
123           } else {
124             throw "Feature: " + Name +
125                   " expected feature in processor feature list!";
126           }
127         }
128       }
129       
130       OS << ((RI != E) ? " },\n" : " }\n");
131     }
132     OS << "};\n";
133   }
134   
135   OS<<"\nenum {\n";
136   OS<<"  FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV),\n";
137   OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
138   OS<<"};\n";
139 }