1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // CodeEmitterGen uses the descriptions of instructions and their fields to 10 // construct an automated code emitter: a function called 11 // getBinaryCodeForInstr() that, given a MCInst, returns the value of the 12 // instruction - either as an uint64_t or as an APInt, depending on the 13 // maximum bit width of all Inst definitions. 14 // 15 // In addition, it generates another function called getOperandBitOffset() 16 // that, given a MCInst and an operand index, returns the minimum of indices of 17 // all bits that carry some portion of the respective operand. When the target's 18 // encodeInstruction() stores the instruction in a little-endian byte order, the 19 // returned value is the offset of the start of the operand in the encoded 20 // instruction. Other targets might need to adjust the returned value according 21 // to their encodeInstruction() implementation. 22 // 23 //===----------------------------------------------------------------------===// 24 25 #include "Common/CodeGenHwModes.h" 26 #include "Common/CodeGenInstruction.h" 27 #include "Common/CodeGenTarget.h" 28 #include "Common/InfoByHwMode.h" 29 #include "Common/VarLenCodeEmitterGen.h" 30 #include "llvm/ADT/APInt.h" 31 #include "llvm/ADT/ArrayRef.h" 32 #include "llvm/ADT/StringExtras.h" 33 #include "llvm/Support/Casting.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include "llvm/TableGen/Error.h" 36 #include "llvm/TableGen/Record.h" 37 #include "llvm/TableGen/TableGenBackend.h" 38 #include <cstdint> 39 #include <map> 40 #include <set> 41 #include <string> 42 #include <utility> 43 #include <vector> 44 45 using namespace llvm; 46 47 namespace { 48 49 class CodeEmitterGen { 50 RecordKeeper &Records; 51 52 public: 53 CodeEmitterGen(RecordKeeper &R) : Records(R) {} 54 55 void run(raw_ostream &o); 56 57 private: 58 int getVariableBit(const std::string &VarName, BitsInit *BI, int bit); 59 std::pair<std::string, std::string> 60 getInstructionCases(Record *R, CodeGenTarget &Target); 61 void addInstructionCasesForEncoding(Record *R, Record *EncodingDef, 62 CodeGenTarget &Target, std::string &Case, 63 std::string &BitOffsetCase); 64 bool addCodeToMergeInOperand(Record *R, BitsInit *BI, 65 const std::string &VarName, std::string &Case, 66 std::string &BitOffsetCase, 67 CodeGenTarget &Target); 68 69 void emitInstructionBaseValues( 70 raw_ostream &o, ArrayRef<const CodeGenInstruction *> NumberedInstructions, 71 CodeGenTarget &Target, unsigned HwMode = DefaultMode); 72 void 73 emitCaseMap(raw_ostream &o, 74 const std::map<std::string, std::vector<std::string>> &CaseMap); 75 unsigned BitWidth = 0u; 76 bool UseAPInt = false; 77 }; 78 79 // If the VarBitInit at position 'bit' matches the specified variable then 80 // return the variable bit position. Otherwise return -1. 81 int CodeEmitterGen::getVariableBit(const std::string &VarName, BitsInit *BI, 82 int bit) { 83 if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) { 84 if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar())) 85 if (VI->getName() == VarName) 86 return VBI->getBitNum(); 87 } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) { 88 if (VI->getName() == VarName) 89 return 0; 90 } 91 92 return -1; 93 } 94 95 // Returns true if it succeeds, false if an error. 96 bool CodeEmitterGen::addCodeToMergeInOperand(Record *R, BitsInit *BI, 97 const std::string &VarName, 98 std::string &Case, 99 std::string &BitOffsetCase, 100 CodeGenTarget &Target) { 101 CodeGenInstruction &CGI = Target.getInstruction(R); 102 103 // Determine if VarName actually contributes to the Inst encoding. 104 int bit = BI->getNumBits() - 1; 105 106 // Scan for a bit that this contributed to. 107 for (; bit >= 0;) { 108 if (getVariableBit(VarName, BI, bit) != -1) 109 break; 110 111 --bit; 112 } 113 114 // If we found no bits, ignore this value, otherwise emit the call to get the 115 // operand encoding. 116 if (bit < 0) 117 return true; 118 119 // If the operand matches by name, reference according to that 120 // operand number. Non-matching operands are assumed to be in 121 // order. 122 unsigned OpIdx; 123 std::pair<unsigned, unsigned> SubOp; 124 if (CGI.Operands.hasSubOperandAlias(VarName, SubOp)) { 125 OpIdx = CGI.Operands[SubOp.first].MIOperandNo + SubOp.second; 126 } else if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { 127 // Get the machine operand number for the indicated operand. 128 OpIdx = CGI.Operands[OpIdx].MIOperandNo; 129 } else { 130 PrintError(R, Twine("No operand named ") + VarName + " in record " + 131 R->getName()); 132 return false; 133 } 134 135 if (CGI.Operands.isFlatOperandNotEmitted(OpIdx)) { 136 PrintError(R, 137 "Operand " + VarName + " used but also marked as not emitted!"); 138 return false; 139 } 140 141 std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx); 142 std::string &EncoderMethodName = 143 CGI.Operands[SO.first].EncoderMethodNames[SO.second]; 144 145 if (UseAPInt) 146 Case += " op.clearAllBits();\n"; 147 148 Case += " // op: " + VarName + "\n"; 149 150 // If the source operand has a custom encoder, use it. 151 if (!EncoderMethodName.empty()) { 152 if (UseAPInt) { 153 Case += " " + EncoderMethodName + "(MI, " + utostr(OpIdx); 154 Case += ", op"; 155 } else { 156 Case += " op = " + EncoderMethodName + "(MI, " + utostr(OpIdx); 157 } 158 Case += ", Fixups, STI);\n"; 159 } else { 160 if (UseAPInt) { 161 Case += 162 " getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")"; 163 Case += ", op, Fixups, STI"; 164 } else { 165 Case += " op = getMachineOpValue(MI, MI.getOperand(" + 166 utostr(OpIdx) + ")"; 167 Case += ", Fixups, STI"; 168 } 169 Case += ");\n"; 170 } 171 172 // Precalculate the number of lits this variable contributes to in the 173 // operand. If there is a single lit (consecutive range of bits) we can use a 174 // destructive sequence on APInt that reduces memory allocations. 175 int numOperandLits = 0; 176 for (int tmpBit = bit; tmpBit >= 0;) { 177 int varBit = getVariableBit(VarName, BI, tmpBit); 178 179 // If this bit isn't from a variable, skip it. 180 if (varBit == -1) { 181 --tmpBit; 182 continue; 183 } 184 185 // Figure out the consecutive range of bits covered by this operand, in 186 // order to generate better encoding code. 187 int beginVarBit = varBit; 188 int N = 1; 189 for (--tmpBit; tmpBit >= 0;) { 190 varBit = getVariableBit(VarName, BI, tmpBit); 191 if (varBit == -1 || varBit != (beginVarBit - N)) 192 break; 193 ++N; 194 --tmpBit; 195 } 196 ++numOperandLits; 197 } 198 199 unsigned BitOffset = -1; 200 for (; bit >= 0;) { 201 int varBit = getVariableBit(VarName, BI, bit); 202 203 // If this bit isn't from a variable, skip it. 204 if (varBit == -1) { 205 --bit; 206 continue; 207 } 208 209 // Figure out the consecutive range of bits covered by this operand, in 210 // order to generate better encoding code. 211 int beginInstBit = bit; 212 int beginVarBit = varBit; 213 int N = 1; 214 for (--bit; bit >= 0;) { 215 varBit = getVariableBit(VarName, BI, bit); 216 if (varBit == -1 || varBit != (beginVarBit - N)) 217 break; 218 ++N; 219 --bit; 220 } 221 222 std::string maskStr; 223 int opShift; 224 225 unsigned loBit = beginVarBit - N + 1; 226 unsigned hiBit = loBit + N; 227 unsigned loInstBit = beginInstBit - N + 1; 228 BitOffset = loInstBit; 229 if (UseAPInt) { 230 std::string extractStr; 231 if (N >= 64) { 232 extractStr = "op.extractBits(" + itostr(hiBit - loBit) + ", " + 233 itostr(loBit) + ")"; 234 Case += " Value.insertBits(" + extractStr + ", " + 235 itostr(loInstBit) + ");\n"; 236 } else { 237 extractStr = "op.extractBitsAsZExtValue(" + itostr(hiBit - loBit) + 238 ", " + itostr(loBit) + ")"; 239 Case += " Value.insertBits(" + extractStr + ", " + 240 itostr(loInstBit) + ", " + itostr(hiBit - loBit) + ");\n"; 241 } 242 } else { 243 uint64_t opMask = ~(uint64_t)0 >> (64 - N); 244 opShift = beginVarBit - N + 1; 245 opMask <<= opShift; 246 maskStr = "UINT64_C(" + utostr(opMask) + ")"; 247 opShift = beginInstBit - beginVarBit; 248 249 if (numOperandLits == 1) { 250 Case += " op &= " + maskStr + ";\n"; 251 if (opShift > 0) { 252 Case += " op <<= " + itostr(opShift) + ";\n"; 253 } else if (opShift < 0) { 254 Case += " op >>= " + itostr(-opShift) + ";\n"; 255 } 256 Case += " Value |= op;\n"; 257 } else { 258 if (opShift > 0) { 259 Case += " Value |= (op & " + maskStr + ") << " + 260 itostr(opShift) + ";\n"; 261 } else if (opShift < 0) { 262 Case += " Value |= (op & " + maskStr + ") >> " + 263 itostr(-opShift) + ";\n"; 264 } else { 265 Case += " Value |= (op & " + maskStr + ");\n"; 266 } 267 } 268 } 269 } 270 271 if (BitOffset != (unsigned)-1) { 272 BitOffsetCase += " case " + utostr(OpIdx) + ":\n"; 273 BitOffsetCase += " // op: " + VarName + "\n"; 274 BitOffsetCase += " return " + utostr(BitOffset) + ";\n"; 275 } 276 277 return true; 278 } 279 280 std::pair<std::string, std::string> 281 CodeEmitterGen::getInstructionCases(Record *R, CodeGenTarget &Target) { 282 std::string Case, BitOffsetCase; 283 284 auto append = [&](const std::string &S) { 285 Case += S; 286 BitOffsetCase += S; 287 }; 288 289 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 290 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 291 const CodeGenHwModes &HWM = Target.getHwModes(); 292 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 293 294 // Invoke the interface to obtain the HwMode ID controlling the 295 // EncodingInfo for the current subtarget. This interface will 296 // mask off irrelevant HwMode IDs. 297 append(" unsigned HwMode = " 298 "STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);\n"); 299 Case += " switch (HwMode) {\n"; 300 Case += " default: llvm_unreachable(\"Unknown hardware mode!\"); " 301 "break;\n"; 302 for (auto &[ModeId, Encoding] : EBM) { 303 if (ModeId == DefaultMode) { 304 Case += 305 " case " + itostr(DefaultMode) + ": InstBitsByHw = InstBits"; 306 } else { 307 Case += " case " + itostr(ModeId) + 308 ": InstBitsByHw = InstBits_" + 309 std::string(HWM.getMode(ModeId).Name); 310 } 311 Case += "; break;\n"; 312 } 313 Case += " };\n"; 314 315 // We need to remodify the 'Inst' value from the table we found above. 316 if (UseAPInt) { 317 int NumWords = APInt::getNumWords(BitWidth); 318 Case += " Inst = APInt(" + itostr(BitWidth); 319 Case += ", ArrayRef(InstBitsByHw + opcode * " + itostr(NumWords) + 320 ", " + itostr(NumWords); 321 Case += "));\n"; 322 Case += " Value = Inst;\n"; 323 } else { 324 Case += " Value = InstBitsByHw[opcode];\n"; 325 } 326 327 append(" switch (HwMode) {\n"); 328 append(" default: llvm_unreachable(\"Unhandled HwMode\");\n"); 329 for (auto &[ModeId, Encoding] : EBM) { 330 append(" case " + itostr(ModeId) + ": {\n"); 331 addInstructionCasesForEncoding(R, Encoding, Target, Case, 332 BitOffsetCase); 333 append(" break;\n"); 334 append(" }\n"); 335 } 336 append(" }\n"); 337 return std::pair(std::move(Case), std::move(BitOffsetCase)); 338 } 339 } 340 addInstructionCasesForEncoding(R, R, Target, Case, BitOffsetCase); 341 return std::pair(std::move(Case), std::move(BitOffsetCase)); 342 } 343 344 void CodeEmitterGen::addInstructionCasesForEncoding( 345 Record *R, Record *EncodingDef, CodeGenTarget &Target, std::string &Case, 346 std::string &BitOffsetCase) { 347 BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst"); 348 349 // Loop over all of the fields in the instruction, determining which are the 350 // operands to the instruction. 351 bool Success = true; 352 size_t OrigBitOffsetCaseSize = BitOffsetCase.size(); 353 BitOffsetCase += " switch (OpNum) {\n"; 354 size_t BitOffsetCaseSizeBeforeLoop = BitOffsetCase.size(); 355 for (const RecordVal &RV : EncodingDef->getValues()) { 356 // Ignore fixed fields in the record, we're looking for values like: 357 // bits<5> RST = { ?, ?, ?, ?, ? }; 358 if (RV.isNonconcreteOK() || RV.getValue()->isComplete()) 359 continue; 360 361 Success &= addCodeToMergeInOperand(R, BI, std::string(RV.getName()), Case, 362 BitOffsetCase, Target); 363 } 364 // Avoid empty switches. 365 if (BitOffsetCase.size() == BitOffsetCaseSizeBeforeLoop) 366 BitOffsetCase.resize(OrigBitOffsetCaseSize); 367 else 368 BitOffsetCase += " }\n"; 369 370 if (!Success) { 371 // Dump the record, so we can see what's going on... 372 std::string E; 373 raw_string_ostream S(E); 374 S << "Dumping record for previous error:\n"; 375 S << *R; 376 PrintNote(E); 377 } 378 379 StringRef PostEmitter = R->getValueAsString("PostEncoderMethod"); 380 if (!PostEmitter.empty()) { 381 Case += " Value = "; 382 Case += PostEmitter; 383 Case += "(MI, Value"; 384 Case += ", STI"; 385 Case += ");\n"; 386 } 387 } 388 389 static void emitInstBits(raw_ostream &OS, const APInt &Bits) { 390 for (unsigned I = 0; I < Bits.getNumWords(); ++I) 391 OS << ((I > 0) ? ", " : "") << "UINT64_C(" << utostr(Bits.getRawData()[I]) 392 << ")"; 393 } 394 395 void CodeEmitterGen::emitInstructionBaseValues( 396 raw_ostream &o, ArrayRef<const CodeGenInstruction *> NumberedInstructions, 397 CodeGenTarget &Target, unsigned HwMode) { 398 const CodeGenHwModes &HWM = Target.getHwModes(); 399 if (HwMode == DefaultMode) 400 o << " static const uint64_t InstBits[] = {\n"; 401 else 402 o << " static const uint64_t InstBits_" 403 << HWM.getModeName(HwMode, /*IncludeDefault=*/true) << "[] = {\n"; 404 405 for (const CodeGenInstruction *CGI : NumberedInstructions) { 406 Record *R = CGI->TheDef; 407 408 if (R->getValueAsString("Namespace") == "TargetOpcode" || 409 R->getValueAsBit("isPseudo")) { 410 o << " "; 411 emitInstBits(o, APInt(BitWidth, 0)); 412 o << ",\n"; 413 continue; 414 } 415 416 Record *EncodingDef = R; 417 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 418 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 419 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 420 if (EBM.hasMode(HwMode)) { 421 EncodingDef = EBM.get(HwMode); 422 } else { 423 // If the HwMode does not match, then Encoding '0' 424 // should be generated. 425 APInt Value(BitWidth, 0); 426 o << " "; 427 emitInstBits(o, Value); 428 o << "," << '\t' << "// " << R->getName() << "\n"; 429 continue; 430 } 431 } 432 } 433 BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst"); 434 435 // Start by filling in fixed values. 436 APInt Value(BitWidth, 0); 437 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) { 438 if (auto *B = dyn_cast<BitInit>(BI->getBit(i)); B && B->getValue()) 439 Value.setBit(i); 440 } 441 o << " "; 442 emitInstBits(o, Value); 443 o << "," << '\t' << "// " << R->getName() << "\n"; 444 } 445 o << " UINT64_C(0)\n };\n"; 446 } 447 448 void CodeEmitterGen::emitCaseMap( 449 raw_ostream &o, 450 const std::map<std::string, std::vector<std::string>> &CaseMap) { 451 std::map<std::string, std::vector<std::string>>::const_iterator IE, EE; 452 for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) { 453 const std::string &Case = IE->first; 454 const std::vector<std::string> &InstList = IE->second; 455 456 for (int i = 0, N = InstList.size(); i < N; i++) { 457 if (i) 458 o << "\n"; 459 o << " case " << InstList[i] << ":"; 460 } 461 o << " {\n"; 462 o << Case; 463 o << " break;\n" 464 << " }\n"; 465 } 466 } 467 468 void CodeEmitterGen::run(raw_ostream &o) { 469 emitSourceFileHeader("Machine Code Emitter", o); 470 471 CodeGenTarget Target(Records); 472 std::vector<Record *> Insts = Records.getAllDerivedDefinitions("Instruction"); 473 474 // For little-endian instruction bit encodings, reverse the bit order 475 Target.reverseBitsForLittleEndianEncoding(); 476 477 ArrayRef<const CodeGenInstruction *> NumberedInstructions = 478 Target.getInstructionsByEnumValue(); 479 480 if (Target.hasVariableLengthEncodings()) { 481 emitVarLenCodeEmitter(Records, o); 482 } else { 483 const CodeGenHwModes &HWM = Target.getHwModes(); 484 // The set of HwModes used by instruction encodings. 485 std::set<unsigned> HwModes; 486 BitWidth = 0; 487 for (const CodeGenInstruction *CGI : NumberedInstructions) { 488 Record *R = CGI->TheDef; 489 if (R->getValueAsString("Namespace") == "TargetOpcode" || 490 R->getValueAsBit("isPseudo")) 491 continue; 492 493 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 494 if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 495 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 496 for (auto &KV : EBM) { 497 BitsInit *BI = KV.second->getValueAsBitsInit("Inst"); 498 BitWidth = std::max(BitWidth, BI->getNumBits()); 499 HwModes.insert(KV.first); 500 } 501 continue; 502 } 503 } 504 BitsInit *BI = R->getValueAsBitsInit("Inst"); 505 BitWidth = std::max(BitWidth, BI->getNumBits()); 506 } 507 UseAPInt = BitWidth > 64; 508 509 // Emit function declaration 510 if (UseAPInt) { 511 o << "void " << Target.getName() 512 << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 513 << " SmallVectorImpl<MCFixup> &Fixups,\n" 514 << " APInt &Inst,\n" 515 << " APInt &Scratch,\n" 516 << " const MCSubtargetInfo &STI) const {\n"; 517 } else { 518 o << "uint64_t " << Target.getName(); 519 o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 520 << " SmallVectorImpl<MCFixup> &Fixups,\n" 521 << " const MCSubtargetInfo &STI) const {\n"; 522 } 523 524 // Emit instruction base values 525 emitInstructionBaseValues(o, NumberedInstructions, Target, DefaultMode); 526 if (!HwModes.empty()) { 527 // Emit table for instrs whose encodings are controlled by HwModes. 528 for (unsigned HwMode : HwModes) { 529 if (HwMode == DefaultMode) 530 continue; 531 emitInstructionBaseValues(o, NumberedInstructions, Target, HwMode); 532 } 533 534 // This pointer will be assigned to the HwMode table later. 535 o << " const uint64_t *InstBitsByHw;\n"; 536 } 537 538 // Map to accumulate all the cases. 539 std::map<std::string, std::vector<std::string>> CaseMap; 540 std::map<std::string, std::vector<std::string>> BitOffsetCaseMap; 541 542 // Construct all cases statement for each opcode 543 for (Record *R : Insts) { 544 if (R->getValueAsString("Namespace") == "TargetOpcode" || 545 R->getValueAsBit("isPseudo")) 546 continue; 547 std::string InstName = 548 (R->getValueAsString("Namespace") + "::" + R->getName()).str(); 549 std::string Case, BitOffsetCase; 550 std::tie(Case, BitOffsetCase) = getInstructionCases(R, Target); 551 552 CaseMap[Case].push_back(InstName); 553 BitOffsetCaseMap[BitOffsetCase].push_back(std::move(InstName)); 554 } 555 556 // Emit initial function code 557 if (UseAPInt) { 558 int NumWords = APInt::getNumWords(BitWidth); 559 o << " const unsigned opcode = MI.getOpcode();\n" 560 << " if (Scratch.getBitWidth() != " << BitWidth << ")\n" 561 << " Scratch = Scratch.zext(" << BitWidth << ");\n" 562 << " Inst = APInt(" << BitWidth << ", ArrayRef(InstBits + opcode * " 563 << NumWords << ", " << NumWords << "));\n" 564 << " APInt &Value = Inst;\n" 565 << " APInt &op = Scratch;\n" 566 << " switch (opcode) {\n"; 567 } else { 568 o << " const unsigned opcode = MI.getOpcode();\n" 569 << " uint64_t Value = InstBits[opcode];\n" 570 << " uint64_t op = 0;\n" 571 << " (void)op; // suppress warning\n" 572 << " switch (opcode) {\n"; 573 } 574 575 // Emit each case statement 576 emitCaseMap(o, CaseMap); 577 578 // Default case: unhandled opcode 579 o << " default:\n" 580 << " std::string msg;\n" 581 << " raw_string_ostream Msg(msg);\n" 582 << " Msg << \"Not supported instr: \" << MI;\n" 583 << " report_fatal_error(Msg.str().c_str());\n" 584 << " }\n"; 585 if (UseAPInt) 586 o << " Inst = Value;\n"; 587 else 588 o << " return Value;\n"; 589 o << "}\n\n"; 590 591 o << "#ifdef GET_OPERAND_BIT_OFFSET\n" 592 << "#undef GET_OPERAND_BIT_OFFSET\n\n" 593 << "uint32_t " << Target.getName() 594 << "MCCodeEmitter::getOperandBitOffset(const MCInst &MI,\n" 595 << " unsigned OpNum,\n" 596 << " const MCSubtargetInfo &STI) const {\n" 597 << " switch (MI.getOpcode()) {\n"; 598 emitCaseMap(o, BitOffsetCaseMap); 599 o << " }\n" 600 << " std::string msg;\n" 601 << " raw_string_ostream Msg(msg);\n" 602 << " Msg << \"Not supported instr[opcode]: \" << MI << \"[\" << OpNum " 603 "<< \"]\";\n" 604 << " report_fatal_error(Msg.str().c_str());\n" 605 << "}\n\n" 606 << "#endif // GET_OPERAND_BIT_OFFSET\n\n"; 607 } 608 } 609 610 } // end anonymous namespace 611 612 static TableGen::Emitter::OptClass<CodeEmitterGen> 613 X("gen-emitter", "Generate machine code emitter"); 614