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
45using namespace llvm;
46
47namespace {
48
49class CodeEmitterGen {
50 const RecordKeeper &Records;
51
52public:
53 CodeEmitterGen(const RecordKeeper &R) : Records(R) {}
54
55 void run(raw_ostream &O);
56
57private:
58 int getVariableBit(const std::string &VarName, const BitsInit *BI, int Bit);
59 std::pair<std::string, std::string>
60 getInstructionCases(const Record *R, const CodeGenTarget &Target);
61 void addInstructionCasesForEncoding(const Record *R,
62 const Record *EncodingDef,
63 const CodeGenTarget &Target,
64 std::string &Case,
65 std::string &BitOffsetCase);
66 bool addCodeToMergeInOperand(const Record *R, const BitsInit *BI,
67 const std::string &VarName, std::string &Case,
68 std::string &BitOffsetCase,
69 const CodeGenTarget &Target);
70
71 void emitInstructionBaseValues(
72 raw_ostream &O, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
73 const CodeGenTarget &Target, unsigned HwMode = DefaultMode);
74 void
75 emitCaseMap(raw_ostream &O,
76 const std::map<std::string, std::vector<std::string>> &CaseMap);
77 unsigned BitWidth = 0u;
78 bool UseAPInt = false;
79};
80
81// If the VarBitInit at position 'bit' matches the specified variable then
82// return the variable bit position. Otherwise return -1.
83int CodeEmitterGen::getVariableBit(const std::string &VarName,
84 const BitsInit *BI, int Bit) {
85 if (const VarBitInit *VBI = dyn_cast<VarBitInit>(Val: BI->getBit(Bit))) {
86 if (const VarInit *VI = dyn_cast<VarInit>(Val: VBI->getBitVar()))
87 if (VI->getName() == VarName)
88 return VBI->getBitNum();
89 } else if (const VarInit *VI = dyn_cast<VarInit>(Val: BI->getBit(Bit))) {
90 if (VI->getName() == VarName)
91 return 0;
92 }
93
94 return -1;
95}
96
97// Returns true if it succeeds, false if an error.
98bool CodeEmitterGen::addCodeToMergeInOperand(const Record *R,
99 const BitsInit *BI,
100 const std::string &VarName,
101 std::string &Case,
102 std::string &BitOffsetCase,
103 const CodeGenTarget &Target) {
104 CodeGenInstruction &CGI = Target.getInstruction(InstRec: R);
105
106 // Determine if VarName actually contributes to the Inst encoding.
107 int Bit = BI->getNumBits() - 1;
108
109 // Scan for a bit that this contributed to.
110 for (; Bit >= 0;) {
111 if (getVariableBit(VarName, BI, Bit) != -1)
112 break;
113
114 --Bit;
115 }
116
117 // If we found no bits, ignore this value, otherwise emit the call to get the
118 // operand encoding.
119 if (Bit < 0)
120 return true;
121
122 // If the operand matches by name, reference according to that
123 // operand number. Non-matching operands are assumed to be in
124 // order.
125 unsigned OpIdx;
126 if (auto SubOp = CGI.Operands.findSubOperandAlias(Name: VarName)) {
127 OpIdx = CGI.Operands[SubOp->first].MIOperandNo + SubOp->second;
128 } else if (auto MayBeOpIdx = CGI.Operands.findOperandNamed(Name: VarName)) {
129 // Get the machine operand number for the indicated operand.
130 OpIdx = CGI.Operands[*MayBeOpIdx].MIOperandNo;
131 } else {
132 PrintError(Rec: R, Msg: Twine("No operand named ") + VarName + " in record " +
133 R->getName());
134 return false;
135 }
136
137 if (CGI.Operands.isFlatOperandNotEmitted(FlatOpNo: OpIdx)) {
138 PrintError(Rec: R,
139 Msg: "Operand " + VarName + " used but also marked as not emitted!");
140 return false;
141 }
142
143 std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(Op: OpIdx);
144 StringRef EncoderMethodName =
145 CGI.Operands[SO.first].EncoderMethodNames[SO.second];
146
147 if (UseAPInt)
148 Case += " op.clearAllBits();\n";
149
150 Case += " // op: " + VarName + "\n";
151
152 // If the source operand has a custom encoder, use it.
153 if (!EncoderMethodName.empty()) {
154 raw_string_ostream CaseOS(Case);
155 CaseOS << indent(6);
156 if (UseAPInt) {
157 CaseOS << EncoderMethodName << "(MI, " + utostr(X: OpIdx) << ", op";
158 } else {
159 CaseOS << "op = " << EncoderMethodName << "(MI, " << utostr(X: OpIdx);
160 }
161 CaseOS << ", Fixups, STI);\n";
162 } else {
163 if (UseAPInt) {
164 Case +=
165 " getMachineOpValue(MI, MI.getOperand(" + utostr(X: OpIdx) + ")";
166 Case += ", op, Fixups, STI";
167 } else {
168 Case += " op = getMachineOpValue(MI, MI.getOperand(" +
169 utostr(X: OpIdx) + ")";
170 Case += ", Fixups, STI";
171 }
172 Case += ");\n";
173 }
174
175 // Precalculate the number of lits this variable contributes to in the
176 // operand. If there is a single lit (consecutive range of bits) we can use a
177 // destructive sequence on APInt that reduces memory allocations.
178 int NumOperandLits = 0;
179 for (int TmpBit = Bit; TmpBit >= 0;) {
180 int VarBit = getVariableBit(VarName, BI, Bit: TmpBit);
181
182 // If this bit isn't from a variable, skip it.
183 if (VarBit == -1) {
184 --TmpBit;
185 continue;
186 }
187
188 // Figure out the consecutive range of bits covered by this operand, in
189 // order to generate better encoding code.
190 int BeginVarBit = VarBit;
191 int N = 1;
192 for (--TmpBit; TmpBit >= 0;) {
193 VarBit = getVariableBit(VarName, BI, Bit: TmpBit);
194 if (VarBit == -1 || VarBit != (BeginVarBit - N))
195 break;
196 ++N;
197 --TmpBit;
198 }
199 ++NumOperandLits;
200 }
201
202 unsigned BitOffset = -1;
203 for (; Bit >= 0;) {
204 int VarBit = getVariableBit(VarName, BI, Bit);
205
206 // If this bit isn't from a variable, skip it.
207 if (VarBit == -1) {
208 --Bit;
209 continue;
210 }
211
212 // Figure out the consecutive range of bits covered by this operand, in
213 // order to generate better encoding code.
214 int BeginInstBit = Bit;
215 int BeginVarBit = VarBit;
216 int N = 1;
217 for (--Bit; Bit >= 0;) {
218 VarBit = getVariableBit(VarName, BI, Bit);
219 if (VarBit == -1 || VarBit != (BeginVarBit - N))
220 break;
221 ++N;
222 --Bit;
223 }
224
225 std::string MaskStr;
226 int OpShift;
227
228 unsigned LoBit = BeginVarBit - N + 1;
229 unsigned HiBit = LoBit + N;
230 unsigned LoInstBit = BeginInstBit - N + 1;
231 BitOffset = LoInstBit;
232 if (UseAPInt) {
233 std::string ExtractStr;
234 if (N >= 64) {
235 ExtractStr = "op.extractBits(" + itostr(X: HiBit - LoBit) + ", " +
236 itostr(X: LoBit) + ")";
237 Case += " Value.insertBits(" + ExtractStr + ", " +
238 itostr(X: LoInstBit) + ");\n";
239 } else {
240 ExtractStr = "op.extractBitsAsZExtValue(" + itostr(X: HiBit - LoBit) +
241 ", " + itostr(X: LoBit) + ")";
242 Case += " Value.insertBits(" + ExtractStr + ", " +
243 itostr(X: LoInstBit) + ", " + itostr(X: HiBit - LoBit) + ");\n";
244 }
245 } else {
246 uint64_t OpMask = ~(uint64_t)0 >> (64 - N);
247 OpShift = BeginVarBit - N + 1;
248 OpMask <<= OpShift;
249 MaskStr = "UINT64_C(" + utostr(X: OpMask) + ")";
250 OpShift = BeginInstBit - BeginVarBit;
251
252 if (NumOperandLits == 1) {
253 Case += " op &= " + MaskStr + ";\n";
254 if (OpShift > 0) {
255 Case += " op <<= " + itostr(X: OpShift) + ";\n";
256 } else if (OpShift < 0) {
257 Case += " op >>= " + itostr(X: -OpShift) + ";\n";
258 }
259 Case += " Value |= op;\n";
260 } else {
261 if (OpShift > 0) {
262 Case += " Value |= (op & " + MaskStr + ") << " +
263 itostr(X: OpShift) + ";\n";
264 } else if (OpShift < 0) {
265 Case += " Value |= (op & " + MaskStr + ") >> " +
266 itostr(X: -OpShift) + ";\n";
267 } else {
268 Case += " Value |= (op & " + MaskStr + ");\n";
269 }
270 }
271 }
272 }
273
274 if (BitOffset != (unsigned)-1) {
275 BitOffsetCase += " case " + utostr(X: OpIdx) + ":\n";
276 BitOffsetCase += " // op: " + VarName + "\n";
277 BitOffsetCase += " return " + utostr(X: BitOffset) + ";\n";
278 }
279
280 return true;
281}
282
283std::pair<std::string, std::string>
284CodeEmitterGen::getInstructionCases(const Record *R,
285 const CodeGenTarget &Target) {
286 std::string Case, BitOffsetCase;
287
288 auto Append = [&](const std::string &S) {
289 Case += S;
290 BitOffsetCase += S;
291 };
292
293 if (const RecordVal *RV = R->getValue(Name: "EncodingInfos")) {
294 if (const auto *DI = dyn_cast_or_null<DefInit>(Val: RV->getValue())) {
295 const CodeGenHwModes &HWM = Target.getHwModes();
296 EncodingInfoByHwMode EBM(DI->getDef(), HWM);
297
298 // Invoke the interface to obtain the HwMode ID controlling the
299 // EncodingInfo for the current subtarget. This interface will
300 // mask off irrelevant HwMode IDs.
301 Append(" unsigned HwMode = "
302 "STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);\n");
303 Case += " switch (HwMode) {\n";
304 Case += " default: llvm_unreachable(\"Unknown hardware mode!\"); "
305 "break;\n";
306 for (auto &[ModeId, Encoding] : EBM) {
307 if (ModeId == DefaultMode) {
308 Case +=
309 " case " + itostr(X: DefaultMode) + ": InstBitsByHw = InstBits";
310 } else {
311 Case += " case " + itostr(X: ModeId) +
312 ": InstBitsByHw = InstBits_" + HWM.getMode(Id: ModeId).Name.str();
313 }
314 Case += "; break;\n";
315 }
316 Case += " };\n";
317
318 // We need to remodify the 'Inst' value from the table we found above.
319 if (UseAPInt) {
320 int NumWords = APInt::getNumWords(BitWidth);
321 Case += " Inst = APInt(" + itostr(X: BitWidth);
322 Case += ", ArrayRef(InstBitsByHw + opcode * " + itostr(X: NumWords) +
323 ", " + itostr(X: NumWords);
324 Case += "));\n";
325 Case += " Value = Inst;\n";
326 } else {
327 Case += " Value = InstBitsByHw[opcode];\n";
328 }
329
330 Append(" switch (HwMode) {\n");
331 Append(" default: llvm_unreachable(\"Unhandled HwMode\");\n");
332 for (auto &[ModeId, Encoding] : EBM) {
333 Append(" case " + itostr(X: ModeId) + ": {\n");
334 addInstructionCasesForEncoding(R, EncodingDef: Encoding, Target, Case,
335 BitOffsetCase);
336 Append(" break;\n");
337 Append(" }\n");
338 }
339 Append(" }\n");
340 return {std::move(Case), std::move(BitOffsetCase)};
341 }
342 }
343 addInstructionCasesForEncoding(R, EncodingDef: R, Target, Case, BitOffsetCase);
344 return {std::move(Case), std::move(BitOffsetCase)};
345}
346
347void CodeEmitterGen::addInstructionCasesForEncoding(
348 const Record *R, const Record *EncodingDef, const CodeGenTarget &Target,
349 std::string &Case, std::string &BitOffsetCase) {
350 const BitsInit *BI = EncodingDef->getValueAsBitsInit(FieldName: "Inst");
351
352 // Loop over all of the fields in the instruction, determining which are the
353 // operands to the instruction.
354 bool Success = true;
355 size_t OrigBitOffsetCaseSize = BitOffsetCase.size();
356 BitOffsetCase += " switch (OpNum) {\n";
357 size_t BitOffsetCaseSizeBeforeLoop = BitOffsetCase.size();
358 for (const RecordVal &RV : EncodingDef->getValues()) {
359 // Ignore fixed fields in the record, we're looking for values like:
360 // bits<5> RST = { ?, ?, ?, ?, ? };
361 if (RV.isNonconcreteOK() || RV.getValue()->isComplete())
362 continue;
363
364 Success &= addCodeToMergeInOperand(R, BI, VarName: RV.getName().str(), Case,
365 BitOffsetCase, Target);
366 }
367 // Avoid empty switches.
368 if (BitOffsetCase.size() == BitOffsetCaseSizeBeforeLoop)
369 BitOffsetCase.resize(n: OrigBitOffsetCaseSize);
370 else
371 BitOffsetCase += " }\n";
372
373 if (!Success) {
374 // Dump the record, so we can see what's going on...
375 std::string E;
376 raw_string_ostream S(E);
377 S << "Dumping record for previous error:\n";
378 S << *R;
379 PrintNote(Msg: E);
380 }
381
382 StringRef PostEmitter = R->getValueAsString(FieldName: "PostEncoderMethod");
383 if (!PostEmitter.empty()) {
384 Case += " Value = ";
385 Case += PostEmitter;
386 Case += "(MI, Value";
387 Case += ", STI";
388 Case += ");\n";
389 }
390}
391
392static void emitInstBits(raw_ostream &OS, const APInt &Bits) {
393 for (unsigned I = 0; I < Bits.getNumWords(); ++I)
394 OS << ((I > 0) ? ", " : "") << "UINT64_C(" << utostr(X: Bits.getRawData()[I])
395 << ")";
396}
397
398void CodeEmitterGen::emitInstructionBaseValues(
399 raw_ostream &O, ArrayRef<const CodeGenInstruction *> NumberedInstructions,
400 const CodeGenTarget &Target, unsigned HwMode) {
401 const CodeGenHwModes &HWM = Target.getHwModes();
402 if (HwMode == DefaultMode)
403 O << " static const uint64_t InstBits[] = {\n";
404 else
405 O << " static const uint64_t InstBits_"
406 << HWM.getModeName(Id: HwMode, /*IncludeDefault=*/true) << "[] = {\n";
407
408 for (const CodeGenInstruction *CGI : NumberedInstructions) {
409 const Record *R = CGI->TheDef;
410
411 if (R->getValueAsString(FieldName: "Namespace") == "TargetOpcode" ||
412 R->getValueAsBit(FieldName: "isPseudo")) {
413 O << " ";
414 emitInstBits(OS&: O, Bits: APInt(BitWidth, 0));
415 O << ",\n";
416 continue;
417 }
418
419 const Record *EncodingDef = R;
420 if (const RecordVal *RV = R->getValue(Name: "EncodingInfos")) {
421 if (auto *DI = dyn_cast_or_null<DefInit>(Val: RV->getValue())) {
422 EncodingInfoByHwMode EBM(DI->getDef(), HWM);
423 if (EBM.hasMode(M: HwMode)) {
424 EncodingDef = EBM.get(Mode: HwMode);
425 } else {
426 // If the HwMode does not match, then Encoding '0'
427 // should be generated.
428 APInt Value(BitWidth, 0);
429 O << " ";
430 emitInstBits(OS&: O, Bits: Value);
431 O << "," << '\t' << "// " << R->getName() << "\n";
432 continue;
433 }
434 }
435 }
436 const BitsInit *BI = EncodingDef->getValueAsBitsInit(FieldName: "Inst");
437
438 // Start by filling in fixed values.
439 APInt Value(BitWidth, 0);
440 for (unsigned I = 0, E = BI->getNumBits(); I != E; ++I) {
441 if (const auto *B = dyn_cast<BitInit>(Val: BI->getBit(Bit: I)); B && B->getValue())
442 Value.setBit(I);
443 }
444 O << " ";
445 emitInstBits(OS&: O, Bits: Value);
446 O << "," << '\t' << "// " << R->getName() << "\n";
447 }
448 O << " UINT64_C(0)\n };\n";
449}
450
451void CodeEmitterGen::emitCaseMap(
452 raw_ostream &O,
453 const std::map<std::string, std::vector<std::string>> &CaseMap) {
454 for (const auto &[Case, InstList] : CaseMap) {
455 bool First = true;
456 for (const auto &Inst : InstList) {
457 if (!First)
458 O << "\n";
459 O << " case " << Inst << ":";
460 First = false;
461 }
462 O << " {\n";
463 O << Case;
464 O << " break;\n"
465 << " }\n";
466 }
467}
468
469void CodeEmitterGen::run(raw_ostream &O) {
470 emitSourceFileHeader(Desc: "Machine Code Emitter", OS&: O);
471
472 CodeGenTarget Target(Records);
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(R: Records, OS&: 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 const Record *R = CGI->TheDef;
489 if (R->getValueAsString(FieldName: "Namespace") == "TargetOpcode" ||
490 R->getValueAsBit(FieldName: "isPseudo"))
491 continue;
492
493 if (const RecordVal *RV = R->getValue(Name: "EncodingInfos")) {
494 if (const DefInit *DI = dyn_cast_or_null<DefInit>(Val: RV->getValue())) {
495 EncodingInfoByHwMode EBM(DI->getDef(), HWM);
496 for (const auto &[Key, Value] : EBM) {
497 const BitsInit *BI = Value->getValueAsBitsInit(FieldName: "Inst");
498 BitWidth = std::max(a: BitWidth, b: BI->getNumBits());
499 HwModes.insert(x: Key);
500 }
501 continue;
502 }
503 }
504 const BitsInit *BI = R->getValueAsBitsInit(FieldName: "Inst");
505 BitWidth = std::max(a: BitWidth, b: 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, HwMode: 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 (const Record *R : Records.getAllDerivedDefinitions(ClassName: "Instruction")) {
544 if (R->getValueAsString(FieldName: "Namespace") == "TargetOpcode" ||
545 R->getValueAsBit(FieldName: "isPseudo"))
546 continue;
547 std::string InstName =
548 (R->getValueAsString(FieldName: "Namespace") + "::" + R->getName()).str();
549 std::string Case, BitOffsetCase;
550 std::tie(args&: Case, args&: BitOffsetCase) = getInstructionCases(R, Target);
551
552 CaseMap[Case].push_back(x: InstName);
553 BitOffsetCaseMap[BitOffsetCase].push_back(x: 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, CaseMap: 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
612static TableGen::Emitter::OptClass<CodeEmitterGen>
613 X("gen-emitter", "Generate machine code emitter");
614