blob: 990e2b3b3596bfcdbc9980b9e97df8b8a5e8f0a4 [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 Lattner169e66b2003-08-03 17:24:20 +000025 GenInstrEnums,
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 Lattnerbc520132003-06-03 04:56:29 +000045 clEnumValN(PrintEnums, "print-enums",
46 "Print enum values for a class"),
47 clEnumValN(Parse, "parse",
48 "Interpret machine code (testing only)"),
49 0));
50
51 cl::opt<std::string>
Chris Lattner85df2252003-06-03 05:07:28 +000052 Class("class", cl::desc("Print Enum list for this class"),
53 cl::value_desc("class name"));
Chris Lattner9a886382003-06-03 05:04:42 +000054
Chris Lattner90523902003-07-30 19:48:02 +000055 cl::opt<std::string>
56 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
57 cl::init("-"));
58
59 cl::opt<std::string>
60 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
Chris Lattnerbc520132003-06-03 04:56:29 +000061}
62
Chris Lattnere62c1182002-12-02 01:23:04 +000063
Chris Lattner90523902003-07-30 19:48:02 +000064void ParseFile(const std::string &Filename);
Chris Lattnere62c1182002-12-02 01:23:04 +000065
66RecordKeeper Records;
67
68static Init *getBit(Record *R, unsigned BitNo) {
69 const std::vector<RecordVal> &V = R->getValues();
70 for (unsigned i = 0, e = V.size(); i != e; ++i)
71 if (V[i].getPrefix()) {
72 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
73 "Can only handle fields of bits<> type!");
74 BitsInit *I = (BitsInit*)V[i].getValue();
75 if (BitNo < I->getNumBits())
76 return I->getBit(BitNo);
77 BitNo -= I->getNumBits();
78 }
79
80 std::cerr << "Cannot find requested bit!\n";
81 abort();
82 return 0;
83}
84
85static unsigned getNumBits(Record *R) {
86 const std::vector<RecordVal> &V = R->getValues();
87 unsigned Num = 0;
88 for (unsigned i = 0, e = V.size(); i != e; ++i)
89 if (V[i].getPrefix()) {
90 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
91 "Can only handle fields of bits<> type!");
92 Num += ((BitsInit*)V[i].getValue())->getNumBits();
93 }
94 return Num;
95}
96
97static bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) {
98 return dynamic_cast<BitInit*>(getBit(I1, BitNo)) &&
99 dynamic_cast<BitInit*>(getBit(I2, BitNo));
100}
101
102static bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) {
103 BitInit *Bit1 = dynamic_cast<BitInit*>(getBit(I1, BitNo));
104 BitInit *Bit2 = dynamic_cast<BitInit*>(getBit(I2, BitNo));
105
106 return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue();
107}
108
109static bool BitRangesEqual(Record *I1, Record *I2,
110 unsigned Start, unsigned End) {
111 for (unsigned i = Start; i != End; ++i)
112 if (!BitsAreEqual(I1, I2, i))
113 return false;
114 return true;
115}
116
117static unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) {
118 // Look for the first bit of the pair that are required to be 0 or 1.
119 while (!dynamic_cast<BitInit*>(getBit(R, FirstFixedBit)))
120 ++FirstFixedBit;
121 return FirstFixedBit;
122}
123
124static void FindInstDifferences(Record *I1, Record *I2,
125 unsigned FirstFixedBit, unsigned MaxBits,
126 unsigned &FirstVaryingBitOverall,
127 unsigned &LastFixedBitOverall) {
128 // Compare the first instruction to the rest of the instructions, looking for
129 // fields that differ.
130 //
131 unsigned FirstVaryingBit = FirstFixedBit;
132 while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit))
133 ++FirstVaryingBit;
134
135 unsigned LastFixedBit = FirstVaryingBit;
136 while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit))
137 ++LastFixedBit;
138
139 if (FirstVaryingBit < FirstVaryingBitOverall)
140 FirstVaryingBitOverall = FirstVaryingBit;
141 if (LastFixedBit < LastFixedBitOverall)
142 LastFixedBitOverall = LastFixedBit;
143}
144
145static bool getBitValue(Record *R, unsigned BitNo) {
146 Init *I = getBit(R, BitNo);
147 assert(dynamic_cast<BitInit*>(I) && "Bit should be fixed!");
148 return ((BitInit*)I)->getValue();
149}
150
151struct BitComparator {
152 unsigned BitBegin, BitEnd;
153 BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {}
154
155 bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2
156 for (unsigned i = BitBegin; i != BitEnd; ++i) {
157 bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i);
158 if (V1 < V2)
159 return true;
160 else if (V2 < V1)
161 return false;
162 }
163 return false;
164 }
165};
166
167static void PrintRange(std::vector<Record*>::iterator I,
168 std::vector<Record*>::iterator E) {
169 while (I != E) std::cerr << **I++;
170}
171
172static bool getMemoryBit(unsigned char *M, unsigned i) {
173 return (M[i/8] & (1 << (i&7))) != 0;
174}
175
176static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
177 std::vector<Record*>::iterator IE,
178 unsigned StartBit) {
179 unsigned FirstFixedBit = 0;
180 for (std::vector<Record*>::iterator I = IB; I != IE; ++I)
181 FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit));
182 return FirstFixedBit;
183}
184
185// ParseMachineCode - Try to split the vector of instructions (which is
186// intentially taken by-copy) in half, narrowing down the possible instructions
187// that we may have found. Eventually, this list will get pared down to zero or
188// one instruction, in which case we have a match or failure.
189//
190static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
191 std::vector<Record*>::iterator InstsE,
192 unsigned char *M) {
193 assert(InstsB != InstsE && "Empty range?");
194 if (InstsB+1 == InstsE) {
195 // Only a single instruction, see if we match it...
196 Record *Inst = *InstsB;
197 for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i)
198 if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i)))
199 if (getMemoryBit(M, i) != BI->getValue())
Chris Lattner1d1adea2003-08-01 04:39:05 +0000200 throw std::string("Parse failed!\n");
Chris Lattnere62c1182002-12-02 01:23:04 +0000201 return Inst;
202 }
203
204 unsigned MaxBits = ~0;
205 for (std::vector<Record*>::iterator I = InstsB; I != InstsE; ++I)
206 MaxBits = std::min(MaxBits, getNumBits(*I));
207
208 unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0);
209 unsigned FirstVaryingBit, LastFixedBit;
210 do {
211 FirstVaryingBit = ~0;
212 LastFixedBit = ~0;
213 for (std::vector<Record*>::iterator I = InstsB+1; I != InstsE; ++I)
214 FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits,
215 FirstVaryingBit, LastFixedBit);
216 if (FirstVaryingBit == MaxBits) {
217 std::cerr << "ERROR: Could not find bit to distinguish between "
218 << "the following entries!\n";
219 PrintRange(InstsB, InstsE);
220 }
221
222#if 0
223 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
224 << ": " << InstsE-InstsB << "\n";
225#endif
226
227 FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit);
228 } while (FirstVaryingBit != FirstFixedBit);
229
230 //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n";
231 //PrintRange(InstsB, InstsE);
232
233 // Sort the Insts list so that the entries have all of the bits in the range
234 // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be
235 // set to either 0 or 1 (BitInit values), which simplifies things.
236 //
237 std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit));
238
239 // Once the list is sorted by these bits, split the bit list into smaller
240 // lists, and recurse on each one.
241 //
242 std::vector<Record*>::iterator RangeBegin = InstsB;
243 Record *Match = 0;
244 while (RangeBegin != InstsE) {
245 std::vector<Record*>::iterator RangeEnd = RangeBegin+1;
246 while (RangeEnd != InstsE &&
247 BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit))
248 ++RangeEnd;
249
250 // We just identified a range of equal instructions. If this range is the
251 // input range, we were not able to distinguish between the instructions in
252 // the set. Print an error and exit!
253 //
254 if (RangeBegin == InstsB && RangeEnd == InstsE) {
255 std::cerr << "Error: Could not distinguish among the following insts!:\n";
256 PrintRange(InstsB, InstsE);
257 abort();
258 }
259
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000260#if 0
261 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
262 << ": [" << RangeEnd-RangeBegin << "] - ";
263 for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i)
264 std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " ";
265 std::cerr << "\n";
266#endif
267
Chris Lattnere62c1182002-12-02 01:23:04 +0000268 if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) {
269 if (Match) {
270 std::cerr << "Error: Multiple matches found:\n";
271 PrintRange(InstsB, InstsE);
272 }
273
274 assert(Match == 0 && "Multiple matches??");
275 Match = R;
276 }
277 RangeBegin = RangeEnd;
278 }
279
280 return Match;
281}
282
283static void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) {
284 assert(dynamic_cast<BitsInit*>(Val.getValue()) &&
285 "Can only handle undefined bits<> types!");
286 BitsInit *BI = (BitsInit*)Val.getValue();
287 assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!");
288
289 unsigned Value = 0;
290 const std::vector<RecordVal> &Vals = I->getValues();
291
292 // Start by filling in fixed values...
293 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
294 if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i)))
295 Value |= B->getValue() << i;
296
297 // Loop over all of the fields in the instruction adding in any
298 // contributions to this value (due to bit references).
299 //
300 unsigned Offset = 0;
301 for (unsigned f = 0, e = Vals.size(); f != e; ++f)
302 if (Vals[f].getPrefix()) {
Chris Lattner98334932002-12-02 17:43:43 +0000303 BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
Chris Lattnere62c1182002-12-02 01:23:04 +0000304 if (&Vals[f] == &Val) {
305 // Read the bits directly now...
306 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
307 Value |= getMemoryBit(Ptr, Offset+i) << i;
308 break;
309 }
310
311 // Scan through the field looking for bit initializers of the current
312 // variable...
Chris Lattner98334932002-12-02 17:43:43 +0000313 for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i)
Chris Lattnere62c1182002-12-02 01:23:04 +0000314 if (VarBitInit *VBI =
Chris Lattner98334932002-12-02 17:43:43 +0000315 dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
316 TypedInit *TI = VBI->getVariable();
317 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
318 if (VI->getName() == Val.getName())
319 Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum();
320 } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
321 // FIXME: implement this!
322 std::cerr << "FIELD INIT not implemented yet!\n";
323 }
Chris Lattnere62c1182002-12-02 01:23:04 +0000324 }
Chris Lattner98334932002-12-02 17:43:43 +0000325 Offset += FieldInitializer->getNumBits();
Chris Lattnere62c1182002-12-02 01:23:04 +0000326 }
327
328 std::cout << "0x" << std::hex << Value << std::dec;
329}
330
331static void PrintInstruction(Record *I, unsigned char *Ptr) {
332 std::cout << "Inst " << getNumBits(I)/8 << " bytes: "
333 << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue()
334 << "\t";
335
336 const std::vector<RecordVal> &Vals = I->getValues();
337 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
338 if (!Vals[i].getValue()->isComplete()) {
339 std::cout << Vals[i].getName() << "=";
340 PrintValue(I, Ptr, Vals[i]);
341 std::cout << "\t";
342 }
343
344 std::cout << "\n";// << *I;
345}
346
347static void ParseMachineCode() {
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000348 // X86 code
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000349 unsigned char Buffer[] = {
350 0x55, // push EBP
Chris Lattnere62c1182002-12-02 01:23:04 +0000351 0x89, 0xE5, // mov EBP, ESP
352 //0x83, 0xEC, 0x08, // sub ESP, 0x8
353 0xE8, 1, 2, 3, 4, // call +0x04030201
354 0x89, 0xEC, // mov ESP, EBP
355 0x5D, // pop EBP
356 0xC3, // ret
357 0x90, // nop
358 0xC9, // leave
359 0x89, 0xF6, // mov ESI, ESI
Chris Lattnere62c1182002-12-02 01:23:04 +0000360 0x68, 1, 2, 3, 4, // push 0x04030201
361 0x5e, // pop ESI
362 0xFF, 0xD0, // call EAX
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000363 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201
Chris Lattnere62c1182002-12-02 01:23:04 +0000364 0x85, 0xC0, // test EAX, EAX
365 0xF4, // hlt
366 };
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000367
368#if 0
369 // SparcV9 code
370 unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1,
371 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1,
372 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
373 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1,
374 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
375 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17
376 };
377#endif
378
Chris Lattner1d1adea2003-08-01 04:39:05 +0000379 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
Chris Lattnere62c1182002-12-02 01:23:04 +0000380
381 unsigned char *BuffPtr = Buffer;
382 while (1) {
383 Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr);
Chris Lattnere62c1182002-12-02 01:23:04 +0000384 PrintInstruction(R, BuffPtr);
385
386 unsigned Bits = getNumBits(R);
387 assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!");
388 BuffPtr += Bits/8;
389 }
390}
391
392
393int main(int argc, char **argv) {
394 cl::ParseCommandLineOptions(argc, argv);
Chris Lattner90523902003-07-30 19:48:02 +0000395 ParseFile(InputFilename);
Chris Lattnere62c1182002-12-02 01:23:04 +0000396
Chris Lattner9a886382003-06-03 05:04:42 +0000397 std::ostream *Out = &std::cout;
398 if (OutputFilename != "-") {
Chris Lattnere79c72d2003-08-01 20:35:01 +0000399 // Output to a .tmp file, because we don't actually want to overwrite the
400 // output file unless the generated file is different or the specified file
401 // does not exist.
402 Out = new std::ofstream((OutputFilename+".tmp").c_str());
Chris Lattner9a886382003-06-03 05:04:42 +0000403
404 if (!Out->good()) {
Chris Lattnere79c72d2003-08-01 20:35:01 +0000405 std::cerr << argv[0] << ": error opening " << OutputFilename << ".tmp!\n";
Chris Lattner9a886382003-06-03 05:04:42 +0000406 return 1;
407 }
408
409 // Make sure the file gets removed if *gasp* tablegen crashes...
Chris Lattnere79c72d2003-08-01 20:35:01 +0000410 RemoveFileOnSignal(OutputFilename+".tmp");
Chris Lattner9a886382003-06-03 05:04:42 +0000411 }
412
Chris Lattner1d1adea2003-08-01 04:39:05 +0000413 try {
414 switch (Action) {
Chris Lattneraccd8ab2003-08-01 04:47:20 +0000415 case PrintRecords:
416 *Out << Records; // No argument, dump all contents
417 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000418 case Parse:
419 ParseMachineCode();
420 break;
421 case GenEmitter:
422 CodeEmitterGen(Records).run(*Out);
423 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000424
Chris Lattner54d156d2003-08-01 05:59:20 +0000425 case GenRegisterEnums:
426 RegisterInfoEmitter(Records).runEnums(*Out);
427 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000428 case GenRegister:
429 RegisterInfoEmitter(Records).run(*Out);
430 break;
431 case GenRegisterHeader:
432 RegisterInfoEmitter(Records).runHeader(*Out);
433 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000434
435 case GenInstrEnums:
436 InstrInfoEmitter(Records).runEnums(*Out);
437 break;
438
Chris Lattner1d1adea2003-08-01 04:39:05 +0000439 case PrintEnums:
Chris Lattner1d1adea2003-08-01 04:39:05 +0000440 std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
Chris Lattner1d1adea2003-08-01 04:39:05 +0000441 for (unsigned i = 0, e = Recs.size(); i != e; ++i)
442 *Out << Recs[i] << ", ";
443 *Out << "\n";
444 break;
Chris Lattnere62c1182002-12-02 01:23:04 +0000445 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000446 } catch (const std::string &Error) {
447 std::cerr << Error << "\n";
Chris Lattnerf1e366a2003-08-01 19:21:43 +0000448 if (Out != &std::cout) {
449 delete Out; // Close the file
450 std::remove(OutputFilename.c_str()); // Remove the file, it's broken
451 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000452 return 1;
Chris Lattnere62c1182002-12-02 01:23:04 +0000453 }
Chris Lattner9a886382003-06-03 05:04:42 +0000454
Chris Lattnere79c72d2003-08-01 20:35:01 +0000455 if (Out != &std::cout) {
456 delete Out; // Close the file
457
458 // Now that we have generated the result, check to see if we either don't
459 // have the requested file, or if the requested file is different than the
460 // file we generated. If so, move the generated file over the requested
461 // file. Otherwise, just remove the file we just generated, so 'make'
462 // doesn't try to regenerate tons of dependencies.
463 //
464 MoveFileOverIfUpdated(OutputFilename+".tmp", OutputFilename);
465 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000466 return 0;
Chris Lattnere62c1182002-12-02 01:23:04 +0000467}