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