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