blob: baa15eb6df459efaa7897750ba5573159e0ef329 [file] [log] [blame]
Chris Lattner1d1adea2003-08-01 04:39:05 +00001//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
Misha Brukman3da94ae2005-04-22 00:00:37 +00002//
John Criswell01d45822003-10-20 20:20:30 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukman3da94ae2005-04-22 00:00:37 +00007//
John Criswell01d45822003-10-20 20:20:30 +00008//===----------------------------------------------------------------------===//
Chris Lattner1d1adea2003-08-01 04:39:05 +00009//
10// TableGen is a tool which can be used to build up a description of something,
11// then invoke one or more "tablegen backends" to emit information about the
12// description in some predefined format. In practice, this is used by the LLVM
13// code generators to automate generation of a code generator through a
14// high-level description of the target.
15//
16//===----------------------------------------------------------------------===//
17
Chris Lattnere62c1182002-12-02 01:23:04 +000018#include "Record.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000019#include "llvm/Support/CommandLine.h"
Chris Lattnerbed85ff2004-05-27 05:41:36 +000020#include "llvm/System/Signals.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000021#include "llvm/Support/FileUtilities.h"
Misha Brukmanf00ce8b2003-05-24 00:17:12 +000022#include "CodeEmitterGen.h"
Chris Lattner1d1adea2003-08-01 04:39:05 +000023#include "RegisterInfoEmitter.h"
Chris Lattner169e66b2003-08-03 17:24:20 +000024#include "InstrInfoEmitter.h"
Chris Lattner2e1f51b2004-08-01 05:59:33 +000025#include "AsmWriterEmitter.h"
Chris Lattner3f781342003-08-06 04:47:56 +000026#include "InstrSelectorEmitter.h"
Chris Lattner4a24c642005-09-03 01:14:03 +000027#include "DAGISelEmitter.h"
Chris Lattnere62c1182002-12-02 01:23:04 +000028#include <algorithm>
Misha Brukmanc3fe45b2003-08-14 16:05:35 +000029#include <cstdio>
Chris Lattner9a886382003-06-03 05:04:42 +000030#include <fstream>
Chris Lattner2082ebe2004-08-01 03:55:39 +000031using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000032
Chris Lattnerbc520132003-06-03 04:56:29 +000033enum ActionType {
34 PrintRecords,
35 GenEmitter,
Chris Lattner54d156d2003-08-01 05:59:20 +000036 GenRegisterEnums, GenRegister, GenRegisterHeader,
Chris Lattner2e1f51b2004-08-01 05:59:33 +000037 GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector,
Chris Lattner4a24c642005-09-03 01:14:03 +000038 GenDAGISel,
Chris Lattnerbc520132003-06-03 04:56:29 +000039 PrintEnums,
Chris Lattner9879aa92004-07-22 21:32:38 +000040 Parse
Chris Lattnerbc520132003-06-03 04:56:29 +000041};
42
43namespace {
44 cl::opt<ActionType>
45 Action(cl::desc("Action to perform:"),
46 cl::values(clEnumValN(PrintRecords, "print-records",
Chris Lattner85df2252003-06-03 05:07:28 +000047 "Print all records to stdout (default)"),
Chris Lattnerbc520132003-06-03 04:56:29 +000048 clEnumValN(GenEmitter, "gen-emitter",
49 "Generate machine code emitter"),
Chris Lattner54d156d2003-08-01 05:59:20 +000050 clEnumValN(GenRegisterEnums, "gen-register-enums",
51 "Generate enum values for registers"),
Chris Lattner1d1adea2003-08-01 04:39:05 +000052 clEnumValN(GenRegister, "gen-register-desc",
53 "Generate a register info description"),
54 clEnumValN(GenRegisterHeader, "gen-register-desc-header",
55 "Generate a register info description header"),
Chris Lattner169e66b2003-08-03 17:24:20 +000056 clEnumValN(GenInstrEnums, "gen-instr-enums",
57 "Generate enum values for instructions"),
Chris Lattner15de32d2003-08-03 21:58:28 +000058 clEnumValN(GenInstrs, "gen-instr-desc",
59 "Generate instruction descriptions"),
Chris Lattner2e1f51b2004-08-01 05:59:33 +000060 clEnumValN(GenAsmWriter, "gen-asm-writer",
61 "Generate assembly writer"),
Chris Lattner3f781342003-08-06 04:47:56 +000062 clEnumValN(GenInstrSelector, "gen-instr-selector",
63 "Generate an instruction selector"),
Chris Lattner4a24c642005-09-03 01:14:03 +000064 clEnumValN(GenDAGISel, "gen-dag-isel",
65 "Generate a DAG instruction selector"),
Chris Lattnerbc520132003-06-03 04:56:29 +000066 clEnumValN(PrintEnums, "print-enums",
67 "Print enum values for a class"),
68 clEnumValN(Parse, "parse",
69 "Interpret machine code (testing only)"),
Chris Lattnerbd935332004-07-16 00:02:21 +000070 clEnumValEnd));
Chris Lattnerbc520132003-06-03 04:56:29 +000071
72 cl::opt<std::string>
Chris Lattner85df2252003-06-03 05:07:28 +000073 Class("class", cl::desc("Print Enum list for this class"),
74 cl::value_desc("class name"));
Chris Lattner9a886382003-06-03 05:04:42 +000075
Chris Lattner90523902003-07-30 19:48:02 +000076 cl::opt<std::string>
77 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
78 cl::init("-"));
79
80 cl::opt<std::string>
81 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
John Criswell96b4bed2003-08-27 13:41:57 +000082
83 cl::opt<std::string>
84 IncludeDir("I", cl::desc("Directory of include files"),
85 cl::value_desc("directory"), cl::init(""));
Chris Lattnerbc520132003-06-03 04:56:29 +000086}
87
Chris Lattner2082ebe2004-08-01 03:55:39 +000088namespace llvm {
89 void ParseFile(const std::string &Filename,
90 const std::string &IncludeDir);
91}
Chris Lattnere62c1182002-12-02 01:23:04 +000092
Chris Lattner2082ebe2004-08-01 03:55:39 +000093RecordKeeper llvm::Records;
Chris Lattnere62c1182002-12-02 01:23:04 +000094
95static Init *getBit(Record *R, unsigned BitNo) {
96 const std::vector<RecordVal> &V = R->getValues();
97 for (unsigned i = 0, e = V.size(); i != e; ++i)
98 if (V[i].getPrefix()) {
99 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000100 "Can only handle fields of bits<> type!");
Chris Lattnere62c1182002-12-02 01:23:04 +0000101 BitsInit *I = (BitsInit*)V[i].getValue();
102 if (BitNo < I->getNumBits())
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000103 return I->getBit(BitNo);
Chris Lattnere62c1182002-12-02 01:23:04 +0000104 BitNo -= I->getNumBits();
105 }
106
107 std::cerr << "Cannot find requested bit!\n";
Chris Lattnerf5761a52004-02-13 16:37:43 +0000108 exit(1);
Chris Lattnere62c1182002-12-02 01:23:04 +0000109 return 0;
110}
111
112static unsigned getNumBits(Record *R) {
113 const std::vector<RecordVal> &V = R->getValues();
114 unsigned Num = 0;
115 for (unsigned i = 0, e = V.size(); i != e; ++i)
116 if (V[i].getPrefix()) {
117 assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000118 "Can only handle fields of bits<> type!");
Chris Lattnere62c1182002-12-02 01:23:04 +0000119 Num += ((BitsInit*)V[i].getValue())->getNumBits();
120 }
121 return Num;
122}
123
124static bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) {
125 return dynamic_cast<BitInit*>(getBit(I1, BitNo)) &&
126 dynamic_cast<BitInit*>(getBit(I2, BitNo));
127}
128
129static bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) {
130 BitInit *Bit1 = dynamic_cast<BitInit*>(getBit(I1, BitNo));
131 BitInit *Bit2 = dynamic_cast<BitInit*>(getBit(I2, BitNo));
132
133 return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue();
134}
135
136static bool BitRangesEqual(Record *I1, Record *I2,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000137 unsigned Start, unsigned End) {
Chris Lattnere62c1182002-12-02 01:23:04 +0000138 for (unsigned i = Start; i != End; ++i)
139 if (!BitsAreEqual(I1, I2, i))
140 return false;
141 return true;
142}
143
144static unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) {
145 // Look for the first bit of the pair that are required to be 0 or 1.
146 while (!dynamic_cast<BitInit*>(getBit(R, FirstFixedBit)))
147 ++FirstFixedBit;
148 return FirstFixedBit;
149}
150
151static void FindInstDifferences(Record *I1, Record *I2,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000152 unsigned FirstFixedBit, unsigned MaxBits,
153 unsigned &FirstVaryingBitOverall,
154 unsigned &LastFixedBitOverall) {
Chris Lattnere62c1182002-12-02 01:23:04 +0000155 // Compare the first instruction to the rest of the instructions, looking for
156 // fields that differ.
157 //
158 unsigned FirstVaryingBit = FirstFixedBit;
159 while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit))
160 ++FirstVaryingBit;
161
162 unsigned LastFixedBit = FirstVaryingBit;
163 while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit))
164 ++LastFixedBit;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000165
Chris Lattnere62c1182002-12-02 01:23:04 +0000166 if (FirstVaryingBit < FirstVaryingBitOverall)
167 FirstVaryingBitOverall = FirstVaryingBit;
168 if (LastFixedBit < LastFixedBitOverall)
169 LastFixedBitOverall = LastFixedBit;
170}
171
172static bool getBitValue(Record *R, unsigned BitNo) {
173 Init *I = getBit(R, BitNo);
174 assert(dynamic_cast<BitInit*>(I) && "Bit should be fixed!");
175 return ((BitInit*)I)->getValue();
176}
177
178struct BitComparator {
179 unsigned BitBegin, BitEnd;
180 BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {}
181
182 bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2
183 for (unsigned i = BitBegin; i != BitEnd; ++i) {
184 bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i);
185 if (V1 < V2)
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000186 return true;
Chris Lattnere62c1182002-12-02 01:23:04 +0000187 else if (V2 < V1)
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000188 return false;
Chris Lattnere62c1182002-12-02 01:23:04 +0000189 }
190 return false;
191 }
192};
193
Misha Brukman3da94ae2005-04-22 00:00:37 +0000194static void PrintRange(std::vector<Record*>::iterator I,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000195 std::vector<Record*>::iterator E) {
Chris Lattnere62c1182002-12-02 01:23:04 +0000196 while (I != E) std::cerr << **I++;
197}
198
199static bool getMemoryBit(unsigned char *M, unsigned i) {
200 return (M[i/8] & (1 << (i&7))) != 0;
201}
202
203static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000204 std::vector<Record*>::iterator IE,
205 unsigned StartBit) {
Chris Lattnere62c1182002-12-02 01:23:04 +0000206 unsigned FirstFixedBit = 0;
207 for (std::vector<Record*>::iterator I = IB; I != IE; ++I)
208 FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit));
209 return FirstFixedBit;
210}
211
212// ParseMachineCode - Try to split the vector of instructions (which is
Misha Brukman737af822003-09-07 20:12:52 +0000213// intentionally taken by-copy) in half, narrowing down the possible
214// instructions that we may have found. Eventually, this list will get pared
215// down to zero or one instruction, in which case we have a match or failure.
Chris Lattnere62c1182002-12-02 01:23:04 +0000216//
Misha Brukman3da94ae2005-04-22 00:00:37 +0000217static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000218 std::vector<Record*>::iterator InstsE,
219 unsigned char *M) {
Chris Lattnere62c1182002-12-02 01:23:04 +0000220 assert(InstsB != InstsE && "Empty range?");
221 if (InstsB+1 == InstsE) {
222 // Only a single instruction, see if we match it...
223 Record *Inst = *InstsB;
224 for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i)
225 if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i)))
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000226 if (getMemoryBit(M, i) != BI->getValue())
227 throw std::string("Parse failed!\n");
Chris Lattnere62c1182002-12-02 01:23:04 +0000228 return Inst;
229 }
230
231 unsigned MaxBits = ~0;
232 for (std::vector<Record*>::iterator I = InstsB; I != InstsE; ++I)
233 MaxBits = std::min(MaxBits, getNumBits(*I));
234
235 unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0);
236 unsigned FirstVaryingBit, LastFixedBit;
237 do {
238 FirstVaryingBit = ~0;
239 LastFixedBit = ~0;
240 for (std::vector<Record*>::iterator I = InstsB+1; I != InstsE; ++I)
241 FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits,
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000242 FirstVaryingBit, LastFixedBit);
Chris Lattnere62c1182002-12-02 01:23:04 +0000243 if (FirstVaryingBit == MaxBits) {
244 std::cerr << "ERROR: Could not find bit to distinguish between "
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000245 << "the following entries!\n";
Chris Lattnere62c1182002-12-02 01:23:04 +0000246 PrintRange(InstsB, InstsE);
247 }
248
249#if 0
250 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000251 << ": " << InstsE-InstsB << "\n";
Chris Lattnere62c1182002-12-02 01:23:04 +0000252#endif
253
254 FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit);
255 } while (FirstVaryingBit != FirstFixedBit);
256
257 //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n";
258 //PrintRange(InstsB, InstsE);
259
260 // Sort the Insts list so that the entries have all of the bits in the range
261 // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be
262 // set to either 0 or 1 (BitInit values), which simplifies things.
263 //
264 std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit));
265
266 // Once the list is sorted by these bits, split the bit list into smaller
267 // lists, and recurse on each one.
268 //
269 std::vector<Record*>::iterator RangeBegin = InstsB;
270 Record *Match = 0;
271 while (RangeBegin != InstsE) {
272 std::vector<Record*>::iterator RangeEnd = RangeBegin+1;
273 while (RangeEnd != InstsE &&
274 BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit))
275 ++RangeEnd;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000276
Chris Lattnere62c1182002-12-02 01:23:04 +0000277 // We just identified a range of equal instructions. If this range is the
278 // input range, we were not able to distinguish between the instructions in
279 // the set. Print an error and exit!
280 //
281 if (RangeBegin == InstsB && RangeEnd == InstsE) {
282 std::cerr << "Error: Could not distinguish among the following insts!:\n";
283 PrintRange(InstsB, InstsE);
Chris Lattnerf5761a52004-02-13 16:37:43 +0000284 exit(1);
Chris Lattnere62c1182002-12-02 01:23:04 +0000285 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000286
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000287#if 0
288 std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000289 << ": [" << RangeEnd-RangeBegin << "] - ";
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000290 for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i)
291 std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " ";
292 std::cerr << "\n";
293#endif
294
Chris Lattnere62c1182002-12-02 01:23:04 +0000295 if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) {
296 if (Match) {
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000297 std::cerr << "Error: Multiple matches found:\n";
298 PrintRange(InstsB, InstsE);
Chris Lattnere62c1182002-12-02 01:23:04 +0000299 }
300
301 assert(Match == 0 && "Multiple matches??");
302 Match = R;
303 }
304 RangeBegin = RangeEnd;
305 }
306
307 return Match;
308}
309
310static void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) {
311 assert(dynamic_cast<BitsInit*>(Val.getValue()) &&
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000312 "Can only handle undefined bits<> types!");
Chris Lattnere62c1182002-12-02 01:23:04 +0000313 BitsInit *BI = (BitsInit*)Val.getValue();
314 assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!");
315
316 unsigned Value = 0;
317 const std::vector<RecordVal> &Vals = I->getValues();
318
319 // Start by filling in fixed values...
320 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
321 if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i)))
322 Value |= B->getValue() << i;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000323
Chris Lattnere62c1182002-12-02 01:23:04 +0000324 // Loop over all of the fields in the instruction adding in any
325 // contributions to this value (due to bit references).
326 //
327 unsigned Offset = 0;
328 for (unsigned f = 0, e = Vals.size(); f != e; ++f)
329 if (Vals[f].getPrefix()) {
Chris Lattner98334932002-12-02 17:43:43 +0000330 BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
Chris Lattnere62c1182002-12-02 01:23:04 +0000331 if (&Vals[f] == &Val) {
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000332 // Read the bits directly now...
333 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
334 Value |= getMemoryBit(Ptr, Offset+i) << i;
335 break;
Chris Lattnere62c1182002-12-02 01:23:04 +0000336 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000337
Chris Lattnere62c1182002-12-02 01:23:04 +0000338 // Scan through the field looking for bit initializers of the current
339 // variable...
Chris Lattner98334932002-12-02 17:43:43 +0000340 for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i)
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000341 if (VarBitInit *VBI =
342 dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
Chris Lattner98334932002-12-02 17:43:43 +0000343 TypedInit *TI = VBI->getVariable();
344 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
345 if (VI->getName() == Val.getName())
346 Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum();
347 } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
348 // FIXME: implement this!
349 std::cerr << "FIELD INIT not implemented yet!\n";
350 }
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000351 }
Chris Lattner98334932002-12-02 17:43:43 +0000352 Offset += FieldInitializer->getNumBits();
Chris Lattnere62c1182002-12-02 01:23:04 +0000353 }
354
355 std::cout << "0x" << std::hex << Value << std::dec;
356}
357
358static void PrintInstruction(Record *I, unsigned char *Ptr) {
359 std::cout << "Inst " << getNumBits(I)/8 << " bytes: "
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000360 << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue()
361 << "\t";
Misha Brukman3da94ae2005-04-22 00:00:37 +0000362
Chris Lattnere62c1182002-12-02 01:23:04 +0000363 const std::vector<RecordVal> &Vals = I->getValues();
364 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
365 if (!Vals[i].getValue()->isComplete()) {
366 std::cout << Vals[i].getName() << "=";
367 PrintValue(I, Ptr, Vals[i]);
368 std::cout << "\t";
369 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000370
Chris Lattnere62c1182002-12-02 01:23:04 +0000371 std::cout << "\n";// << *I;
372}
373
374static void ParseMachineCode() {
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000375 // X86 code
Chris Lattner7b1d49b2002-12-03 20:01:04 +0000376 unsigned char Buffer[] = {
377 0x55, // push EBP
Jeff Cohenea3e5e52005-04-22 04:13:13 +0000378 0x89, 0xE5, // mov EBP, ESP
379 //0x83, 0xEC, 0x08, // sub ESP, 0x8
380 0xE8, 1, 2, 3, 4, // call +0x04030201
381 0x89, 0xEC, // mov ESP, EBP
382 0x5D, // pop EBP
383 0xC3, // ret
384 0x90, // nop
385 0xC9, // leave
386 0x89, 0xF6, // mov ESI, ESI
387 0x68, 1, 2, 3, 4, // push 0x04030201
388 0x5e, // pop ESI
389 0xFF, 0xD0, // call EAX
390 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201
391 0x85, 0xC0, // test EAX, EAX
392 0xF4, // hlt
Chris Lattnere62c1182002-12-02 01:23:04 +0000393 };
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000394
395#if 0
396 // SparcV9 code
Misha Brukman3da94ae2005-04-22 00:00:37 +0000397 unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1,
Misha Brukmanf00ce8b2003-05-24 00:17:12 +0000398 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1,
399 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
400 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1,
401 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
402 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17
403 };
404#endif
405
Chris Lattner1d1adea2003-08-01 04:39:05 +0000406 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
Chris Lattnere62c1182002-12-02 01:23:04 +0000407
408 unsigned char *BuffPtr = Buffer;
409 while (1) {
410 Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr);
Chris Lattnere62c1182002-12-02 01:23:04 +0000411 PrintInstruction(R, BuffPtr);
412
413 unsigned Bits = getNumBits(R);
414 assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!");
415 BuffPtr += Bits/8;
416 }
417}
418
Chris Lattnere62c1182002-12-02 01:23:04 +0000419int main(int argc, char **argv) {
420 cl::ParseCommandLineOptions(argc, argv);
John Criswell96b4bed2003-08-27 13:41:57 +0000421 ParseFile(InputFilename, IncludeDir);
Chris Lattnere62c1182002-12-02 01:23:04 +0000422
Chris Lattner9a886382003-06-03 05:04:42 +0000423 std::ostream *Out = &std::cout;
424 if (OutputFilename != "-") {
Chris Lattner42df6d12004-07-13 06:11:46 +0000425 Out = new std::ofstream(OutputFilename.c_str());
Chris Lattner9a886382003-06-03 05:04:42 +0000426
427 if (!Out->good()) {
Chris Lattner42df6d12004-07-13 06:11:46 +0000428 std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
Chris Lattner9a886382003-06-03 05:04:42 +0000429 return 1;
430 }
431
432 // Make sure the file gets removed if *gasp* tablegen crashes...
Reid Spencer227b6d02004-11-14 22:30:54 +0000433 sys::RemoveFileOnSignal(sys::Path(OutputFilename));
Chris Lattner9a886382003-06-03 05:04:42 +0000434 }
435
Chris Lattner1d1adea2003-08-01 04:39:05 +0000436 try {
437 switch (Action) {
Chris Lattneraccd8ab2003-08-01 04:47:20 +0000438 case PrintRecords:
439 *Out << Records; // No argument, dump all contents
440 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000441 case Parse:
442 ParseMachineCode();
443 break;
444 case GenEmitter:
445 CodeEmitterGen(Records).run(*Out);
446 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000447
Chris Lattner54d156d2003-08-01 05:59:20 +0000448 case GenRegisterEnums:
449 RegisterInfoEmitter(Records).runEnums(*Out);
450 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000451 case GenRegister:
452 RegisterInfoEmitter(Records).run(*Out);
453 break;
454 case GenRegisterHeader:
455 RegisterInfoEmitter(Records).runHeader(*Out);
456 break;
Chris Lattner169e66b2003-08-03 17:24:20 +0000457
458 case GenInstrEnums:
459 InstrInfoEmitter(Records).runEnums(*Out);
460 break;
Chris Lattner15de32d2003-08-03 21:58:28 +0000461 case GenInstrs:
462 InstrInfoEmitter(Records).run(*Out);
463 break;
Chris Lattner2e1f51b2004-08-01 05:59:33 +0000464
465 case GenAsmWriter:
466 AsmWriterEmitter(Records).run(*Out);
467 break;
468
Chris Lattner3f781342003-08-06 04:47:56 +0000469 case GenInstrSelector:
470 InstrSelectorEmitter(Records).run(*Out);
471 break;
Chris Lattner4a24c642005-09-03 01:14:03 +0000472 case GenDAGISel:
473 DAGISelEmitter(Records).run(*Out);
474 break;
Chris Lattner1d1adea2003-08-01 04:39:05 +0000475 case PrintEnums:
Brian Gaeked0fde302003-11-11 22:41:34 +0000476 {
Chris Lattner1d1adea2003-08-01 04:39:05 +0000477 std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
Chris Lattner1d1adea2003-08-01 04:39:05 +0000478 for (unsigned i = 0, e = Recs.size(); i != e; ++i)
Chris Lattner7b9ee512004-02-06 03:19:17 +0000479 *Out << Recs[i]->getName() << ", ";
Chris Lattner1d1adea2003-08-01 04:39:05 +0000480 *Out << "\n";
481 break;
Chris Lattnere62c1182002-12-02 01:23:04 +0000482 }
Brian Gaeked0fde302003-11-11 22:41:34 +0000483 default:
484 assert(1 && "Invalid Action");
485 return 1;
486 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000487 } catch (const std::string &Error) {
Reid Spencer23f7d512004-09-03 23:17:54 +0000488 std::cerr << argv[0] << ": " << Error << "\n";
Chris Lattnerf1e366a2003-08-01 19:21:43 +0000489 if (Out != &std::cout) {
490 delete Out; // Close the file
491 std::remove(OutputFilename.c_str()); // Remove the file, it's broken
492 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000493 return 1;
Reid Spencer23f7d512004-09-03 23:17:54 +0000494 } catch (...) {
495 std::cerr << argv[0] << ": Unknown unexpected exception occurred.\n";
496 if (Out != &std::cout) {
497 delete Out; // Close the file
498 std::remove(OutputFilename.c_str()); // Remove the file, it's broken
499 }
500 return 2;
Chris Lattnere62c1182002-12-02 01:23:04 +0000501 }
Chris Lattner9a886382003-06-03 05:04:42 +0000502
Chris Lattnere79c72d2003-08-01 20:35:01 +0000503 if (Out != &std::cout) {
504 delete Out; // Close the file
Chris Lattnere79c72d2003-08-01 20:35:01 +0000505 }
Chris Lattner1d1adea2003-08-01 04:39:05 +0000506 return 0;
Chris Lattnere62c1182002-12-02 01:23:04 +0000507}