CodeEmitterGen.cpp revision 0e5e49e6888c354ff95fc9e56d0881af78cb4269
1//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 2// 3// FIXME: Document. 4// 5//===----------------------------------------------------------------------===// 6 7#include "CodeEmitterGen.h" 8#include "Record.h" 9#include "Support/Debug.h" 10 11void CodeEmitterGen::run(std::ostream &o) { 12 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 13 14 EmitSourceFileHeader("Machine Code Emitter", o); 15 16 std::string Namespace = "V9::"; 17 std::string ClassName = "SparcV9CodeEmitter::"; 18 19 //const std::string &Namespace = Inst->getValue("Namespace")->getName(); 20 o << "unsigned " << ClassName 21 << "getBinaryCodeForInstr(MachineInstr &MI) {\n" 22 << " unsigned Value = 0;\n" 23 << " DEBUG(std::cerr << MI);\n" 24 << " switch (MI.getOpcode()) {\n"; 25 for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end(); 26 I != E; ++I) { 27 Record *R = *I; 28 o << " case " << Namespace << R->getName() << ": {\n" 29 << " DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n"; 30 31 BitsInit *BI = R->getValueAsBitsInit("Inst"); 32 33 unsigned Value = 0; 34 const std::vector<RecordVal> &Vals = R->getValues(); 35 36 DEBUG(o << " // prefilling: "); 37 // Start by filling in fixed values... 38 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 39 if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) { 40 Value |= B->getValue() << (e-i-1); 41 DEBUG(o << B->getValue()); 42 } else { 43 DEBUG(o << "0"); 44 } 45 } 46 DEBUG(o << "\n"); 47 48 DEBUG(o << " // " << *R->getValue("Inst") << "\n"); 49 o << " Value = " << Value << "U;\n\n"; 50 51 // Loop over all of the fields in the instruction determining which are the 52 // operands to the instruction. 53 // 54 unsigned op = 0; 55 std::map<std::string, unsigned> OpOrder; 56 std::map<std::string, bool> OpContinuous; 57 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 58 if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) { 59 // Is the operand continuous? If so, we can just mask and OR it in 60 // instead of doing it bit-by-bit, saving a lot in runtime cost. 61 const BitsInit *InstInit = BI; 62 int beginBitInVar = -1, endBitInVar = -1; 63 int beginBitInInst = -1, endBitInInst = -1; 64 bool continuous = true; 65 66 for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) { 67 if (VarBitInit *VBI = 68 dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) { 69 TypedInit *TI = VBI->getVariable(); 70 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 71 // only process the current variable 72 if (VI->getName() != Vals[i].getName()) 73 continue; 74 75 if (beginBitInVar == -1) 76 beginBitInVar = VBI->getBitNum(); 77 78 if (endBitInVar == -1) 79 endBitInVar = VBI->getBitNum(); 80 else { 81 if (endBitInVar == (int)VBI->getBitNum() + 1) 82 endBitInVar = VBI->getBitNum(); 83 else { 84 continuous = false; 85 break; 86 } 87 } 88 89 if (beginBitInInst == -1) 90 beginBitInInst = bit; 91 if (endBitInInst == -1) 92 endBitInInst = bit; 93 else { 94 if (endBitInInst == bit + 1) 95 endBitInInst = bit; 96 else { 97 continuous = false; 98 break; 99 } 100 } 101 102 // maintain same distance between bits in field and bits in 103 // instruction. if the relative distances stay the same 104 // throughout, 105 if (beginBitInVar - (int)VBI->getBitNum() != 106 beginBitInInst - bit) { 107 continuous = false; 108 break; 109 } 110 } 111 } 112 } 113 114 // If we have found no bit in "Inst" which comes from this field, then 115 // this is not an operand!! 116 if (beginBitInInst != -1) { 117 o << " // op" << op << ": " << Vals[i].getName() << "\n" 118 << " int64_t op" << op 119 <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n"; 120 //<< " MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n"; 121 OpOrder[Vals[i].getName()] = op++; 122 123 DEBUG(o << " // Var: begin = " << beginBitInVar 124 << ", end = " << endBitInVar 125 << "; Inst: begin = " << beginBitInInst 126 << ", end = " << endBitInInst << "\n"); 127 128 if (continuous) { 129 DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()] 130 << "\n"); 131 132 // Mask off the right bits 133 // Low mask (ie. shift, if necessary) 134 if (endBitInVar != 0) { 135 o << " op" << OpOrder[Vals[i].getName()] 136 << " >>= " << endBitInVar << ";\n"; 137 beginBitInVar -= endBitInVar; 138 endBitInVar = 0; 139 } 140 141 // High mask 142 o << " op" << OpOrder[Vals[i].getName()] 143 << " &= (1<<" << beginBitInVar+1 << ") - 1;\n"; 144 145 // Shift the value to the correct place (according to place in inst) 146 if (endBitInInst != 0) 147 o << " op" << OpOrder[Vals[i].getName()] 148 << " <<= " << endBitInInst << ";\n"; 149 150 // Just OR in the result 151 o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n"; 152 } 153 154 // otherwise, will be taken care of in the loop below using this 155 // value: 156 OpContinuous[Vals[i].getName()] = continuous; 157 } 158 } 159 } 160 161 for (unsigned f = 0, e = Vals.size(); f != e; ++f) { 162 if (Vals[f].getPrefix()) { 163 BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue(); 164 165 // Scan through the field looking for bit initializers of the current 166 // variable... 167 for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) { 168 if (BitInit *BI = dynamic_cast<BitInit*>(FieldInitializer->getBit(i))) 169 { 170 DEBUG(o << " // bit init: f: " << f << ", i: " << i << "\n"); 171 } else if (UnsetInit *UI = 172 dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) { 173 DEBUG(o << " // unset init: f: " << f << ", i: " << i << "\n"); 174 } else if (VarBitInit *VBI = 175 dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) { 176 TypedInit *TI = VBI->getVariable(); 177 if (VarInit *VI = dynamic_cast<VarInit*>(TI)) { 178 // If the bits of the field are laid out consecutively in the 179 // instruction, then instead of separately ORing in bits, just 180 // mask and shift the entire field for efficiency. 181 if (OpContinuous[VI->getName()]) { 182 // already taken care of in the loop above, thus there is no 183 // need to individually OR in the bits 184 185 // for debugging, output the regular version anyway, commented 186 DEBUG(o << " // Value |= getValueBit(op" 187 << OpOrder[VI->getName()] << ", " << VBI->getBitNum() 188 << ")" << " << " << i << ";\n"); 189 } else { 190 o << " Value |= getValueBit(op" << OpOrder[VI->getName()] 191 << ", " << VBI->getBitNum() 192 << ")" << " << " << i << ";\n"; 193 } 194 } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) { 195 // FIXME: implement this! 196 o << "FIELD INIT not implemented yet!\n"; 197 } else { 198 o << "Error: UNIMPLEMENTED\n"; 199 } 200 } 201 } 202 } 203 } 204 205 o << " break;\n" 206 << " }\n"; 207 } 208 209 o << " default:\n" 210 << " DEBUG(std::cerr << \"Not supported instr: \" << MI << \"\\n\");\n" 211 << " abort();\n" 212 << " }\n" 213 << " return Value;\n" 214 << "}\n"; 215} 216