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:
CodeEmitterGen(RecordKeeper & R)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.
getVariableBit(const std::string & VarName,BitsInit * BI,int bit)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.
addCodeToMergeInOperand(Record * R,BitsInit * BI,const std::string & VarName,std::string & Case,std::string & BitOffsetCase,CodeGenTarget & Target)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>
getInstructionCases(Record * R,CodeGenTarget & Target)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
addInstructionCasesForEncoding(Record * R,Record * EncodingDef,CodeGenTarget & Target,std::string & Case,std::string & BitOffsetCase)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
emitInstBits(raw_ostream & OS,const APInt & Bits)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
emitInstructionBaseValues(raw_ostream & o,ArrayRef<const CodeGenInstruction * > NumberedInstructions,CodeGenTarget & Target,unsigned HwMode)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
emitCaseMap(raw_ostream & o,const std::map<std::string,std::vector<std::string>> & CaseMap)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
run(raw_ostream & o)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