blob: 8a22c54e472a124ba959a0bf5ba6b54fb44db068 [file] [log] [blame]
Chris Lattner1d1adea2003-08-01 04:39:05 +00001//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
2//
3// TableGen is a tool which can be used to build up a description of something,
4// then invoke one or more "tablegen backends" to emit information about the
5// description in some predefined format. In practice, this is used by the LLVM
6// code generators to automate generation of a code generator through a
7// high-level description of the target.
8//
9//===----------------------------------------------------------------------===//
10
Chris Lattnere62c1182002-12-02 01:23:04 +000011#include "Record.h"
12#include "Support/CommandLine.h"
Chris Lattner9a886382003-06-03 05:04:42 +000013#include "Support/Signals.h"
Chris Lattnere79c72d2003-08-01 20:35:01 +000014#include "Support/FileUtilities.h"
Misha Brukmanf00ce8b2003-05-24 00:17:12 +000015#include "CodeEmitterGen.h"
Chris Lattner1d1adea2003-08-01 04:39:05 +000016#include "RegisterInfoEmitter.h"
Chris Lattner169e66b2003-08-03 17:24:20 +000017#include "InstrInfoEmitter.h"
Chris Lattnere62c1182002-12-02 01:23:04 +000018#include <algorithm>
Chris Lattner9a886382003-06-03 05:04:42 +000019#include <fstream>
Chris Lattnere62c1182002-12-02 01:23:04 +000020
Chris Lattnerbc520132003-06-03 04:56:29 +000021enum ActionType {
22 PrintRecords,
23 GenEmitter,
Chris Lattner54d156d2003-08-01 05:59:20 +000024 GenRegisterEnums, GenRegister, GenRegisterHeader,
Chris Lattner15de32d2003-08-03 21:58:28 +000025 GenInstrEnums, GenInstrs,
Chris Lattnerbc520132003-06-03 04:56:29 +000026 PrintEnums,
27 Parse,
28};
29
30namespace {
31 cl::opt<ActionType>
32 Action(cl::desc("Action to perform:"),
33 cl::values(clEnumValN(PrintRecords, "print-records",
Chris Lattner85df2252003-06-03 05:07:28 +000034 "Print all records to stdout (default)"),
Chris Lattnerbc520132003-06-03 04:56:29 +000035 clEnumValN(GenEmitter, "gen-emitter",
36 "Generate machine code emitter"),
Chris Lattner54d156d2003-08-01 05:59:20 +000037 clEnumValN(GenRegisterEnums, "gen-register-enums",
38 "Generate enum values for registers"),
Chris Lattner1d1adea2003-08-01 04:39:05 +000039 clEnumValN(GenRegister, "gen-register-desc",
40 "Generate a register info description"),
41 clEnumValN(GenRegisterHeader, "gen-register-desc-header",
42 "Generate a register info description header"),
Chris Lattner169e66b2003-08-03 17:24:20 +000043 clEnumValN(GenInstrEnums, "gen-instr-enums",
44 "Generate enum values for instructions"),
Chris Lattner15de32d2003-08-03 21:58:28 +000045 clEnumValN(GenInstrs, "gen-instr-desc",
46 "Generate instruction descriptions"),
Chris Lattnerbc520132003-06-03 04:56:29 +000047 clEnumValN(PrintEnums, "print-enums",
48 "Print enum values for a class"),
49 clEnumValN(Parse, "parse",
50 "Interpret machine code (testing only)"),
51 0));
52
53 cl::opt<std::string>
Chris Lattner85df2252003-06-03 05:07:28 +000054 Class("class", cl::desc("Print Enum list for this class"),
55 cl::value_desc("class name"));
Chris Lattner9a886382003-06-03 05:04:42 +000056
Chris Lattner90523902003-07-30 19:48:02 +000057 cl::opt<std::string>
58 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
59 cl::init("-"));
60
61 cl::opt<std::string>
62 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
Chris Lattnerbc520132003-06-03 04:56:29 +000063}
64
Chris Lattnere62c1182002-12-02 01:23:04 +000065
Chris Lattner90523902003-07-30 19:48:02 +000066void ParseFile(const std::string &Filename);
Chris Lattnere62c1182002-12-02 01:23:04 +000067
68RecordKeeper Records;
69
70static Init *getBit(Record *R, unsigned BitNo) {
71 const std::vector<RecordVal> &V = R->getValues();
72 for (unsigned i = 0, e = V.size(); i != e; ++i)
73 if (V[i].getPrefix()) {
74 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
75 "Can only handle fields of bits<> type!");
76 BitsInit *I = (BitsInit*)V[i].getValue();
77 if (BitNo < I->getNumBits())
78 return I->getBit(BitNo);
79 BitNo -= I->getNumBits();
80 }
81
82 std::cerr << "Cannot find requested bit!\n";
83 abort();
84 return 0;
85}
86
87static unsigned getNumBits(Record *R) {
88 const std::vector<RecordVal> &V = R->getValues();
89 unsigned Num = 0;
90 for (unsigned i = 0, e = V.size(); i != e; ++i)
91 if (V[i].getPrefix()) {
92 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
93 "Can only handle fields of bits<> type!");
94 Num += ((BitsInit*)V[i].getValue())->getNumBits();
95 }
96 return Num;
97}
98
99static bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) {
100 return dynamic_cast<BitInit*>(getBit(I1, BitNo)) &&
101 dynamic_cast<BitInit*>(getBit(I2, BitNo));
102}
103
104static bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) {
105 BitInit *Bit1 = dynamic_cast<BitInit*>(getBit(I1, BitNo));
106 BitInit *Bit2 = dynamic_cast<BitInit*>(getBit(I2, BitNo));
107
108 return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue();
109}
110
111static bool BitRangesEqual(Record *I1, Record *I2,
112 unsigned Start, unsigned End) {
113 for (unsigned i = Start; i != End; ++i)
114 if (!BitsAreEqual(I1, I2, i))
115 return false;
116 return true;
117}
118
119static unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) {
120 // Look for the first bit of the pair that are required to be 0 or 1.
121 while (!dynamic_cast<BitInit*>(getBit(R, FirstFixedBit)))
122 ++FirstFixedBit;
123 return FirstFixedBit;
124}
125
126static void FindInstDifferences(Record *I1, Record *I2,
127 unsigned FirstFixedBit, unsigned MaxBits,
128 unsigned &FirstVaryingBitOverall,
129 unsigned &LastFixedBitOverall) {
130 // Compare the first instruction to the rest of the instructions, looking for
131 // fields that differ.
132 //
133 unsigned FirstVaryingBit = FirstFixedBit;
134 while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit))
135 ++FirstVaryingBit;
136
137 unsigned LastFixedBit = FirstVaryingBit;
138 while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit))
139 ++LastFixedBit;
140
141 if (FirstVaryingBit < FirstVaryingBitOverall)
142 FirstVaryingBitOverall = FirstVaryingBit;
143 if (LastFixedBit < LastFixedBitOverall)
144 LastFixedBitOverall = LastFixedBit;
145}
146
147static bool getBitValue(Record *R, unsigned BitNo) {
148 Init *I = getBit(R, BitNo);
149 assert(dynamic_cast<BitInit*>(I) && "Bit should be fixed!");
150 return ((BitInit*)I)->getValue();
151}
152
153struct BitComparator {
154 unsigned BitBegin, BitEnd;
155 BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {}
156
157 bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2
158 for (unsigned i = BitBegin; i != BitEnd; ++i) {
159 bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i);
160 if (V1 < V2)
161 return true;
162 else if (V2 < V1)
163 return false;
164 }
165 return false;
166 }
167};
168
169static void PrintRange(std::vector<Record*>::iterator I,
170 std::vector<Record*>::iterator E) {
171 while (I != E) std::cerr << **I++;
172}
173
174static bool getMemoryBit(unsigned char *M, unsigned i) {
175 return (M[i/8] & (1 << (i&7))) != 0;
176}
177
178static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
179 std::vector<Record*>::iterator IE,
180 unsigned StartBit) {
181 unsigned FirstFixedBit = 0;
182 for (std::vector<Record*>::iterator I = IB; I != IE; ++I)
183 FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit));
184 return FirstFixedBit;
185}
186
187// ParseMachineCode - Try to split the vector of instructions (which is
188// intentially taken by-copy) in half, narrowing down the possible instructions
189// that we may have found. Eventually, this list will get pared down to zero or
190// one instruction, in which case we have a match or failure.
191//
192static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
193 std::vector<Record*>::iterator InstsE,
194 unsigned char *M) {
195 assert(InstsB != InstsE && "Empty range?");
196 if (InstsB+1 == InstsE) {
197 // Only a single instruction, see if we match it...
198 Record *Inst = *InstsB;
199 for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i)
200 if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i)))
201 if (getMemoryBit(M, i) != BI->getValue())
Chris Lattner1d1adea2003-08-01 04:39:05 +0000202 throw std::string("Parse failed!\n");
Chris Lattnere62c1182002-12-02 01:23:04 +0000203 return Inst;
204 }
205
206 unsigned MaxBits = ~0;
207 for (std::vector<Record*>::iterator I = InstsB; I != InstsE; ++I)
208 MaxBits = std::min(MaxBits, getNumBits(*I));
209
210 unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0);
211 unsigned FirstVaryingBit, LastFixedBit;
212 do {
213 FirstVaryingBit = ~0;
214 LastFixedBit = ~0;
215 for (std::vector<Record*>::iterator I = InstsB+1; I != InstsE; ++I)
216 FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits,
217 FirstVaryingBit, LastFixedBit);
218 if (FirstVaryingBit == MaxBits) {
219 std::cerr << "ERROR: Could not find bit to distinguish between "
220 << "the following entries!\n";
221 PrintRange(InstsB, InstsE);
222 }
223
224#if 0
225 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
226 << ": " << InstsE-InstsB << "\n";
227#endif
228
229 FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit);
230 } while (FirstVaryingBit != FirstFixedBit);
231
232 //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n";
233 //PrintRange(InstsB, InstsE);
234
235 // Sort the Insts list so that the entries have all of the bits in the range
236 // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be
237 // set to either 0 or 1 (BitInit values), which simplifies things.
238 //
239 std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit));
240
241 // Once the list is sorted by these bits, split the bit list into smaller
242 // lists, and recurse on each one.
243 //
244 std::vector<Record*>::iterator RangeBegin = InstsB;
245 Record *Match = 0;
246 while (RangeBegin != InstsE) {
247 std::vector<Record*>::iterator RangeEnd = RangeBegin+1;
248 while (RangeEnd != InstsE &&
249 BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit))
250 ++RangeEnd;
251
252 // We just identified a range of equal instructions. If this range is the
253 // input range, we were not able to distinguish between the instructions in
254 // the set. Print an error and exit!
255 //
256 if (RangeBegin == InstsB && RangeEnd == InstsE) {
257 std::cerr << "Error: Could not distinguish among the following insts!:\n";
258 PrintRange(InstsB, InstsE);
259 abort();
260 }
261
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000262#if 0
263 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
264 << ": [" << RangeEnd-RangeBegin << "] - ";
265 for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i)
266 std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " ";
267 std::cerr << "\n";
268#endif
269
Chris Lattnere62c1182002-12-02 01:23:04 +0000270 if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) {
271 if (Match) {
272 std::cerr << "Error: Multiple matches found:\n";
273 PrintRange(InstsB, InstsE);
274 }
275
276 assert(Match == 0 && "Multiple matches??");
277 Match = R;
278 }
279 RangeBegin = RangeEnd;
280 }
281
282 return Match;
283}
284
285static void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) {
286 assert(dynamic_cast<BitsInit*>(Val.getValue()) &&
287 "Can only handle undefined bits<> types!");
288 BitsInit *BI = (BitsInit*)Val.getValue();
289 assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!");
290
291 unsigned Value = 0;
292 const std::vector<RecordVal> &Vals = I->getValues();
293
294 // Start by filling in fixed values...
295 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
296 if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i)))
297 Value |= B->getValue() << i;
298
299 // Loop over all of the fields in the instruction adding in any
300 // contributions to this value (due to bit references).
301 //
302 unsigned Offset = 0;
303 for (unsigned f = 0, e = Vals.size(); f != e; ++f)
304 if (Vals[f].getPrefix()) {
Chris Lattner98334932002-12-02 17:43:43 +0000305 BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
Chris Lattnere62c1182002-12-02 01:23:04 +0000306 if (&Vals[f] == &Val) {
307 // Read the bits directly now...
308 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
309 Value |= getMemoryBit(Ptr, Offset+i) << i;
310 break;
311 }
312
313 // Scan through the field looking for bit initializers of the current
314 // variable...
Chris Lattner98334932002-12-02 17:43:43 +0000315 for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i)
Chris Lattnere62c1182002-12-02 01:23:04 +0000316 if (VarBitInit *VBI =
Chris Lattner98334932002-12-02 17:43:43 +0000317 dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
318 TypedInit *TI = VBI->getVariable();
319 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
320 if (VI->getName() == Val.getName())
321 Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum();
322 } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
323 // FIXME: implement this!
324 std::cerr << "FIELD INIT not implemented yet!\n";
325 }
Chris Lattnere62c1182002-12-02 01:23:04 +0000326 }
Chris Lattner98334932002-12-02 17:43:43 +0000327 Offset += FieldInitializer->getNumBits();
Chris Lattnere62c1182002-12-02 01:23:04 +0000328 }
329
330 std::cout << "0x" << std::hex << Value << std::dec;
331}
332
333static void PrintInstruction(Record *I, unsigned char *Ptr) {
334 std::cout << "Inst " << getNumBits(I)/8 << " bytes: "
335 << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue()
336 << "\t";
337
338 const std::vector<RecordVal> &Vals = I->getValues();
339 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
340 if (!Vals[i].getValue()->isComplete()) {
341 std::cout << Vals[i].getName() << "=";
342 PrintValue(I, Ptr, Vals[i]);
343 std::cout << "\t";
344 }
345
346 std::cout << "\n";// << *I;
347}
348
349static void ParseMachineCode() {
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000350 // X86 code
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000351 unsigned char Buffer[] = {
352 0x55, // push EBP
Chris Lattnere62c1182002-12-02 01:23:04 +0000353 0x89, 0xE5, // mov EBP, ESP
354 //0x83, 0xEC, 0x08, // sub ESP, 0x8
355 0xE8, 1, 2, 3, 4, // call +0x04030201
356 0x89, 0xEC, // mov ESP, EBP
357 0x5D, // pop EBP
358 0xC3, // ret
359 0x90, // nop
360 0xC9, // leave
361 0x89, 0xF6, // mov ESI, ESI
Chris Lattnere62c1182002-12-02 01:23:04 +0000362 0x68, 1, 2, 3, 4, // push 0x04030201
363 0x5e, // pop ESI
364 0xFF, 0xD0, // call EAX
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000365 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201
Chris Lattnere62c1182002-12-02 01:23:04 +0000366 0x85, 0xC0, // test EAX, EAX
367 0xF4, // hlt
368 };
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000369
370#if 0
371 // SparcV9 code
372 unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1,
373 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1,
374 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
375 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1,
376 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
377 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17
378 };
379#endif
380
Chris Lattner1d1adea2003-08-01 04:39:05 +0000381 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
Chris Lattnere62c1182002-12-02 01:23:04 +0000382
383 unsigned char *BuffPtr = Buffer;
384 while (1) {
385 Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr);
Chris Lattnere62c1182002-12-02 01:23:04 +0000386 PrintInstruction(R, BuffPtr);
387
388 unsigned Bits = getNumBits(R);
389 assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!");
390 BuffPtr += Bits/8;
391 }
392}
393
394
395int main(int argc, char **argv) {
396 cl::ParseCommandLineOptions(argc, argv);
Chris Lattner90523902003-07-30 19:48:02 +0000397 ParseFile(InputFilename);
Chris Lattnere62c1182002-12-02 01:23:04 +0000398
Chris Lattner9a886382003-06-03 05:04:42 +0000399 std::ostream *Out = &std::cout;
400 if (OutputFilename != "-") {
Chris Lattnere79c72d2003-08-01 20:35:01 +0000401 // Output to a .tmp file, because we don't actually want to overwrite the
402 // output file unless the generated file is different or the specified file
403 // does not exist.
404 Out = new std::ofstream((OutputFilename+".tmp").c_str());
Chris Lattner9a886382003-06-03 05:04:42 +0000405
406 if (!Out->good()) {
Chris Lattnere79c72d2003-08-01 20:35:01 +0000407 std::cerr << argv[0] << ": error opening " << OutputFilename << ".tmp!\n";
Chris Lattner9a886382003-06-03 05:04:42 +0000408 return 1;
409 }
410
411 // Make sure the file gets removed if *gasp* tablegen crashes...
Chris Lattnere79c72d2003-08-01 20:35:01 +0000412 RemoveFileOnSignal(OutputFilename+".tmp");
Chris Lattner9a886382003-06-03 05:04:42 +0000413 }
414
Chris Lattner1d1adea2003-08-01 04:39:05 +0000415 try {
416 switch (Action) {
Chris Lattneraccd8ab2003-08-01 04:47:20 +0000417 case PrintRecords:
418 *Out << Records; // No argument, dump all contents
419 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000420 case Parse:
421 ParseMachineCode();
422 break;
423 case GenEmitter:
424 CodeEmitterGen(Records).run(*Out);
425 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000426
Chris Lattner54d156d2003-08-01 05:59:20 +0000427 case GenRegisterEnums:
428 RegisterInfoEmitter(Records).runEnums(*Out);
429 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000430 case GenRegister:
431 RegisterInfoEmitter(Records).run(*Out);
432 break;
433 case GenRegisterHeader:
434 RegisterInfoEmitter(Records).runHeader(*Out);
435 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000436
437 case GenInstrEnums:
438 InstrInfoEmitter(Records).runEnums(*Out);
439 break;
Chris Lattner15de32d2003-08-03 21:58:28 +0000440 case GenInstrs:
441 InstrInfoEmitter(Records).run(*Out);
442 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000443
Chris Lattner1d1adea2003-08-01 04:39:05 +0000444 case PrintEnums:
Chris Lattner1d1adea2003-08-01 04:39:05 +0000445 std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
Chris Lattner1d1adea2003-08-01 04:39:05 +0000446 for (unsigned i = 0, e = Recs.size(); i != e; ++i)
447 *Out << Recs[i] << ", ";
448 *Out << "\n";
449 break;
Chris Lattnere62c1182002-12-02 01:23:04 +0000450 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000451 } catch (const std::string &Error) {
452 std::cerr << Error << "\n";
Chris Lattnerf1e366a2003-08-01 19:21:43 +0000453 if (Out != &std::cout) {
454 delete Out; // Close the file
455 std::remove(OutputFilename.c_str()); // Remove the file, it's broken
456 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000457 return 1;
Chris Lattnere62c1182002-12-02 01:23:04 +0000458 }
Chris Lattner9a886382003-06-03 05:04:42 +0000459
Chris Lattnere79c72d2003-08-01 20:35:01 +0000460 if (Out != &std::cout) {
461 delete Out; // Close the file
462
463 // Now that we have generated the result, check to see if we either don't
464 // have the requested file, or if the requested file is different than the
465 // file we generated. If so, move the generated file over the requested
466 // file. Otherwise, just remove the file we just generated, so 'make'
467 // doesn't try to regenerate tons of dependencies.
468 //
469 MoveFileOverIfUpdated(OutputFilename+".tmp", OutputFilename);
470 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000471 return 0;
Chris Lattnere62c1182002-12-02 01:23:04 +0000472}