CodeEmitterGen.cpp revision 3da94aec4d429b2ba0f65fa040c33650cade196b
1//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// CodeEmitterGen uses the descriptions of instructions and their fields to 11// construct an automated code emitter: a function that, given a MachineInstr, 12// returns the (currently, 32-bit unsigned) value of the instruction. 13// 14//===----------------------------------------------------------------------===// 15 16#include "CodeEmitterGen.h" 17#include "CodeGenTarget.h" 18#include "Record.h" 19#include "llvm/Support/Debug.h" 20using namespace llvm; 21 22void CodeEmitterGen::emitInstrOpBits(std::ostream &o, 23 const std::vector<RecordVal> &Vals, 24 std::map<std::string, unsigned> &OpOrder, 25 std::map<std::string, bool> &OpContinuous) 26{ 27 for (unsigned f = 0, e = Vals.size(); f != e; ++f) { 28 if (Vals[f].getPrefix()) { 29 BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); 30 31 // Scan through the field looking for bit initializers of the current 32 // variable... 33 for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) { 34 Init *I = FieldInitializer->getBit(i); 35 if (BitInit *BI = dynamic_cast<BitInit*>(I)) { 36 DEBUG(o << " // bit init: f: " << f << ", i: " << i << "\n"); 37 } else if (UnsetInit *UI = dynamic_cast<UnsetInit*>(I)) { 38 DEBUG(o << " // unset init: f: " << f << ", i: " << i << "\n"); 39 } else if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(I)) { 40 TypedInit *TI = VBI->getVariable(); 41 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 42 // If the bits of the field are laid out consecutively in the 43 // instruction, then instead of separately ORing in bits, just 44 // mask and shift the entire field for efficiency. 45 if (OpContinuous[VI->getName()]) { 46 // already taken care of in the loop above, thus there is no 47 // need to individually OR in the bits 48 49 // for debugging, output the regular version anyway, commented 50 DEBUG(o << " // Value |= getValueBit(op" 51 << OpOrder[VI->getName()] << ", " << VBI->getBitNum() 52 << ")" << " << " << i << ";\n"); 53 } else { 54 o << " Value |= getValueBit(op" << OpOrder[VI->getName()] 55 << ", " << VBI->getBitNum() 56 << ")" << " << " << i << ";\n"; 57 } 58 } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) { 59 // FIXME: implement this! 60 std::cerr << "Error: FieldInit not implemented!\n"; 61 abort(); 62 } else { 63 std::cerr << "Error: unimplemented case in " 64 << "CodeEmitterGen::emitInstrOpBits()\n"; 65 abort(); 66 } 67 } 68 } 69 } 70 } 71} 72 73 74void CodeEmitterGen::run(std::ostream &o) { 75 CodeGenTarget Target; 76 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 77 78 EmitSourceFileHeader("Machine Code Emitter", o); 79 o << "namespace llvm {\n\n"; 80 std::string Namespace = Insts[0]->getValueAsString("Namespace") + "::"; 81 82 // Emit function declaration 83 o << "unsigned " << Target.getName() << "CodeEmitter::" 84 << "getBinaryCodeForInstr(MachineInstr &MI) {\n" 85 << " unsigned Value = 0;\n" 86 << " DEBUG(std::cerr << MI);\n" 87 << " switch (MI.getOpcode()) {\n"; 88 89 // Emit a case statement for each opcode 90 for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); 91 I != E; ++I) { 92 Record *R = *I; 93 o << " case " << Namespace << R->getName() << ": {\n" 94 << " DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n"; 95 96 BitsInit *BI = R->getValueAsBitsInit("Inst"); 97 98 // For little-endian instruction bit encodings, reverse the bit order 99 if (Target.isLittleEndianEncoding()) { 100 unsigned numBits = BI->getNumBits(); 101 BitsInit *NewBI = new BitsInit(numBits); 102 for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { 103 unsigned bitSwapIdx = numBits - bit - 1; 104 Init *OrigBit = BI->getBit(bit); 105 Init *BitSwap = BI->getBit(bitSwapIdx); 106 NewBI->setBit(bit, BitSwap); 107 NewBI->setBit(bitSwapIdx, OrigBit); 108 } 109 if (numBits % 2) { 110 unsigned middle = (numBits + 1) / 2; 111 NewBI->setBit(middle, BI->getBit(middle)); 112 } 113 BI = NewBI; 114 } 115 116 unsigned Value = 0; 117 const std::vector<RecordVal> &Vals = R->getValues(); 118 119 DEBUG(o << " // prefilling: "); 120 // Start by filling in fixed values... 121 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 122 if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) { 123 Value |= B->getValue() << (e-i-1); 124 DEBUG(o << B->getValue()); 125 } else { 126 DEBUG(o << "0"); 127 } 128 } 129 DEBUG(o << "\n"); 130 131 DEBUG(o << " // " << *R->getValue("Inst") << "\n"); 132 o << " Value = " << Value << "U;\n\n"; 133 134 // Loop over all of the fields in the instruction, determining which are the 135 // operands to the instruction. 136 unsigned op = 0; 137 std::map<std::string, unsigned> OpOrder; 138 std::map<std::string, bool> OpContinuous; 139 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 140 if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) { 141 // Is the operand continuous? If so, we can just mask and OR it in 142 // instead of doing it bit-by-bit, saving a lot in runtime cost. 143 BitsInit *InstInit = BI; 144 int beginBitInVar = -1, endBitInVar = -1; 145 int beginBitInInst = -1, endBitInInst = -1; 146 bool continuous = true; 147 148 for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) { 149 if (VarBitInit *VBI = 150 dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) { 151 TypedInit *TI = VBI->getVariable(); 152 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 153 // only process the current variable 154 if (VI->getName() != Vals[i].getName()) 155 continue; 156 157 if (beginBitInVar == -1) 158 beginBitInVar = VBI->getBitNum(); 159 160 if (endBitInVar == -1) 161 endBitInVar = VBI->getBitNum(); 162 else { 163 if (endBitInVar == (int)VBI->getBitNum() + 1) 164 endBitInVar = VBI->getBitNum(); 165 else { 166 continuous = false; 167 break; 168 } 169 } 170 171 if (beginBitInInst == -1) 172 beginBitInInst = bit; 173 if (endBitInInst == -1) 174 endBitInInst = bit; 175 else { 176 if (endBitInInst == bit + 1) 177 endBitInInst = bit; 178 else { 179 continuous = false; 180 break; 181 } 182 } 183 184 // maintain same distance between bits in field and bits in 185 // instruction. if the relative distances stay the same 186 // throughout, 187 if (beginBitInVar - (int)VBI->getBitNum() != 188 beginBitInInst - bit) { 189 continuous = false; 190 break; 191 } 192 } 193 } 194 } 195 196 // If we have found no bit in "Inst" which comes from this field, then 197 // this is not an operand!! 198 if (beginBitInInst != -1) { 199 o << " // op" << op << ": " << Vals[i].getName() << "\n" 200 << " int64_t op" << op 201 <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n"; 202 //<< " MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n"; 203 OpOrder[Vals[i].getName()] = op++; 204 205 DEBUG(o << " // Var: begin = " << beginBitInVar 206 << ", end = " << endBitInVar 207 << "; Inst: begin = " << beginBitInInst 208 << ", end = " << endBitInInst << "\n"); 209 210 if (continuous) { 211 DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()] 212 << "\n"); 213 214 // Mask off the right bits 215 // Low mask (ie. shift, if necessary) 216 assert(endBitInVar >= 0 && "Negative shift amount in masking!"); 217 if (endBitInVar != 0) { 218 o << " op" << OpOrder[Vals[i].getName()] 219 << " >>= " << endBitInVar << ";\n"; 220 beginBitInVar -= endBitInVar; 221 endBitInVar = 0; 222 } 223 224 // High mask 225 o << " op" << OpOrder[Vals[i].getName()] 226 << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; 227 228 // Shift the value to the correct place (according to place in inst) 229 assert(endBitInInst >= 0 && "Negative shift amount!"); 230 if (endBitInInst != 0) 231 o << " op" << OpOrder[Vals[i].getName()] 232 << " <<= " << endBitInInst << ";\n"; 233 234 // Just OR in the result 235 o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n"; 236 } 237 238 // otherwise, will be taken care of in the loop below using this 239 // value: 240 OpContinuous[Vals[i].getName()] = continuous; 241 } 242 } 243 } 244 245 emitInstrOpBits(o, Vals, OpOrder, OpContinuous); 246 247 o << " break;\n" 248 << " }\n"; 249 } 250 251 // Default case: unhandled opcode 252 o << " default:\n" 253 << " std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n" 254 << " abort();\n" 255 << " }\n" 256 << " return Value;\n" 257 << "}\n\n"; 258 259 o << "} // End llvm namespace \n"; 260} 261