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