TableGen.cpp revision 2082ebe8b3a5db302748828ab4f79a36d239c1d9
11d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//===- TableGen.cpp - Top-Level TableGen implementation -------------------===// 201d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// 301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// The LLVM Compiler Infrastructure 401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// 501d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// This file was developed by the LLVM research group and is distributed under 601d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 701d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// 801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===// 91d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// 101d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// TableGen is a tool which can be used to build up a description of something, 111d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// then invoke one or more "tablegen backends" to emit information about the 121d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// description in some predefined format. In practice, this is used by the LLVM 131d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// code generators to automate generation of a code generator through a 141d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// high-level description of the target. 151d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// 161d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//===----------------------------------------------------------------------===// 171d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner 18e62c1185bee05facc25d1d725434f517261d308bChris Lattner#include "Record.h" 19e62c1185bee05facc25d1d725434f517261d308bChris Lattner#include "Support/CommandLine.h" 20bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h" 21e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner#include "Support/FileUtilities.h" 22f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman#include "CodeEmitterGen.h" 231d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner#include "RegisterInfoEmitter.h" 24169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner#include "InstrInfoEmitter.h" 253f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner#include "InstrSelectorEmitter.h" 26e62c1185bee05facc25d1d725434f517261d308bChris Lattner#include <algorithm> 27c3fe45b2f577eaf4d12cb7890773af3a8dea73c7Misha Brukman#include <cstdio> 289a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner#include <fstream> 292082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm; 30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 31bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattnerenum ActionType { 32bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner PrintRecords, 33bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner GenEmitter, 3454d156d33324b7715453993f21684915a28e310aChris Lattner GenRegisterEnums, GenRegister, GenRegisterHeader, 353f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner GenInstrEnums, GenInstrs, GenInstrSelector, 36bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner PrintEnums, 379879aa9c95850021da29bcc0ca3643c11b67f481Chris Lattner Parse 38bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner}; 39bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner 40bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattnernamespace { 41bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner cl::opt<ActionType> 42bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner Action(cl::desc("Action to perform:"), 43bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner cl::values(clEnumValN(PrintRecords, "print-records", 4485df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner "Print all records to stdout (default)"), 45bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner clEnumValN(GenEmitter, "gen-emitter", 46bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner "Generate machine code emitter"), 4754d156d33324b7715453993f21684915a28e310aChris Lattner clEnumValN(GenRegisterEnums, "gen-register-enums", 4854d156d33324b7715453993f21684915a28e310aChris Lattner "Generate enum values for registers"), 491d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner clEnumValN(GenRegister, "gen-register-desc", 501d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner "Generate a register info description"), 511d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner clEnumValN(GenRegisterHeader, "gen-register-desc-header", 521d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner "Generate a register info description header"), 53169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner clEnumValN(GenInstrEnums, "gen-instr-enums", 54169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner "Generate enum values for instructions"), 5515de32d706287e1457ab26b74d731f5367083b99Chris Lattner clEnumValN(GenInstrs, "gen-instr-desc", 5615de32d706287e1457ab26b74d731f5367083b99Chris Lattner "Generate instruction descriptions"), 573f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner clEnumValN(GenInstrSelector, "gen-instr-selector", 583f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner "Generate an instruction selector"), 59bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner clEnumValN(PrintEnums, "print-enums", 60bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner "Print enum values for a class"), 61bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner clEnumValN(Parse, "parse", 62bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner "Interpret machine code (testing only)"), 63bd935336d4dd9d9a55feed9d9ef0bd6941060f37Chris Lattner clEnumValEnd)); 64bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner 65bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner cl::opt<std::string> 6685df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner Class("class", cl::desc("Print Enum list for this class"), 6785df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner cl::value_desc("class name")); 689a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner 6990523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner cl::opt<std::string> 7090523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), 7190523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner cl::init("-")); 7290523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner 7390523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner cl::opt<std::string> 7490523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 7596b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell 7696b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell cl::opt<std::string> 7796b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell IncludeDir("I", cl::desc("Directory of include files"), 7896b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell cl::value_desc("directory"), cl::init("")); 79bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner} 80bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner 812082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnernamespace llvm { 822082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattner void ParseFile(const std::string &Filename, 832082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattner const std::string &IncludeDir); 842082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattner} 85e62c1185bee05facc25d1d725434f517261d308bChris Lattner 862082ebe8b3a5db302748828ab4f79a36d239c1d9Chris LattnerRecordKeeper llvm::Records; 87e62c1185bee05facc25d1d725434f517261d308bChris Lattner 88e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic Init *getBit(Record *R, unsigned BitNo) { 89e62c1185bee05facc25d1d725434f517261d308bChris Lattner const std::vector<RecordVal> &V = R->getValues(); 90e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = V.size(); i != e; ++i) 91e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (V[i].getPrefix()) { 92e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(dynamic_cast<BitsInit*>(V[i].getValue()) && 93e62c1185bee05facc25d1d725434f517261d308bChris Lattner "Can only handle fields of bits<> type!"); 94e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitsInit *I = (BitsInit*)V[i].getValue(); 95e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (BitNo < I->getNumBits()) 96e62c1185bee05facc25d1d725434f517261d308bChris Lattner return I->getBit(BitNo); 97e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitNo -= I->getNumBits(); 98e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 99e62c1185bee05facc25d1d725434f517261d308bChris Lattner 100e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cerr << "Cannot find requested bit!\n"; 101f5761a5e68fa805d58422ca0db5f32f049e77551Chris Lattner exit(1); 102e62c1185bee05facc25d1d725434f517261d308bChris Lattner return 0; 103e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 104e62c1185bee05facc25d1d725434f517261d308bChris Lattner 105e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic unsigned getNumBits(Record *R) { 106e62c1185bee05facc25d1d725434f517261d308bChris Lattner const std::vector<RecordVal> &V = R->getValues(); 107e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned Num = 0; 108e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = V.size(); i != e; ++i) 109e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (V[i].getPrefix()) { 110e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(dynamic_cast<BitsInit*>(V[i].getValue()) && 111e62c1185bee05facc25d1d725434f517261d308bChris Lattner "Can only handle fields of bits<> type!"); 112e62c1185bee05facc25d1d725434f517261d308bChris Lattner Num += ((BitsInit*)V[i].getValue())->getNumBits(); 113e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 114e62c1185bee05facc25d1d725434f517261d308bChris Lattner return Num; 115e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 116e62c1185bee05facc25d1d725434f517261d308bChris Lattner 117e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) { 118e62c1185bee05facc25d1d725434f517261d308bChris Lattner return dynamic_cast<BitInit*>(getBit(I1, BitNo)) && 119e62c1185bee05facc25d1d725434f517261d308bChris Lattner dynamic_cast<BitInit*>(getBit(I2, BitNo)); 120e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 121e62c1185bee05facc25d1d725434f517261d308bChris Lattner 122e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) { 123e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitInit *Bit1 = dynamic_cast<BitInit*>(getBit(I1, BitNo)); 124e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitInit *Bit2 = dynamic_cast<BitInit*>(getBit(I2, BitNo)); 125e62c1185bee05facc25d1d725434f517261d308bChris Lattner 126e62c1185bee05facc25d1d725434f517261d308bChris Lattner return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue(); 127e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 128e62c1185bee05facc25d1d725434f517261d308bChris Lattner 129e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic bool BitRangesEqual(Record *I1, Record *I2, 130e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned Start, unsigned End) { 131e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = Start; i != End; ++i) 132e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (!BitsAreEqual(I1, I2, i)) 133e62c1185bee05facc25d1d725434f517261d308bChris Lattner return false; 134e62c1185bee05facc25d1d725434f517261d308bChris Lattner return true; 135e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 136e62c1185bee05facc25d1d725434f517261d308bChris Lattner 137e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) { 138e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Look for the first bit of the pair that are required to be 0 or 1. 139e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (!dynamic_cast<BitInit*>(getBit(R, FirstFixedBit))) 140e62c1185bee05facc25d1d725434f517261d308bChris Lattner ++FirstFixedBit; 141e62c1185bee05facc25d1d725434f517261d308bChris Lattner return FirstFixedBit; 142e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 143e62c1185bee05facc25d1d725434f517261d308bChris Lattner 144e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic void FindInstDifferences(Record *I1, Record *I2, 145e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned FirstFixedBit, unsigned MaxBits, 146e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned &FirstVaryingBitOverall, 147e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned &LastFixedBitOverall) { 148e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Compare the first instruction to the rest of the instructions, looking for 149e62c1185bee05facc25d1d725434f517261d308bChris Lattner // fields that differ. 150e62c1185bee05facc25d1d725434f517261d308bChris Lattner // 151e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned FirstVaryingBit = FirstFixedBit; 152e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit)) 153e62c1185bee05facc25d1d725434f517261d308bChris Lattner ++FirstVaryingBit; 154e62c1185bee05facc25d1d725434f517261d308bChris Lattner 155e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned LastFixedBit = FirstVaryingBit; 156e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit)) 157e62c1185bee05facc25d1d725434f517261d308bChris Lattner ++LastFixedBit; 158e62c1185bee05facc25d1d725434f517261d308bChris Lattner 159e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (FirstVaryingBit < FirstVaryingBitOverall) 160e62c1185bee05facc25d1d725434f517261d308bChris Lattner FirstVaryingBitOverall = FirstVaryingBit; 161e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (LastFixedBit < LastFixedBitOverall) 162e62c1185bee05facc25d1d725434f517261d308bChris Lattner LastFixedBitOverall = LastFixedBit; 163e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 164e62c1185bee05facc25d1d725434f517261d308bChris Lattner 165e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic bool getBitValue(Record *R, unsigned BitNo) { 166e62c1185bee05facc25d1d725434f517261d308bChris Lattner Init *I = getBit(R, BitNo); 167e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(dynamic_cast<BitInit*>(I) && "Bit should be fixed!"); 168e62c1185bee05facc25d1d725434f517261d308bChris Lattner return ((BitInit*)I)->getValue(); 169e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 170e62c1185bee05facc25d1d725434f517261d308bChris Lattner 171e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstruct BitComparator { 172e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned BitBegin, BitEnd; 173e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {} 174e62c1185bee05facc25d1d725434f517261d308bChris Lattner 175e62c1185bee05facc25d1d725434f517261d308bChris Lattner bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2 176e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = BitBegin; i != BitEnd; ++i) { 177e62c1185bee05facc25d1d725434f517261d308bChris Lattner bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i); 178e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (V1 < V2) 179e62c1185bee05facc25d1d725434f517261d308bChris Lattner return true; 180e62c1185bee05facc25d1d725434f517261d308bChris Lattner else if (V2 < V1) 181e62c1185bee05facc25d1d725434f517261d308bChris Lattner return false; 182e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 183e62c1185bee05facc25d1d725434f517261d308bChris Lattner return false; 184e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 185e62c1185bee05facc25d1d725434f517261d308bChris Lattner}; 186e62c1185bee05facc25d1d725434f517261d308bChris Lattner 187e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic void PrintRange(std::vector<Record*>::iterator I, 188e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::vector<Record*>::iterator E) { 189e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (I != E) std::cerr << **I++; 190e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 191e62c1185bee05facc25d1d725434f517261d308bChris Lattner 192e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic bool getMemoryBit(unsigned char *M, unsigned i) { 193e62c1185bee05facc25d1d725434f517261d308bChris Lattner return (M[i/8] & (1 << (i&7))) != 0; 194e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 195e62c1185bee05facc25d1d725434f517261d308bChris Lattner 196e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB, 197e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::vector<Record*>::iterator IE, 198e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned StartBit) { 199e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned FirstFixedBit = 0; 200e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (std::vector<Record*>::iterator I = IB; I != IE; ++I) 201e62c1185bee05facc25d1d725434f517261d308bChris Lattner FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit)); 202e62c1185bee05facc25d1d725434f517261d308bChris Lattner return FirstFixedBit; 203e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 204e62c1185bee05facc25d1d725434f517261d308bChris Lattner 205e62c1185bee05facc25d1d725434f517261d308bChris Lattner// ParseMachineCode - Try to split the vector of instructions (which is 206737af827e830eb8eeecda42a31d44d284fbe0204Misha Brukman// intentionally taken by-copy) in half, narrowing down the possible 207737af827e830eb8eeecda42a31d44d284fbe0204Misha Brukman// instructions that we may have found. Eventually, this list will get pared 208737af827e830eb8eeecda42a31d44d284fbe0204Misha Brukman// down to zero or one instruction, in which case we have a match or failure. 209e62c1185bee05facc25d1d725434f517261d308bChris Lattner// 210e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic Record *ParseMachineCode(std::vector<Record*>::iterator InstsB, 211e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::vector<Record*>::iterator InstsE, 212e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned char *M) { 213e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(InstsB != InstsE && "Empty range?"); 214e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (InstsB+1 == InstsE) { 215e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Only a single instruction, see if we match it... 216e62c1185bee05facc25d1d725434f517261d308bChris Lattner Record *Inst = *InstsB; 217e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i) 218e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i))) 219e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (getMemoryBit(M, i) != BI->getValue()) 2201d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner throw std::string("Parse failed!\n"); 221e62c1185bee05facc25d1d725434f517261d308bChris Lattner return Inst; 222e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 223e62c1185bee05facc25d1d725434f517261d308bChris Lattner 224e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned MaxBits = ~0; 225e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (std::vector<Record*>::iterator I = InstsB; I != InstsE; ++I) 226e62c1185bee05facc25d1d725434f517261d308bChris Lattner MaxBits = std::min(MaxBits, getNumBits(*I)); 227e62c1185bee05facc25d1d725434f517261d308bChris Lattner 228e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0); 229e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned FirstVaryingBit, LastFixedBit; 230e62c1185bee05facc25d1d725434f517261d308bChris Lattner do { 231e62c1185bee05facc25d1d725434f517261d308bChris Lattner FirstVaryingBit = ~0; 232e62c1185bee05facc25d1d725434f517261d308bChris Lattner LastFixedBit = ~0; 233e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (std::vector<Record*>::iterator I = InstsB+1; I != InstsE; ++I) 234e62c1185bee05facc25d1d725434f517261d308bChris Lattner FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits, 235e62c1185bee05facc25d1d725434f517261d308bChris Lattner FirstVaryingBit, LastFixedBit); 236e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (FirstVaryingBit == MaxBits) { 237e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cerr << "ERROR: Could not find bit to distinguish between " 238e62c1185bee05facc25d1d725434f517261d308bChris Lattner << "the following entries!\n"; 239e62c1185bee05facc25d1d725434f517261d308bChris Lattner PrintRange(InstsB, InstsE); 240e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 241e62c1185bee05facc25d1d725434f517261d308bChris Lattner 242e62c1185bee05facc25d1d725434f517261d308bChris Lattner#if 0 243e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit 244e62c1185bee05facc25d1d725434f517261d308bChris Lattner << ": " << InstsE-InstsB << "\n"; 245e62c1185bee05facc25d1d725434f517261d308bChris Lattner#endif 246e62c1185bee05facc25d1d725434f517261d308bChris Lattner 247e62c1185bee05facc25d1d725434f517261d308bChris Lattner FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit); 248e62c1185bee05facc25d1d725434f517261d308bChris Lattner } while (FirstVaryingBit != FirstFixedBit); 249e62c1185bee05facc25d1d725434f517261d308bChris Lattner 250e62c1185bee05facc25d1d725434f517261d308bChris Lattner //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n"; 251e62c1185bee05facc25d1d725434f517261d308bChris Lattner //PrintRange(InstsB, InstsE); 252e62c1185bee05facc25d1d725434f517261d308bChris Lattner 253e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Sort the Insts list so that the entries have all of the bits in the range 254e62c1185bee05facc25d1d725434f517261d308bChris Lattner // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be 255e62c1185bee05facc25d1d725434f517261d308bChris Lattner // set to either 0 or 1 (BitInit values), which simplifies things. 256e62c1185bee05facc25d1d725434f517261d308bChris Lattner // 257e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit)); 258e62c1185bee05facc25d1d725434f517261d308bChris Lattner 259e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Once the list is sorted by these bits, split the bit list into smaller 260e62c1185bee05facc25d1d725434f517261d308bChris Lattner // lists, and recurse on each one. 261e62c1185bee05facc25d1d725434f517261d308bChris Lattner // 262e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::vector<Record*>::iterator RangeBegin = InstsB; 263e62c1185bee05facc25d1d725434f517261d308bChris Lattner Record *Match = 0; 264e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (RangeBegin != InstsE) { 265e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::vector<Record*>::iterator RangeEnd = RangeBegin+1; 266e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (RangeEnd != InstsE && 267e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit)) 268e62c1185bee05facc25d1d725434f517261d308bChris Lattner ++RangeEnd; 269e62c1185bee05facc25d1d725434f517261d308bChris Lattner 270e62c1185bee05facc25d1d725434f517261d308bChris Lattner // We just identified a range of equal instructions. If this range is the 271e62c1185bee05facc25d1d725434f517261d308bChris Lattner // input range, we were not able to distinguish between the instructions in 272e62c1185bee05facc25d1d725434f517261d308bChris Lattner // the set. Print an error and exit! 273e62c1185bee05facc25d1d725434f517261d308bChris Lattner // 274e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (RangeBegin == InstsB && RangeEnd == InstsE) { 275e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cerr << "Error: Could not distinguish among the following insts!:\n"; 276e62c1185bee05facc25d1d725434f517261d308bChris Lattner PrintRange(InstsB, InstsE); 277f5761a5e68fa805d58422ca0db5f32f049e77551Chris Lattner exit(1); 278e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 279e62c1185bee05facc25d1d725434f517261d308bChris Lattner 2807b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner#if 0 2817b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit 2827b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner << ": [" << RangeEnd-RangeBegin << "] - "; 2837b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i) 2847b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " "; 2857b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner std::cerr << "\n"; 2867b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner#endif 2877b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner 288e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) { 289e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (Match) { 290e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cerr << "Error: Multiple matches found:\n"; 291e62c1185bee05facc25d1d725434f517261d308bChris Lattner PrintRange(InstsB, InstsE); 292e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 293e62c1185bee05facc25d1d725434f517261d308bChris Lattner 294e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(Match == 0 && "Multiple matches??"); 295e62c1185bee05facc25d1d725434f517261d308bChris Lattner Match = R; 296e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 297e62c1185bee05facc25d1d725434f517261d308bChris Lattner RangeBegin = RangeEnd; 298e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 299e62c1185bee05facc25d1d725434f517261d308bChris Lattner 300e62c1185bee05facc25d1d725434f517261d308bChris Lattner return Match; 301e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 302e62c1185bee05facc25d1d725434f517261d308bChris Lattner 303e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) { 304e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(dynamic_cast<BitsInit*>(Val.getValue()) && 305e62c1185bee05facc25d1d725434f517261d308bChris Lattner "Can only handle undefined bits<> types!"); 306e62c1185bee05facc25d1d725434f517261d308bChris Lattner BitsInit *BI = (BitsInit*)Val.getValue(); 307e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!"); 308e62c1185bee05facc25d1d725434f517261d308bChris Lattner 309e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned Value = 0; 310e62c1185bee05facc25d1d725434f517261d308bChris Lattner const std::vector<RecordVal> &Vals = I->getValues(); 311e62c1185bee05facc25d1d725434f517261d308bChris Lattner 312e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Start by filling in fixed values... 313e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 314e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i))) 315e62c1185bee05facc25d1d725434f517261d308bChris Lattner Value |= B->getValue() << i; 316e62c1185bee05facc25d1d725434f517261d308bChris Lattner 317e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Loop over all of the fields in the instruction adding in any 318e62c1185bee05facc25d1d725434f517261d308bChris Lattner // contributions to this value (due to bit references). 319e62c1185bee05facc25d1d725434f517261d308bChris Lattner // 320e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned Offset = 0; 321e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned f = 0, e = Vals.size(); f != e; ++f) 322e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (Vals[f].getPrefix()) { 3239833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); 324e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (&Vals[f] == &Val) { 325e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Read the bits directly now... 326e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 327e62c1185bee05facc25d1d725434f517261d308bChris Lattner Value |= getMemoryBit(Ptr, Offset+i) << i; 328e62c1185bee05facc25d1d725434f517261d308bChris Lattner break; 329e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 330e62c1185bee05facc25d1d725434f517261d308bChris Lattner 331e62c1185bee05facc25d1d725434f517261d308bChris Lattner // Scan through the field looking for bit initializers of the current 332e62c1185bee05facc25d1d725434f517261d308bChris Lattner // variable... 3339833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i) 334e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (VarBitInit *VBI = 3359833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) { 3369833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner TypedInit *TI = VBI->getVariable(); 3379833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 3389833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner if (VI->getName() == Val.getName()) 3399833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum(); 3409833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) { 3419833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner // FIXME: implement this! 3429833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner std::cerr << "FIELD INIT not implemented yet!\n"; 3439833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner } 344e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 3459833493bae15d9b84cb1c5dc26a2d7bcc8aefebdChris Lattner Offset += FieldInitializer->getNumBits(); 346e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 347e62c1185bee05facc25d1d725434f517261d308bChris Lattner 348e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cout << "0x" << std::hex << Value << std::dec; 349e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 350e62c1185bee05facc25d1d725434f517261d308bChris Lattner 351e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic void PrintInstruction(Record *I, unsigned char *Ptr) { 352e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cout << "Inst " << getNumBits(I)/8 << " bytes: " 353e62c1185bee05facc25d1d725434f517261d308bChris Lattner << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue() 354e62c1185bee05facc25d1d725434f517261d308bChris Lattner << "\t"; 355e62c1185bee05facc25d1d725434f517261d308bChris Lattner 356e62c1185bee05facc25d1d725434f517261d308bChris Lattner const std::vector<RecordVal> &Vals = I->getValues(); 357e62c1185bee05facc25d1d725434f517261d308bChris Lattner for (unsigned i = 0, e = Vals.size(); i != e; ++i) 358e62c1185bee05facc25d1d725434f517261d308bChris Lattner if (!Vals[i].getValue()->isComplete()) { 359e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cout << Vals[i].getName() << "="; 360e62c1185bee05facc25d1d725434f517261d308bChris Lattner PrintValue(I, Ptr, Vals[i]); 361e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cout << "\t"; 362e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 363e62c1185bee05facc25d1d725434f517261d308bChris Lattner 364e62c1185bee05facc25d1d725434f517261d308bChris Lattner std::cout << "\n";// << *I; 365e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 366e62c1185bee05facc25d1d725434f517261d308bChris Lattner 367e62c1185bee05facc25d1d725434f517261d308bChris Lattnerstatic void ParseMachineCode() { 368f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman // X86 code 3697b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner unsigned char Buffer[] = { 3707b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner 0x55, // push EBP 371e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x89, 0xE5, // mov EBP, ESP 372e62c1185bee05facc25d1d725434f517261d308bChris Lattner //0x83, 0xEC, 0x08, // sub ESP, 0x8 373e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0xE8, 1, 2, 3, 4, // call +0x04030201 374e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x89, 0xEC, // mov ESP, EBP 375e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x5D, // pop EBP 376e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0xC3, // ret 377e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x90, // nop 378e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0xC9, // leave 379e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x89, 0xF6, // mov ESI, ESI 380e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x68, 1, 2, 3, 4, // push 0x04030201 381e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x5e, // pop ESI 382e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0xFF, 0xD0, // call EAX 3837b1d49b61d212d3428f7505d550ef767f19543f8Chris Lattner 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201 384e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0x85, 0xC0, // test EAX, EAX 385e62c1185bee05facc25d1d725434f517261d308bChris Lattner 0xF4, // hlt 386e62c1185bee05facc25d1d725434f517261d308bChris Lattner }; 387f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 388f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman#if 0 389f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman // SparcV9 code 390f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1, 391f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1, 392f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 393f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 394f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 395f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17 396f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman }; 397f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman#endif 398f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman 3991d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 400e62c1185bee05facc25d1d725434f517261d308bChris Lattner 401e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned char *BuffPtr = Buffer; 402e62c1185bee05facc25d1d725434f517261d308bChris Lattner while (1) { 403e62c1185bee05facc25d1d725434f517261d308bChris Lattner Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr); 404e62c1185bee05facc25d1d725434f517261d308bChris Lattner PrintInstruction(R, BuffPtr); 405e62c1185bee05facc25d1d725434f517261d308bChris Lattner 406e62c1185bee05facc25d1d725434f517261d308bChris Lattner unsigned Bits = getNumBits(R); 407e62c1185bee05facc25d1d725434f517261d308bChris Lattner assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!"); 408e62c1185bee05facc25d1d725434f517261d308bChris Lattner BuffPtr += Bits/8; 409e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 410e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 411e62c1185bee05facc25d1d725434f517261d308bChris Lattner 412e62c1185bee05facc25d1d725434f517261d308bChris Lattnerint main(int argc, char **argv) { 413e62c1185bee05facc25d1d725434f517261d308bChris Lattner cl::ParseCommandLineOptions(argc, argv); 41496b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell ParseFile(InputFilename, IncludeDir); 415e62c1185bee05facc25d1d725434f517261d308bChris Lattner 4169a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner std::ostream *Out = &std::cout; 4179a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner if (OutputFilename != "-") { 41842df6d1396d0335621f648b0e4a6e59f13e868f2Chris Lattner Out = new std::ofstream(OutputFilename.c_str()); 4199a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner 4209a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner if (!Out->good()) { 42142df6d1396d0335621f648b0e4a6e59f13e868f2Chris Lattner std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; 4229a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner return 1; 4239a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner } 4249a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner 4259a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner // Make sure the file gets removed if *gasp* tablegen crashes... 42642df6d1396d0335621f648b0e4a6e59f13e868f2Chris Lattner RemoveFileOnSignal(OutputFilename); 4279a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner } 4289a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner 4291d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner try { 4301d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner switch (Action) { 431accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner case PrintRecords: 432accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner *Out << Records; // No argument, dump all contents 433accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner break; 4341d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner case Parse: 4351d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner ParseMachineCode(); 4361d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner break; 4371d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner case GenEmitter: 4381d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner CodeEmitterGen(Records).run(*Out); 4391d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner break; 440169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner 44154d156d33324b7715453993f21684915a28e310aChris Lattner case GenRegisterEnums: 44254d156d33324b7715453993f21684915a28e310aChris Lattner RegisterInfoEmitter(Records).runEnums(*Out); 44354d156d33324b7715453993f21684915a28e310aChris Lattner break; 4441d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner case GenRegister: 4451d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner RegisterInfoEmitter(Records).run(*Out); 4461d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner break; 4471d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner case GenRegisterHeader: 4481d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner RegisterInfoEmitter(Records).runHeader(*Out); 4491d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner break; 450169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner 451169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner case GenInstrEnums: 452169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner InstrInfoEmitter(Records).runEnums(*Out); 453169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner break; 45415de32d706287e1457ab26b74d731f5367083b99Chris Lattner case GenInstrs: 45515de32d706287e1457ab26b74d731f5367083b99Chris Lattner InstrInfoEmitter(Records).run(*Out); 45615de32d706287e1457ab26b74d731f5367083b99Chris Lattner break; 4573f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner case GenInstrSelector: 4583f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner InstrSelectorEmitter(Records).run(*Out); 4593f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner break; 4601d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner case PrintEnums: 461d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke { 4621d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class); 4631d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner for (unsigned i = 0, e = Recs.size(); i != e; ++i) 4647b9ee51a55f7f16b54e9839d99841bc2fab71ebeChris Lattner *Out << Recs[i]->getName() << ", "; 4651d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner *Out << "\n"; 4661d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner break; 467e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 468d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke default: 469d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke assert(1 && "Invalid Action"); 470d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke return 1; 471d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke } 4721d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner } catch (const std::string &Error) { 4731d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner std::cerr << Error << "\n"; 474f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner if (Out != &std::cout) { 475f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner delete Out; // Close the file 476f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner std::remove(OutputFilename.c_str()); // Remove the file, it's broken 477f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner } 4781d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner return 1; 479e62c1185bee05facc25d1d725434f517261d308bChris Lattner } 4809a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner 481e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner if (Out != &std::cout) { 482e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner delete Out; // Close the file 483e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner } 4841d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner return 0; 485e62c1185bee05facc25d1d725434f517261d308bChris Lattner} 486