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