CodeEmitterGen.cpp revision 303975
1//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// 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 "CodeGenTarget.h" 17#include "llvm/ADT/StringExtras.h" 18#include "llvm/Support/CommandLine.h" 19#include "llvm/Support/Debug.h" 20#include "llvm/TableGen/Record.h" 21#include "llvm/TableGen/TableGenBackend.h" 22#include <map> 23#include <string> 24#include <vector> 25using namespace llvm; 26 27namespace { 28 29class CodeEmitterGen { 30 RecordKeeper &Records; 31public: 32 CodeEmitterGen(RecordKeeper &R) : Records(R) {} 33 34 void run(raw_ostream &o); 35private: 36 int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); 37 std::string getInstructionCase(Record *R, CodeGenTarget &Target); 38 void AddCodeToMergeInOperand(Record *R, BitsInit *BI, 39 const std::string &VarName, 40 unsigned &NumberedOp, 41 std::set<unsigned> &NamedOpIndices, 42 std::string &Case, CodeGenTarget &Target); 43 44}; 45 46// If the VarBitInit at position 'bit' matches the specified variable then 47// return the variable bit position. Otherwise return -1. 48int CodeEmitterGen::getVariableBit(const std::string &VarName, 49 BitsInit *BI, int bit) { 50 if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) { 51 if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar())) 52 if (VI->getName() == VarName) 53 return VBI->getBitNum(); 54 } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) { 55 if (VI->getName() == VarName) 56 return 0; 57 } 58 59 return -1; 60} 61 62void CodeEmitterGen:: 63AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName, 64 unsigned &NumberedOp, 65 std::set<unsigned> &NamedOpIndices, 66 std::string &Case, CodeGenTarget &Target) { 67 CodeGenInstruction &CGI = Target.getInstruction(R); 68 69 // Determine if VarName actually contributes to the Inst encoding. 70 int bit = BI->getNumBits()-1; 71 72 // Scan for a bit that this contributed to. 73 for (; bit >= 0; ) { 74 if (getVariableBit(VarName, BI, bit) != -1) 75 break; 76 77 --bit; 78 } 79 80 // If we found no bits, ignore this value, otherwise emit the call to get the 81 // operand encoding. 82 if (bit < 0) return; 83 84 // If the operand matches by name, reference according to that 85 // operand number. Non-matching operands are assumed to be in 86 // order. 87 unsigned OpIdx; 88 if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { 89 // Get the machine operand number for the indicated operand. 90 OpIdx = CGI.Operands[OpIdx].MIOperandNo; 91 assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) && 92 "Explicitly used operand also marked as not emitted!"); 93 } else { 94 unsigned NumberOps = CGI.Operands.size(); 95 /// If this operand is not supposed to be emitted by the 96 /// generated emitter, skip it. 97 while (NumberedOp < NumberOps && 98 (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) || 99 (!NamedOpIndices.empty() && NamedOpIndices.count( 100 CGI.Operands.getSubOperandNumber(NumberedOp).first)))) { 101 ++NumberedOp; 102 103 if (NumberedOp >= CGI.Operands.back().MIOperandNo + 104 CGI.Operands.back().MINumOperands) { 105 errs() << "Too few operands in record " << R->getName() << 106 " (no match for variable " << VarName << "):\n"; 107 errs() << *R; 108 errs() << '\n'; 109 110 return; 111 } 112 } 113 114 OpIdx = NumberedOp++; 115 } 116 117 std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx); 118 std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName; 119 120 // If the source operand has a custom encoder, use it. This will 121 // get the encoding for all of the suboperands. 122 if (!EncoderMethodName.empty()) { 123 // A custom encoder has all of the information for the 124 // sub-operands, if there are more than one, so only 125 // query the encoder once per source operand. 126 if (SO.second == 0) { 127 Case += " // op: " + VarName + "\n" + 128 " op = " + EncoderMethodName + "(MI, " + utostr(OpIdx); 129 Case += ", Fixups, STI"; 130 Case += ");\n"; 131 } 132 } else { 133 Case += " // op: " + VarName + "\n" + 134 " op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")"; 135 Case += ", Fixups, STI"; 136 Case += ");\n"; 137 } 138 139 for (; bit >= 0; ) { 140 int varBit = getVariableBit(VarName, BI, bit); 141 142 // If this bit isn't from a variable, skip it. 143 if (varBit == -1) { 144 --bit; 145 continue; 146 } 147 148 // Figure out the consecutive range of bits covered by this operand, in 149 // order to generate better encoding code. 150 int beginInstBit = bit; 151 int beginVarBit = varBit; 152 int N = 1; 153 for (--bit; bit >= 0;) { 154 varBit = getVariableBit(VarName, BI, bit); 155 if (varBit == -1 || varBit != (beginVarBit - N)) break; 156 ++N; 157 --bit; 158 } 159 160 uint64_t opMask = ~(uint64_t)0 >> (64-N); 161 int opShift = beginVarBit - N + 1; 162 opMask <<= opShift; 163 opShift = beginInstBit - beginVarBit; 164 165 if (opShift > 0) { 166 Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " + 167 itostr(opShift) + ";\n"; 168 } else if (opShift < 0) { 169 Case += " Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " + 170 itostr(-opShift) + ";\n"; 171 } else { 172 Case += " Value |= op & UINT64_C(" + utostr(opMask) + ");\n"; 173 } 174 } 175} 176 177 178std::string CodeEmitterGen::getInstructionCase(Record *R, 179 CodeGenTarget &Target) { 180 std::string Case; 181 182 BitsInit *BI = R->getValueAsBitsInit("Inst"); 183 const std::vector<RecordVal> &Vals = R->getValues(); 184 unsigned NumberedOp = 0; 185 186 std::set<unsigned> NamedOpIndices; 187 // Collect the set of operand indices that might correspond to named 188 // operand, and skip these when assigning operands based on position. 189 if (Target.getInstructionSet()-> 190 getValueAsBit("noNamedPositionallyEncodedOperands")) { 191 CodeGenInstruction &CGI = Target.getInstruction(R); 192 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 193 unsigned OpIdx; 194 if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx)) 195 continue; 196 197 NamedOpIndices.insert(OpIdx); 198 } 199 } 200 201 // Loop over all of the fields in the instruction, determining which are the 202 // operands to the instruction. 203 for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 204 // Ignore fixed fields in the record, we're looking for values like: 205 // bits<5> RST = { ?, ?, ?, ?, ? }; 206 if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete()) 207 continue; 208 209 AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, 210 NamedOpIndices, Case, Target); 211 } 212 213 std::string PostEmitter = R->getValueAsString("PostEncoderMethod"); 214 if (!PostEmitter.empty()) { 215 Case += " Value = " + PostEmitter + "(MI, Value"; 216 Case += ", STI"; 217 Case += ");\n"; 218 } 219 220 return Case; 221} 222 223void CodeEmitterGen::run(raw_ostream &o) { 224 CodeGenTarget Target(Records); 225 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 226 227 // For little-endian instruction bit encodings, reverse the bit order 228 Target.reverseBitsForLittleEndianEncoding(); 229 230 const std::vector<const CodeGenInstruction*> &NumberedInstructions = 231 Target.getInstructionsByEnumValue(); 232 233 // Emit function declaration 234 o << "uint64_t " << Target.getName(); 235 o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 236 << " SmallVectorImpl<MCFixup> &Fixups,\n" 237 << " const MCSubtargetInfo &STI) const {\n"; 238 239 // Emit instruction base values 240 o << " static const uint64_t InstBits[] = {\n"; 241 for (std::vector<const CodeGenInstruction*>::const_iterator 242 IN = NumberedInstructions.begin(), 243 EN = NumberedInstructions.end(); 244 IN != EN; ++IN) { 245 const CodeGenInstruction *CGI = *IN; 246 Record *R = CGI->TheDef; 247 248 if (R->getValueAsString("Namespace") == "TargetOpcode" || 249 R->getValueAsBit("isPseudo")) { 250 o << " UINT64_C(0),\n"; 251 continue; 252 } 253 254 BitsInit *BI = R->getValueAsBitsInit("Inst"); 255 256 // Start by filling in fixed values. 257 uint64_t Value = 0; 258 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 259 if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e-i-1))) 260 Value |= (uint64_t)B->getValue() << (e-i-1); 261 } 262 o << " UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n"; 263 } 264 o << " UINT64_C(0)\n };\n"; 265 266 // Map to accumulate all the cases. 267 std::map<std::string, std::vector<std::string> > CaseMap; 268 269 // Construct all cases statement for each opcode 270 for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end(); 271 IC != EC; ++IC) { 272 Record *R = *IC; 273 if (R->getValueAsString("Namespace") == "TargetOpcode" || 274 R->getValueAsBit("isPseudo")) 275 continue; 276 const std::string &InstName = R->getValueAsString("Namespace") + "::" 277 + R->getName(); 278 std::string Case = getInstructionCase(R, Target); 279 280 CaseMap[Case].push_back(InstName); 281 } 282 283 // Emit initial function code 284 o << " const unsigned opcode = MI.getOpcode();\n" 285 << " uint64_t Value = InstBits[opcode];\n" 286 << " uint64_t op = 0;\n" 287 << " (void)op; // suppress warning\n" 288 << " switch (opcode) {\n"; 289 290 // Emit each case statement 291 std::map<std::string, std::vector<std::string> >::iterator IE, EE; 292 for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 293 const std::string &Case = IE->first; 294 std::vector<std::string> &InstList = IE->second; 295 296 for (int i = 0, N = InstList.size(); i < N; i++) { 297 if (i) o << "\n"; 298 o << " case " << InstList[i] << ":"; 299 } 300 o << " {\n"; 301 o << Case; 302 o << " break;\n" 303 << " }\n"; 304 } 305 306 // Default case: unhandled opcode 307 o << " default:\n" 308 << " std::string msg;\n" 309 << " raw_string_ostream Msg(msg);\n" 310 << " Msg << \"Not supported instr: \" << MI;\n" 311 << " report_fatal_error(Msg.str());\n" 312 << " }\n" 313 << " return Value;\n" 314 << "}\n\n"; 315} 316 317} // End anonymous namespace 318 319namespace llvm { 320 321void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) { 322 emitSourceFileHeader("Machine Code Emitter", OS); 323 CodeEmitterGen(RK).run(OS); 324} 325 326} // End llvm namespace 327