1//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===//
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// This tablegen backend is responsible for emitting a description of the target
10// instruction set for the code generator.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Basic/SequenceToOffsetTable.h"
15#include "Common/CodeGenDAGPatterns.h"
16#include "Common/CodeGenInstruction.h"
17#include "Common/CodeGenSchedule.h"
18#include "Common/CodeGenTarget.h"
19#include "Common/PredicateExpander.h"
20#include "Common/SubtargetFeatureInfo.h"
21#include "Common/Types.h"
22#include "TableGenBackends.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringExtras.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/raw_ostream.h"
29#include "llvm/TableGen/Error.h"
30#include "llvm/TableGen/Record.h"
31#include "llvm/TableGen/TableGenBackend.h"
32#include <cassert>
33#include <cstdint>
34#include <iterator>
35#include <map>
36#include <string>
37#include <utility>
38#include <vector>
39
40using namespace llvm;
41
42cl::OptionCategory InstrInfoEmitterCat("Options for -gen-instr-info");
43static cl::opt<bool> ExpandMIOperandInfo(
44 "instr-info-expand-mi-operand-info",
45 cl::desc("Expand operand's MIOperandInfo DAG into suboperands"),
46 cl::cat(InstrInfoEmitterCat), cl::init(Val: true));
47
48namespace {
49
50class InstrInfoEmitter {
51 RecordKeeper &Records;
52 CodeGenDAGPatterns CDP;
53 const CodeGenSchedModels &SchedModels;
54
55public:
56 InstrInfoEmitter(RecordKeeper &R)
57 : Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
58
59 // run - Output the instruction set description.
60 void run(raw_ostream &OS);
61
62private:
63 void emitEnums(raw_ostream &OS);
64
65 typedef std::vector<std::string> OperandInfoTy;
66 typedef std::vector<OperandInfoTy> OperandInfoListTy;
67 typedef std::map<OperandInfoTy, unsigned> OperandInfoMapTy;
68
69 /// The keys of this map are maps which have OpName enum values as their keys
70 /// and instruction operand indices as their values. The values of this map
71 /// are lists of instruction names.
72 typedef std::map<std::map<unsigned, unsigned>, std::vector<std::string>>
73 OpNameMapTy;
74 typedef std::map<std::string, unsigned>::iterator StrUintMapIter;
75
76 /// Generate member functions in the target-specific GenInstrInfo class.
77 ///
78 /// This method is used to custom expand TIIPredicate definitions.
79 /// See file llvm/Target/TargetInstPredicates.td for a description of what is
80 /// a TIIPredicate and how to use it.
81 void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName,
82 bool ExpandDefinition = true);
83
84 /// Expand TIIPredicate definitions to functions that accept a const MCInst
85 /// reference.
86 void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName);
87
88 /// Write verifyInstructionPredicates methods.
89 void emitFeatureVerifier(raw_ostream &OS, const CodeGenTarget &Target);
90 void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
91 Record *InstrInfo,
92 std::map<std::vector<Record *>, unsigned> &EL,
93 const OperandInfoMapTy &OperandInfo, raw_ostream &OS);
94 void emitOperandTypeMappings(
95 raw_ostream &OS, const CodeGenTarget &Target,
96 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
97 void
98 initOperandMapData(ArrayRef<const CodeGenInstruction *> NumberedInstructions,
99 StringRef Namespace,
100 std::map<std::string, unsigned> &Operands,
101 OpNameMapTy &OperandMap);
102 void emitOperandNameMappings(
103 raw_ostream &OS, const CodeGenTarget &Target,
104 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
105
106 void emitLogicalOperandSizeMappings(
107 raw_ostream &OS, StringRef Namespace,
108 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
109 void emitLogicalOperandTypeMappings(
110 raw_ostream &OS, StringRef Namespace,
111 ArrayRef<const CodeGenInstruction *> NumberedInstructions);
112
113 // Operand information.
114 unsigned CollectOperandInfo(OperandInfoListTy &OperandInfoList,
115 OperandInfoMapTy &OperandInfoMap);
116 void EmitOperandInfo(raw_ostream &OS, OperandInfoListTy &OperandInfoList);
117 OperandInfoTy GetOperandInfo(const CodeGenInstruction &Inst);
118};
119
120} // end anonymous namespace
121
122//===----------------------------------------------------------------------===//
123// Operand Info Emission.
124//===----------------------------------------------------------------------===//
125
126InstrInfoEmitter::OperandInfoTy
127InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
128 OperandInfoTy Result;
129
130 for (auto &Op : Inst.Operands) {
131 // Handle aggregate operands and normal operands the same way by expanding
132 // either case into a list of operands for this op.
133 std::vector<CGIOperandList::OperandInfo> OperandList;
134
135 // This might be a multiple operand thing. Targets like X86 have
136 // registers in their multi-operand operands. It may also be an anonymous
137 // operand, which has a single operand, but no declared class for the
138 // operand.
139 DagInit *MIOI = Op.MIOperandInfo;
140
141 if (!MIOI || MIOI->getNumArgs() == 0) {
142 // Single, anonymous, operand.
143 OperandList.push_back(x: Op);
144 } else {
145 for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) {
146 OperandList.push_back(x: Op);
147
148 auto *OpR = cast<DefInit>(Val: MIOI->getArg(Num: j))->getDef();
149 OperandList.back().Rec = OpR;
150 }
151 }
152
153 for (unsigned j = 0, e = OperandList.size(); j != e; ++j) {
154 Record *OpR = OperandList[j].Rec;
155 std::string Res;
156
157 if (OpR->isSubClassOf(Name: "RegisterOperand"))
158 OpR = OpR->getValueAsDef(FieldName: "RegClass");
159 if (OpR->isSubClassOf(Name: "RegisterClass"))
160 Res += getQualifiedName(R: OpR) + "RegClassID, ";
161 else if (OpR->isSubClassOf(Name: "PointerLikeRegClass"))
162 Res += utostr(X: OpR->getValueAsInt(FieldName: "RegClassKind")) + ", ";
163 else
164 // -1 means the operand does not have a fixed register class.
165 Res += "-1, ";
166
167 // Fill in applicable flags.
168 Res += "0";
169
170 // Ptr value whose register class is resolved via callback.
171 if (OpR->isSubClassOf(Name: "PointerLikeRegClass"))
172 Res += "|(1<<MCOI::LookupPtrRegClass)";
173
174 // Predicate operands. Check to see if the original unexpanded operand
175 // was of type PredicateOp.
176 if (Op.Rec->isSubClassOf(Name: "PredicateOp"))
177 Res += "|(1<<MCOI::Predicate)";
178
179 // Optional def operands. Check to see if the original unexpanded operand
180 // was of type OptionalDefOperand.
181 if (Op.Rec->isSubClassOf(Name: "OptionalDefOperand"))
182 Res += "|(1<<MCOI::OptionalDef)";
183
184 // Branch target operands. Check to see if the original unexpanded
185 // operand was of type BranchTargetOperand.
186 if (Op.Rec->isSubClassOf(Name: "BranchTargetOperand"))
187 Res += "|(1<<MCOI::BranchTarget)";
188
189 // Fill in operand type.
190 Res += ", ";
191 assert(!Op.OperandType.empty() && "Invalid operand type.");
192 Res += Op.OperandType;
193
194 // Fill in constraint info.
195 Res += ", ";
196
197 const CGIOperandList::ConstraintInfo &Constraint = Op.Constraints[j];
198 if (Constraint.isNone())
199 Res += "0";
200 else if (Constraint.isEarlyClobber())
201 Res += "MCOI_EARLY_CLOBBER";
202 else {
203 assert(Constraint.isTied());
204 Res += "MCOI_TIED_TO(" + utostr(X: Constraint.getTiedOperand()) + ")";
205 }
206
207 Result.push_back(x: Res);
208 }
209 }
210
211 return Result;
212}
213
214unsigned
215InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList,
216 OperandInfoMapTy &OperandInfoMap) {
217 const CodeGenTarget &Target = CDP.getTargetInfo();
218 unsigned Offset = 0;
219 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
220 OperandInfoTy OperandInfo = GetOperandInfo(Inst: *Inst);
221 if (OperandInfoMap.insert(x: {OperandInfo, Offset}).second) {
222 OperandInfoList.push_back(x: OperandInfo);
223 Offset += OperandInfo.size();
224 }
225 }
226 return Offset;
227}
228
229void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
230 OperandInfoListTy &OperandInfoList) {
231 unsigned Offset = 0;
232 for (auto &OperandInfo : OperandInfoList) {
233 OS << " /* " << Offset << " */";
234 for (auto &Info : OperandInfo)
235 OS << " { " << Info << " },";
236 OS << '\n';
237 Offset += OperandInfo.size();
238 }
239}
240
241/// Initialize data structures for generating operand name mappings.
242///
243/// \param Operands [out] A map used to generate the OpName enum with operand
244/// names as its keys and operand enum values as its values.
245/// \param OperandMap [out] A map for representing the operand name mappings for
246/// each instructions. This is used to generate the OperandMap table as
247/// well as the getNamedOperandIdx() function.
248void InstrInfoEmitter::initOperandMapData(
249 ArrayRef<const CodeGenInstruction *> NumberedInstructions,
250 StringRef Namespace, std::map<std::string, unsigned> &Operands,
251 OpNameMapTy &OperandMap) {
252 unsigned NumOperands = 0;
253 for (const CodeGenInstruction *Inst : NumberedInstructions) {
254 if (!Inst->TheDef->getValueAsBit(FieldName: "UseNamedOperandTable"))
255 continue;
256 std::map<unsigned, unsigned> OpList;
257 for (const auto &Info : Inst->Operands) {
258 StrUintMapIter I = Operands.find(x: Info.Name);
259
260 if (I == Operands.end()) {
261 I = Operands.insert(position: Operands.begin(), x: std::pair<std::string, unsigned>(
262 Info.Name, NumOperands++));
263 }
264 OpList[I->second] = Info.MIOperandNo;
265 }
266 OperandMap[OpList].push_back(x: Namespace.str() +
267 "::" + Inst->TheDef->getName().str());
268 }
269}
270
271/// Generate a table and function for looking up the indices of operands by
272/// name.
273///
274/// This code generates:
275/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
276/// for each operand name.
277/// - A 2-dimensional table called OperandMap for mapping OpName enum values to
278/// operand indices.
279/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
280/// for looking up the operand index for an instruction, given a value from
281/// OpName enum
282void InstrInfoEmitter::emitOperandNameMappings(
283 raw_ostream &OS, const CodeGenTarget &Target,
284 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
285 StringRef Namespace = Target.getInstNamespace();
286 std::string OpNameNS = "OpName";
287 // Map of operand names to their enumeration value. This will be used to
288 // generate the OpName enum.
289 std::map<std::string, unsigned> Operands;
290 OpNameMapTy OperandMap;
291
292 initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap);
293
294 OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
295 OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
296 OS << "namespace llvm {\n";
297 OS << "namespace " << Namespace << " {\n";
298 OS << "namespace " << OpNameNS << " {\n";
299 OS << "enum {\n";
300 for (const auto &Op : Operands)
301 OS << " " << Op.first << " = " << Op.second << ",\n";
302
303 OS << " OPERAND_LAST";
304 OS << "\n};\n";
305 OS << "} // end namespace OpName\n";
306 OS << "} // end namespace " << Namespace << "\n";
307 OS << "} // end namespace llvm\n";
308 OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
309
310 OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
311 OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
312 OS << "namespace llvm {\n";
313 OS << "namespace " << Namespace << " {\n";
314 OS << "LLVM_READONLY\n";
315 OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n";
316 if (!Operands.empty()) {
317 OS << " static const int16_t OperandMap [][" << Operands.size()
318 << "] = {\n";
319 for (const auto &Entry : OperandMap) {
320 const std::map<unsigned, unsigned> &OpList = Entry.first;
321 OS << "{";
322
323 // Emit a row of the OperandMap table
324 for (unsigned i = 0, e = Operands.size(); i != e; ++i)
325 OS << (OpList.count(x: i) == 0 ? -1 : (int)OpList.find(x: i)->second) << ", ";
326
327 OS << "},\n";
328 }
329 OS << "};\n";
330
331 OS << " switch(Opcode) {\n";
332 unsigned TableIndex = 0;
333 for (const auto &Entry : OperandMap) {
334 for (const std::string &Name : Entry.second)
335 OS << " case " << Name << ":\n";
336
337 OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n";
338 }
339 OS << " default: return -1;\n";
340 OS << " }\n";
341 } else {
342 // There are no operands, so no need to emit anything
343 OS << " return -1;\n";
344 }
345 OS << "}\n";
346 OS << "} // end namespace " << Namespace << "\n";
347 OS << "} // end namespace llvm\n";
348 OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
349}
350
351/// Generate an enum for all the operand types for this target, under the
352/// llvm::TargetNamespace::OpTypes namespace.
353/// Operand types are all definitions derived of the Operand Target.td class.
354void InstrInfoEmitter::emitOperandTypeMappings(
355 raw_ostream &OS, const CodeGenTarget &Target,
356 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
357
358 StringRef Namespace = Target.getInstNamespace();
359 std::vector<Record *> Operands = Records.getAllDerivedDefinitions(ClassName: "Operand");
360 std::vector<Record *> RegisterOperands =
361 Records.getAllDerivedDefinitions(ClassName: "RegisterOperand");
362 std::vector<Record *> RegisterClasses =
363 Records.getAllDerivedDefinitions(ClassName: "RegisterClass");
364
365 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
366 OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
367 OS << "namespace llvm {\n";
368 OS << "namespace " << Namespace << " {\n";
369 OS << "namespace OpTypes {\n";
370 OS << "enum OperandType {\n";
371
372 unsigned EnumVal = 0;
373 for (const std::vector<Record *> *RecordsToAdd :
374 {&Operands, &RegisterOperands, &RegisterClasses}) {
375 for (const Record *Op : *RecordsToAdd) {
376 if (!Op->isAnonymous())
377 OS << " " << Op->getName() << " = " << EnumVal << ",\n";
378 ++EnumVal;
379 }
380 }
381
382 OS << " OPERAND_TYPE_LIST_END"
383 << "\n};\n";
384 OS << "} // end namespace OpTypes\n";
385 OS << "} // end namespace " << Namespace << "\n";
386 OS << "} // end namespace llvm\n";
387 OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
388
389 OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
390 OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
391 OS << "namespace llvm {\n";
392 OS << "namespace " << Namespace << " {\n";
393 OS << "LLVM_READONLY\n";
394 OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
395 auto getInstrName = [&](int I) -> StringRef {
396 return NumberedInstructions[I]->TheDef->getName();
397 };
398 // TODO: Factor out duplicate operand lists to compress the tables.
399 if (!NumberedInstructions.empty()) {
400 std::vector<int> OperandOffsets;
401 std::vector<Record *> OperandRecords;
402 int CurrentOffset = 0;
403 for (const CodeGenInstruction *Inst : NumberedInstructions) {
404 OperandOffsets.push_back(x: CurrentOffset);
405 for (const auto &Op : Inst->Operands) {
406 const DagInit *MIOI = Op.MIOperandInfo;
407 if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
408 // Single, anonymous, operand.
409 OperandRecords.push_back(x: Op.Rec);
410 ++CurrentOffset;
411 } else {
412 for (Init *Arg : MIOI->getArgs()) {
413 OperandRecords.push_back(x: cast<DefInit>(Val: Arg)->getDef());
414 ++CurrentOffset;
415 }
416 }
417 }
418 }
419
420 // Emit the table of offsets (indexes) into the operand type table.
421 // Size the unsigned integer offset to save space.
422 assert(OperandRecords.size() <= UINT32_MAX &&
423 "Too many operands for offset table");
424 OS << " static const " << getMinimalTypeForRange(Range: OperandRecords.size());
425 OS << " Offsets[] = {\n";
426 for (int I = 0, E = OperandOffsets.size(); I != E; ++I) {
427 OS << " /* " << getInstrName(I) << " */\n";
428 OS << " " << OperandOffsets[I] << ",\n";
429 }
430 OS << " };\n";
431
432 // Add an entry for the end so that we don't need to special case it below.
433 OperandOffsets.push_back(x: OperandRecords.size());
434
435 // Emit the actual operand types in a flat table.
436 // Size the signed integer operand type to save space.
437 assert(EnumVal <= INT16_MAX &&
438 "Too many operand types for operand types table");
439 OS << "\n using namespace OpTypes;\n";
440 OS << " static";
441 OS << ((EnumVal <= INT8_MAX) ? " const int8_t" : " const int16_t");
442 OS << " OpcodeOperandTypes[] = {\n ";
443 for (int I = 0, E = OperandRecords.size(), CurOffset = 0; I != E; ++I) {
444 // We print each Opcode's operands in its own row.
445 if (I == OperandOffsets[CurOffset]) {
446 OS << "\n /* " << getInstrName(CurOffset) << " */\n ";
447 while (OperandOffsets[++CurOffset] == I)
448 OS << "/* " << getInstrName(CurOffset) << " */\n ";
449 }
450 Record *OpR = OperandRecords[I];
451 if ((OpR->isSubClassOf(Name: "Operand") ||
452 OpR->isSubClassOf(Name: "RegisterOperand") ||
453 OpR->isSubClassOf(Name: "RegisterClass")) &&
454 !OpR->isAnonymous())
455 OS << OpR->getName();
456 else
457 OS << -1;
458 OS << ", ";
459 }
460 OS << "\n };\n";
461
462 OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
463 } else {
464 OS << " llvm_unreachable(\"No instructions defined\");\n";
465 }
466 OS << "}\n";
467 OS << "} // end namespace " << Namespace << "\n";
468 OS << "} // end namespace llvm\n";
469 OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
470
471 OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
472 OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
473 OS << "namespace llvm {\n";
474 OS << "namespace " << Namespace << " {\n";
475 OS << "LLVM_READONLY\n";
476 OS << "static int getMemOperandSize(int OpType) {\n";
477 OS << " switch (OpType) {\n";
478 std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
479 for (const Record *Op : Operands) {
480 if (!Op->isSubClassOf(Name: "X86MemOperand"))
481 continue;
482 if (int Size = Op->getValueAsInt(FieldName: "Size"))
483 SizeToOperandName[Size].push_back(Elt: Op->getName());
484 }
485 OS << " default: return 0;\n";
486 for (const auto &KV : SizeToOperandName) {
487 for (const StringRef &OperandName : KV.second)
488 OS << " case OpTypes::" << OperandName << ":\n";
489 OS << " return " << KV.first << ";\n\n";
490 }
491 OS << " }\n}\n";
492 OS << "} // end namespace " << Namespace << "\n";
493 OS << "} // end namespace llvm\n";
494 OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n";
495}
496
497void InstrInfoEmitter::emitLogicalOperandSizeMappings(
498 raw_ostream &OS, StringRef Namespace,
499 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
500 std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
501
502 std::map<unsigned, std::vector<std::string>> InstMap;
503
504 size_t LogicalOpListSize = 0U;
505 std::vector<unsigned> LogicalOpList;
506 for (const auto *Inst : NumberedInstructions) {
507 if (!Inst->TheDef->getValueAsBit(FieldName: "UseLogicalOperandMappings"))
508 continue;
509
510 LogicalOpList.clear();
511 llvm::transform(Range: Inst->Operands, d_first: std::back_inserter(x&: LogicalOpList),
512 F: [](const CGIOperandList::OperandInfo &Op) -> unsigned {
513 auto *MIOI = Op.MIOperandInfo;
514 if (!MIOI || MIOI->getNumArgs() == 0)
515 return 1;
516 return MIOI->getNumArgs();
517 });
518 LogicalOpListSize = std::max(a: LogicalOpList.size(), b: LogicalOpListSize);
519
520 auto I =
521 LogicalOpSizeMap.insert(x: {LogicalOpList, LogicalOpSizeMap.size()}).first;
522 InstMap[I->second].push_back(
523 x: (Namespace + "::" + Inst->TheDef->getName()).str());
524 }
525
526 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
527 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
528 OS << "namespace llvm {\n";
529 OS << "namespace " << Namespace << " {\n";
530 OS << "LLVM_READONLY static unsigned\n";
531 OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
532 if (!InstMap.empty()) {
533 std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
534 LogicalOpSizeMap.size());
535 for (auto &P : LogicalOpSizeMap) {
536 LogicalOpSizeList[P.second] = &P.first;
537 }
538 OS << " static const unsigned SizeMap[][" << LogicalOpListSize
539 << "] = {\n";
540 for (auto &R : LogicalOpSizeList) {
541 const auto &Row = *R;
542 OS << " {";
543 int i;
544 for (i = 0; i < static_cast<int>(Row.size()); ++i) {
545 OS << Row[i] << ", ";
546 }
547 for (; i < static_cast<int>(LogicalOpListSize); ++i) {
548 OS << "0, ";
549 }
550 OS << "}, ";
551 OS << "\n";
552 }
553 OS << " };\n";
554
555 OS << " switch (Opcode) {\n";
556 OS << " default: return LogicalOpIdx;\n";
557 for (auto &P : InstMap) {
558 auto OpMapIdx = P.first;
559 const auto &Insts = P.second;
560 for (const auto &Inst : Insts) {
561 OS << " case " << Inst << ":\n";
562 }
563 OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
564 }
565 OS << " }\n";
566 } else {
567 OS << " return LogicalOpIdx;\n";
568 }
569 OS << "}\n";
570
571 OS << "LLVM_READONLY static inline unsigned\n";
572 OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
573 OS << " auto S = 0U;\n";
574 OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
575 OS << " S += getLogicalOperandSize(Opcode, i);\n";
576 OS << " return S;\n";
577 OS << "}\n";
578
579 OS << "} // end namespace " << Namespace << "\n";
580 OS << "} // end namespace llvm\n";
581 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
582}
583
584void InstrInfoEmitter::emitLogicalOperandTypeMappings(
585 raw_ostream &OS, StringRef Namespace,
586 ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
587 std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap;
588
589 std::map<unsigned, std::vector<std::string>> InstMap;
590
591 size_t OpTypeListSize = 0U;
592 std::vector<std::string> LogicalOpTypeList;
593 for (const auto *Inst : NumberedInstructions) {
594 if (!Inst->TheDef->getValueAsBit(FieldName: "UseLogicalOperandMappings"))
595 continue;
596
597 LogicalOpTypeList.clear();
598 for (const auto &Op : Inst->Operands) {
599 auto *OpR = Op.Rec;
600 if ((OpR->isSubClassOf(Name: "Operand") ||
601 OpR->isSubClassOf(Name: "RegisterOperand") ||
602 OpR->isSubClassOf(Name: "RegisterClass")) &&
603 !OpR->isAnonymous()) {
604 LogicalOpTypeList.push_back(
605 x: (Namespace + "::OpTypes::" + Op.Rec->getName()).str());
606 } else {
607 LogicalOpTypeList.push_back(x: "-1");
608 }
609 }
610 OpTypeListSize = std::max(a: LogicalOpTypeList.size(), b: OpTypeListSize);
611
612 auto I =
613 LogicalOpTypeMap.insert(x: {LogicalOpTypeList, LogicalOpTypeMap.size()})
614 .first;
615 InstMap[I->second].push_back(
616 x: (Namespace + "::" + Inst->TheDef->getName()).str());
617 }
618
619 OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
620 OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
621 OS << "namespace llvm {\n";
622 OS << "namespace " << Namespace << " {\n";
623 OS << "LLVM_READONLY static int\n";
624 OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
625 if (!InstMap.empty()) {
626 std::vector<const std::vector<std::string> *> LogicalOpTypeList(
627 LogicalOpTypeMap.size());
628 for (auto &P : LogicalOpTypeMap) {
629 LogicalOpTypeList[P.second] = &P.first;
630 }
631 OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n";
632 for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) {
633 const auto &Row = *LogicalOpTypeList[r];
634 OS << " {";
635 int i, s = Row.size();
636 for (i = 0; i < s; ++i) {
637 if (i > 0)
638 OS << ", ";
639 OS << Row[i];
640 }
641 for (; i < static_cast<int>(OpTypeListSize); ++i) {
642 if (i > 0)
643 OS << ", ";
644 OS << "-1";
645 }
646 OS << "}";
647 if (r != rs - 1)
648 OS << ",";
649 OS << "\n";
650 }
651 OS << " };\n";
652
653 OS << " switch (Opcode) {\n";
654 OS << " default: return -1;\n";
655 for (auto &P : InstMap) {
656 auto OpMapIdx = P.first;
657 const auto &Insts = P.second;
658 for (const auto &Inst : Insts) {
659 OS << " case " << Inst << ":\n";
660 }
661 OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
662 }
663 OS << " }\n";
664 } else {
665 OS << " return -1;\n";
666 }
667 OS << "}\n";
668 OS << "} // end namespace " << Namespace << "\n";
669 OS << "} // end namespace llvm\n";
670 OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n";
671}
672
673void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
674 StringRef TargetName) {
675 RecVec TIIPredicates = Records.getAllDerivedDefinitions(ClassName: "TIIPredicate");
676
677 OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
678 OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
679
680 OS << "namespace llvm {\n";
681 OS << "class MCInst;\n";
682 OS << "class FeatureBitset;\n\n";
683
684 OS << "namespace " << TargetName << "_MC {\n\n";
685
686 for (const Record *Rec : TIIPredicates) {
687 OS << "bool " << Rec->getValueAsString(FieldName: "FunctionName")
688 << "(const MCInst &MI);\n";
689 }
690
691 OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
692 "&Features);\n";
693
694 OS << "\n} // end namespace " << TargetName << "_MC\n";
695 OS << "} // end namespace llvm\n\n";
696
697 OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
698
699 OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
700 OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
701
702 OS << "namespace llvm {\n";
703 OS << "namespace " << TargetName << "_MC {\n\n";
704
705 PredicateExpander PE(TargetName);
706 PE.setExpandForMC(true);
707
708 for (const Record *Rec : TIIPredicates) {
709 OS << "bool " << Rec->getValueAsString(FieldName: "FunctionName");
710 OS << "(const MCInst &MI) {\n";
711
712 OS.indent(NumSpaces: PE.getIndentLevel() * 2);
713 PE.expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Body"));
714 OS << "\n}\n\n";
715 }
716
717 OS << "} // end namespace " << TargetName << "_MC\n";
718 OS << "} // end namespace llvm\n\n";
719
720 OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
721}
722
723static std::string
724getNameForFeatureBitset(const std::vector<Record *> &FeatureBitset) {
725 std::string Name = "CEFBS";
726 for (const auto &Feature : FeatureBitset)
727 Name += ("_" + Feature->getName()).str();
728 return Name;
729}
730
731void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
732 const CodeGenTarget &Target) {
733 const auto &All = SubtargetFeatureInfo::getAll(Records);
734 std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
735 SubtargetFeatures.insert(first: All.begin(), last: All.end());
736
737 OS << "#if (defined(ENABLE_INSTR_PREDICATE_VERIFIER) && !defined(NDEBUG)) "
738 << "||\\\n"
739 << " defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
740 << "#define GET_COMPUTE_FEATURES\n"
741 << "#endif\n";
742 OS << "#ifdef GET_COMPUTE_FEATURES\n"
743 << "#undef GET_COMPUTE_FEATURES\n"
744 << "namespace llvm {\n"
745 << "namespace " << Target.getName() << "_MC {\n\n";
746
747 // Emit the subtarget feature enumeration.
748 SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
749 OS);
750 // Emit the available features compute function.
751 OS << "inline ";
752 SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
753 TargetName: Target.getName(), ClassName: "", FuncName: "computeAvailableFeatures", SubtargetFeatures, OS);
754
755 std::vector<std::vector<Record *>> FeatureBitsets;
756 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
757 FeatureBitsets.emplace_back();
758 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs(FieldName: "Predicates")) {
759 const auto &I = SubtargetFeatures.find(x: Predicate);
760 if (I != SubtargetFeatures.end())
761 FeatureBitsets.back().push_back(x: I->second.TheDef);
762 }
763 }
764
765 llvm::sort(C&: FeatureBitsets, Comp: [&](const std::vector<Record *> &A,
766 const std::vector<Record *> &B) {
767 if (A.size() < B.size())
768 return true;
769 if (A.size() > B.size())
770 return false;
771 for (auto Pair : zip(t: A, u: B)) {
772 if (std::get<0>(t&: Pair)->getName() < std::get<1>(t&: Pair)->getName())
773 return true;
774 if (std::get<0>(t&: Pair)->getName() > std::get<1>(t&: Pair)->getName())
775 return false;
776 }
777 return false;
778 });
779 FeatureBitsets.erase(
780 first: std::unique(first: FeatureBitsets.begin(), last: FeatureBitsets.end()),
781 last: FeatureBitsets.end());
782 OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
783 << " enum : " << getMinimalTypeForRange(Range: FeatureBitsets.size()) << " {\n"
784 << " CEFBS_None,\n";
785 for (const auto &FeatureBitset : FeatureBitsets) {
786 if (FeatureBitset.empty())
787 continue;
788 OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
789 }
790 OS << " };\n\n"
791 << " static constexpr FeatureBitset FeatureBitsets[] = {\n"
792 << " {}, // CEFBS_None\n";
793 for (const auto &FeatureBitset : FeatureBitsets) {
794 if (FeatureBitset.empty())
795 continue;
796 OS << " {";
797 for (const auto &Feature : FeatureBitset) {
798 const auto &I = SubtargetFeatures.find(x: Feature);
799 assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
800 OS << I->second.getEnumBitName() << ", ";
801 }
802 OS << "},\n";
803 }
804 OS << " };\n"
805 << " static constexpr " << getMinimalTypeForRange(Range: FeatureBitsets.size())
806 << " RequiredFeaturesRefs[] = {\n";
807 unsigned InstIdx = 0;
808 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) {
809 OS << " CEFBS";
810 unsigned NumPredicates = 0;
811 for (Record *Predicate : Inst->TheDef->getValueAsListOfDefs(FieldName: "Predicates")) {
812 const auto &I = SubtargetFeatures.find(x: Predicate);
813 if (I != SubtargetFeatures.end()) {
814 OS << '_' << I->second.TheDef->getName();
815 NumPredicates++;
816 }
817 }
818 if (!NumPredicates)
819 OS << "_None";
820 OS << ", // " << Inst->TheDef->getName() << " = " << InstIdx << "\n";
821 InstIdx++;
822 }
823 OS << " };\n\n"
824 << " assert(Opcode < " << InstIdx << ");\n"
825 << " return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
826 << "}\n\n";
827
828 OS << "} // end namespace " << Target.getName() << "_MC\n"
829 << "} // end namespace llvm\n"
830 << "#endif // GET_COMPUTE_FEATURES\n\n";
831
832 OS << "#ifdef GET_AVAILABLE_OPCODE_CHECKER\n"
833 << "#undef GET_AVAILABLE_OPCODE_CHECKER\n"
834 << "namespace llvm {\n"
835 << "namespace " << Target.getName() << "_MC {\n";
836 OS << "bool isOpcodeAvailable("
837 << "unsigned Opcode, const FeatureBitset &Features) {\n"
838 << " FeatureBitset AvailableFeatures = "
839 << "computeAvailableFeatures(Features);\n"
840 << " FeatureBitset RequiredFeatures = "
841 << "computeRequiredFeatures(Opcode);\n"
842 << " FeatureBitset MissingFeatures =\n"
843 << " (AvailableFeatures & RequiredFeatures) ^\n"
844 << " RequiredFeatures;\n"
845 << " return !MissingFeatures.any();\n"
846 << "}\n";
847 OS << "} // end namespace " << Target.getName() << "_MC\n"
848 << "} // end namespace llvm\n"
849 << "#endif // GET_AVAILABLE_OPCODE_CHECKER\n\n";
850
851 OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
852 << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
853 << "#include <sstream>\n\n";
854
855 OS << "namespace llvm {\n";
856 OS << "namespace " << Target.getName() << "_MC {\n\n";
857
858 // Emit the name table for error messages.
859 OS << "#ifndef NDEBUG\n";
860 SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
861 OS << "#endif // NDEBUG\n\n";
862
863 // Emit the predicate verifier.
864 OS << "void verifyInstructionPredicates(\n"
865 << " unsigned Opcode, const FeatureBitset &Features) {\n"
866 << "#ifndef NDEBUG\n";
867 OS << " FeatureBitset AvailableFeatures = "
868 "computeAvailableFeatures(Features);\n";
869 OS << " FeatureBitset RequiredFeatures = "
870 << "computeRequiredFeatures(Opcode);\n";
871 OS << " FeatureBitset MissingFeatures =\n"
872 << " (AvailableFeatures & RequiredFeatures) ^\n"
873 << " RequiredFeatures;\n"
874 << " if (MissingFeatures.any()) {\n"
875 << " std::ostringstream Msg;\n"
876 << " Msg << \"Attempting to emit \" << &" << Target.getName()
877 << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
878 << " << \" instruction but the \";\n"
879 << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
880 << " if (MissingFeatures.test(i))\n"
881 << " Msg << SubtargetFeatureNames[i] << \" \";\n"
882 << " Msg << \"predicate(s) are not met\";\n"
883 << " report_fatal_error(Msg.str().c_str());\n"
884 << " }\n"
885 << "#endif // NDEBUG\n";
886 OS << "}\n";
887 OS << "} // end namespace " << Target.getName() << "_MC\n";
888 OS << "} // end namespace llvm\n";
889 OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
890}
891
892void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
893 StringRef TargetName,
894 bool ExpandDefinition) {
895 RecVec TIIPredicates = Records.getAllDerivedDefinitions(ClassName: "TIIPredicate");
896 if (TIIPredicates.empty())
897 return;
898
899 PredicateExpander PE(TargetName);
900 PE.setExpandForMC(false);
901
902 for (const Record *Rec : TIIPredicates) {
903 OS << (ExpandDefinition ? "" : "static ") << "bool ";
904 if (ExpandDefinition)
905 OS << TargetName << "InstrInfo::";
906 OS << Rec->getValueAsString(FieldName: "FunctionName");
907 OS << "(const MachineInstr &MI)";
908 if (!ExpandDefinition) {
909 OS << ";\n";
910 continue;
911 }
912
913 OS << " {\n";
914 OS.indent(NumSpaces: PE.getIndentLevel() * 2);
915 PE.expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Body"));
916 OS << "\n}\n\n";
917 }
918}
919
920//===----------------------------------------------------------------------===//
921// Main Output.
922//===----------------------------------------------------------------------===//
923
924// run - Emit the main instruction description records for the target...
925void InstrInfoEmitter::run(raw_ostream &OS) {
926 emitSourceFileHeader(Desc: "Target Instruction Enum Values and Descriptors", OS);
927 emitEnums(OS);
928
929 CodeGenTarget &Target = CDP.getTargetInfo();
930 const std::string &TargetName = std::string(Target.getName());
931 Record *InstrInfo = Target.getInstructionSet();
932
933 // Collect all of the operand info records.
934 Records.startTimer(Name: "Collect operand info");
935 OperandInfoListTy OperandInfoList;
936 OperandInfoMapTy OperandInfoMap;
937 unsigned OperandInfoSize =
938 CollectOperandInfo(OperandInfoList, OperandInfoMap);
939
940 // Collect all of the instruction's implicit uses and defs.
941 Records.startTimer(Name: "Collect uses/defs");
942 std::map<std::vector<Record *>, unsigned> EmittedLists;
943 std::vector<std::vector<Record *>> ImplicitLists;
944 unsigned ImplicitListSize = 0;
945 for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) {
946 std::vector<Record *> ImplicitOps = II->ImplicitUses;
947 llvm::append_range(C&: ImplicitOps, R: II->ImplicitDefs);
948 if (EmittedLists.insert(x: {ImplicitOps, ImplicitListSize}).second) {
949 ImplicitLists.push_back(x: ImplicitOps);
950 ImplicitListSize += ImplicitOps.size();
951 }
952 }
953
954 ArrayRef<const CodeGenInstruction *> NumberedInstructions =
955 Target.getInstructionsByEnumValue();
956 OS << "#if defined(GET_INSTRINFO_MC_DESC) || "
957 "defined(GET_INSTRINFO_CTOR_DTOR)\n";
958 OS << "namespace llvm {\n\n";
959
960 OS << "struct " << TargetName << "InstrTable {\n";
961 OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n";
962 OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), "
963 "\"Unwanted padding between Insts and OperandInfo\");\n";
964 OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n";
965 OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), "
966 "\"Unwanted padding between OperandInfo and ImplicitOps\");\n";
967 OS << " MCPhysReg ImplicitOps[" << std::max(a: ImplicitListSize, b: 1U) << "];\n";
968 OS << "};\n\n";
969
970 OS << "} // end namespace llvm\n";
971 OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
972 "defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
973
974 OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
975 OS << "#undef GET_INSTRINFO_MC_DESC\n";
976 OS << "namespace llvm {\n\n";
977
978 // Emit all of the MCInstrDesc records in reverse ENUM ordering.
979 Records.startTimer(Name: "Emit InstrDesc records");
980 OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
981 OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
982 << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
983
984 OS << "extern const " << TargetName << "InstrTable " << TargetName
985 << "Descs = {\n {\n";
986 SequenceToOffsetTable<std::string> InstrNames;
987 unsigned Num = NumberedInstructions.size();
988 for (const CodeGenInstruction *Inst : reverse(C&: NumberedInstructions)) {
989 // Keep a list of the instruction names.
990 InstrNames.add(Seq: std::string(Inst->TheDef->getName()));
991 // Emit the record into the table.
992 emitRecord(Inst: *Inst, Num: --Num, InstrInfo, EL&: EmittedLists, OperandInfo: OperandInfoMap, OS);
993 }
994
995 OS << " }, {\n";
996
997 // Emit all of the operand info records.
998 Records.startTimer(Name: "Emit operand info");
999 EmitOperandInfo(OS, OperandInfoList);
1000
1001 OS << " }, {\n";
1002
1003 // Emit all of the instruction's implicit uses and defs.
1004 Records.startTimer(Name: "Emit uses/defs");
1005 for (auto &List : ImplicitLists) {
1006 OS << " /* " << EmittedLists[List] << " */";
1007 for (auto &Reg : List)
1008 OS << ' ' << getQualifiedName(R: Reg) << ',';
1009 OS << '\n';
1010 }
1011
1012 OS << " }\n};\n\n";
1013
1014 // Emit the array of instruction names.
1015 Records.startTimer(Name: "Emit instruction names");
1016 InstrNames.layout();
1017 InstrNames.emitStringLiteralDef(OS, Decl: Twine("extern const char ") + TargetName +
1018 "InstrNameData[]");
1019
1020 OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
1021 Num = 0;
1022 for (const CodeGenInstruction *Inst : NumberedInstructions) {
1023 // Newline every eight entries.
1024 if (Num % 8 == 0)
1025 OS << "\n ";
1026 OS << InstrNames.get(Seq: std::string(Inst->TheDef->getName())) << "U, ";
1027 ++Num;
1028 }
1029 OS << "\n};\n\n";
1030
1031 bool HasDeprecationFeatures =
1032 llvm::any_of(Range&: NumberedInstructions, P: [](const CodeGenInstruction *Inst) {
1033 return !Inst->HasComplexDeprecationPredicate &&
1034 !Inst->DeprecatedReason.empty();
1035 });
1036 if (HasDeprecationFeatures) {
1037 OS << "extern const uint8_t " << TargetName
1038 << "InstrDeprecationFeatures[] = {";
1039 Num = 0;
1040 for (const CodeGenInstruction *Inst : NumberedInstructions) {
1041 if (Num % 8 == 0)
1042 OS << "\n ";
1043 if (!Inst->HasComplexDeprecationPredicate &&
1044 !Inst->DeprecatedReason.empty())
1045 OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
1046 << ", ";
1047 else
1048 OS << "uint8_t(-1), ";
1049 ++Num;
1050 }
1051 OS << "\n};\n\n";
1052 }
1053
1054 bool HasComplexDeprecationInfos =
1055 llvm::any_of(Range&: NumberedInstructions, P: [](const CodeGenInstruction *Inst) {
1056 return Inst->HasComplexDeprecationPredicate;
1057 });
1058 if (HasComplexDeprecationInfos) {
1059 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
1060 << "InstrComplexDeprecationInfos[] = {";
1061 Num = 0;
1062 for (const CodeGenInstruction *Inst : NumberedInstructions) {
1063 if (Num % 8 == 0)
1064 OS << "\n ";
1065 if (Inst->HasComplexDeprecationPredicate)
1066 // Emit a function pointer to the complex predicate method.
1067 OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
1068 else
1069 OS << "nullptr, ";
1070 ++Num;
1071 }
1072 OS << "\n};\n\n";
1073 }
1074
1075 // MCInstrInfo initialization routine.
1076 Records.startTimer(Name: "Emit initialization routine");
1077 OS << "static inline void Init" << TargetName
1078 << "MCInstrInfo(MCInstrInfo *II) {\n";
1079 OS << " II->InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
1080 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
1081 if (HasDeprecationFeatures)
1082 OS << TargetName << "InstrDeprecationFeatures, ";
1083 else
1084 OS << "nullptr, ";
1085 if (HasComplexDeprecationInfos)
1086 OS << TargetName << "InstrComplexDeprecationInfos, ";
1087 else
1088 OS << "nullptr, ";
1089 OS << NumberedInstructions.size() << ");\n}\n\n";
1090
1091 OS << "} // end namespace llvm\n";
1092
1093 OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
1094
1095 // Create a TargetInstrInfo subclass to hide the MC layer initialization.
1096 OS << "#ifdef GET_INSTRINFO_HEADER\n";
1097 OS << "#undef GET_INSTRINFO_HEADER\n";
1098
1099 std::string ClassName = TargetName + "GenInstrInfo";
1100 OS << "namespace llvm {\n";
1101 OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
1102 << " explicit " << ClassName
1103 << "(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, "
1104 "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
1105 << " ~" << ClassName << "() override = default;\n";
1106
1107 OS << "\n};\n} // end namespace llvm\n";
1108
1109 OS << "#endif // GET_INSTRINFO_HEADER\n\n";
1110
1111 OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
1112 OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
1113 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
1114 OS << "\n";
1115 OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
1116
1117 OS << "#ifdef GET_INSTRINFO_HELPERS\n";
1118 OS << "#undef GET_INSTRINFO_HELPERS\n\n";
1119 emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
1120 OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
1121
1122 OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
1123 OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
1124
1125 OS << "namespace llvm {\n";
1126 OS << "extern const " << TargetName << "InstrTable " << TargetName
1127 << "Descs;\n";
1128 OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
1129 OS << "extern const char " << TargetName << "InstrNameData[];\n";
1130 if (HasDeprecationFeatures)
1131 OS << "extern const uint8_t " << TargetName
1132 << "InstrDeprecationFeatures[];\n";
1133 if (HasComplexDeprecationInfos)
1134 OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
1135 << "InstrComplexDeprecationInfos[];\n";
1136 OS << ClassName << "::" << ClassName
1137 << "(unsigned CFSetupOpcode, unsigned CFDestroyOpcode, unsigned "
1138 "CatchRetOpcode, unsigned ReturnOpcode)\n"
1139 << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
1140 "ReturnOpcode) {\n"
1141 << " InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
1142 << "InstrNameIndices, " << TargetName << "InstrNameData, ";
1143 if (HasDeprecationFeatures)
1144 OS << TargetName << "InstrDeprecationFeatures, ";
1145 else
1146 OS << "nullptr, ";
1147 if (HasComplexDeprecationInfos)
1148 OS << TargetName << "InstrComplexDeprecationInfos, ";
1149 else
1150 OS << "nullptr, ";
1151 OS << NumberedInstructions.size() << ");\n}\n";
1152 OS << "} // end namespace llvm\n";
1153
1154 OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
1155
1156 Records.startTimer(Name: "Emit operand name mappings");
1157 emitOperandNameMappings(OS, Target, NumberedInstructions);
1158
1159 Records.startTimer(Name: "Emit operand type mappings");
1160 emitOperandTypeMappings(OS, Target, NumberedInstructions);
1161
1162 Records.startTimer(Name: "Emit logical operand size mappings");
1163 emitLogicalOperandSizeMappings(OS, Namespace: TargetName, NumberedInstructions);
1164
1165 Records.startTimer(Name: "Emit logical operand type mappings");
1166 emitLogicalOperandTypeMappings(OS, Namespace: TargetName, NumberedInstructions);
1167
1168 Records.startTimer(Name: "Emit helper methods");
1169 emitMCIIHelperMethods(OS, TargetName);
1170
1171 Records.startTimer(Name: "Emit verifier methods");
1172 emitFeatureVerifier(OS, Target);
1173}
1174
1175void InstrInfoEmitter::emitRecord(
1176 const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo,
1177 std::map<std::vector<Record *>, unsigned> &EmittedLists,
1178 const OperandInfoMapTy &OperandInfoMap, raw_ostream &OS) {
1179 int MinOperands = 0;
1180 if (!Inst.Operands.empty())
1181 // Each logical operand can be multiple MI operands.
1182 MinOperands =
1183 Inst.Operands.back().MIOperandNo + Inst.Operands.back().MINumOperands;
1184 // Even the logical output operand may be multiple MI operands.
1185 int DefOperands = 0;
1186 if (Inst.Operands.NumDefs) {
1187 auto &Opnd = Inst.Operands[Inst.Operands.NumDefs - 1];
1188 DefOperands = Opnd.MIOperandNo + Opnd.MINumOperands;
1189 }
1190
1191 OS << " { ";
1192 OS << Num << ",\t" << MinOperands << ",\t" << DefOperands << ",\t"
1193 << Inst.TheDef->getValueAsInt(FieldName: "Size") << ",\t"
1194 << SchedModels.getSchedClassIdx(Inst) << ",\t";
1195
1196 CodeGenTarget &Target = CDP.getTargetInfo();
1197
1198 // Emit the implicit use/def list...
1199 OS << Inst.ImplicitUses.size() << ",\t" << Inst.ImplicitDefs.size() << ",\t";
1200 std::vector<Record *> ImplicitOps = Inst.ImplicitUses;
1201 llvm::append_range(C&: ImplicitOps, R: Inst.ImplicitDefs);
1202 OS << Target.getName() << "ImpOpBase + " << EmittedLists[ImplicitOps]
1203 << ",\t";
1204
1205 // Emit the operand info offset.
1206 OperandInfoTy OperandInfo = GetOperandInfo(Inst);
1207 OS << OperandInfoMap.find(x: OperandInfo)->second << ",\t0";
1208
1209 // Emit all of the target independent flags...
1210 if (Inst.isPreISelOpcode)
1211 OS << "|(1ULL<<MCID::PreISelOpcode)";
1212 if (Inst.isPseudo)
1213 OS << "|(1ULL<<MCID::Pseudo)";
1214 if (Inst.isMeta)
1215 OS << "|(1ULL<<MCID::Meta)";
1216 if (Inst.isReturn)
1217 OS << "|(1ULL<<MCID::Return)";
1218 if (Inst.isEHScopeReturn)
1219 OS << "|(1ULL<<MCID::EHScopeReturn)";
1220 if (Inst.isBranch)
1221 OS << "|(1ULL<<MCID::Branch)";
1222 if (Inst.isIndirectBranch)
1223 OS << "|(1ULL<<MCID::IndirectBranch)";
1224 if (Inst.isCompare)
1225 OS << "|(1ULL<<MCID::Compare)";
1226 if (Inst.isMoveImm)
1227 OS << "|(1ULL<<MCID::MoveImm)";
1228 if (Inst.isMoveReg)
1229 OS << "|(1ULL<<MCID::MoveReg)";
1230 if (Inst.isBitcast)
1231 OS << "|(1ULL<<MCID::Bitcast)";
1232 if (Inst.isAdd)
1233 OS << "|(1ULL<<MCID::Add)";
1234 if (Inst.isTrap)
1235 OS << "|(1ULL<<MCID::Trap)";
1236 if (Inst.isSelect)
1237 OS << "|(1ULL<<MCID::Select)";
1238 if (Inst.isBarrier)
1239 OS << "|(1ULL<<MCID::Barrier)";
1240 if (Inst.hasDelaySlot)
1241 OS << "|(1ULL<<MCID::DelaySlot)";
1242 if (Inst.isCall)
1243 OS << "|(1ULL<<MCID::Call)";
1244 if (Inst.canFoldAsLoad)
1245 OS << "|(1ULL<<MCID::FoldableAsLoad)";
1246 if (Inst.mayLoad)
1247 OS << "|(1ULL<<MCID::MayLoad)";
1248 if (Inst.mayStore)
1249 OS << "|(1ULL<<MCID::MayStore)";
1250 if (Inst.mayRaiseFPException)
1251 OS << "|(1ULL<<MCID::MayRaiseFPException)";
1252 if (Inst.isPredicable)
1253 OS << "|(1ULL<<MCID::Predicable)";
1254 if (Inst.isConvertibleToThreeAddress)
1255 OS << "|(1ULL<<MCID::ConvertibleTo3Addr)";
1256 if (Inst.isCommutable)
1257 OS << "|(1ULL<<MCID::Commutable)";
1258 if (Inst.isTerminator)
1259 OS << "|(1ULL<<MCID::Terminator)";
1260 if (Inst.isReMaterializable)
1261 OS << "|(1ULL<<MCID::Rematerializable)";
1262 if (Inst.isNotDuplicable)
1263 OS << "|(1ULL<<MCID::NotDuplicable)";
1264 if (Inst.Operands.hasOptionalDef)
1265 OS << "|(1ULL<<MCID::HasOptionalDef)";
1266 if (Inst.usesCustomInserter)
1267 OS << "|(1ULL<<MCID::UsesCustomInserter)";
1268 if (Inst.hasPostISelHook)
1269 OS << "|(1ULL<<MCID::HasPostISelHook)";
1270 if (Inst.Operands.isVariadic)
1271 OS << "|(1ULL<<MCID::Variadic)";
1272 if (Inst.hasSideEffects)
1273 OS << "|(1ULL<<MCID::UnmodeledSideEffects)";
1274 if (Inst.isAsCheapAsAMove)
1275 OS << "|(1ULL<<MCID::CheapAsAMove)";
1276 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq)
1277 OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)";
1278 if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq)
1279 OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)";
1280 if (Inst.isRegSequence)
1281 OS << "|(1ULL<<MCID::RegSequence)";
1282 if (Inst.isExtractSubreg)
1283 OS << "|(1ULL<<MCID::ExtractSubreg)";
1284 if (Inst.isInsertSubreg)
1285 OS << "|(1ULL<<MCID::InsertSubreg)";
1286 if (Inst.isConvergent)
1287 OS << "|(1ULL<<MCID::Convergent)";
1288 if (Inst.variadicOpsAreDefs)
1289 OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
1290 if (Inst.isAuthenticated)
1291 OS << "|(1ULL<<MCID::Authenticated)";
1292
1293 // Emit all of the target-specific flags...
1294 BitsInit *TSF = Inst.TheDef->getValueAsBitsInit(FieldName: "TSFlags");
1295 if (!TSF)
1296 PrintFatalError(ErrorLoc: Inst.TheDef->getLoc(), Msg: "no TSFlags?");
1297 uint64_t Value = 0;
1298 for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
1299 if (const auto *Bit = dyn_cast<BitInit>(Val: TSF->getBit(Bit: i)))
1300 Value |= uint64_t(Bit->getValue()) << i;
1301 else
1302 PrintFatalError(ErrorLoc: Inst.TheDef->getLoc(),
1303 Msg: "Invalid TSFlags bit in " + Inst.TheDef->getName());
1304 }
1305 OS << ", 0x";
1306 OS.write_hex(N: Value);
1307 OS << "ULL";
1308
1309 OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
1310}
1311
1312// emitEnums - Print out enum values for all of the instructions.
1313void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
1314 OS << "#ifdef GET_INSTRINFO_ENUM\n";
1315 OS << "#undef GET_INSTRINFO_ENUM\n";
1316
1317 OS << "namespace llvm {\n\n";
1318
1319 const CodeGenTarget &Target = CDP.getTargetInfo();
1320
1321 // We must emit the PHI opcode first...
1322 StringRef Namespace = Target.getInstNamespace();
1323
1324 if (Namespace.empty())
1325 PrintFatalError(Msg: "No instructions defined!");
1326
1327 OS << "namespace " << Namespace << " {\n";
1328 OS << " enum {\n";
1329 unsigned Num = 0;
1330 for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue())
1331 OS << " " << Inst->TheDef->getName()
1332 << "\t= " << (Num = Target.getInstrIntValue(R: Inst->TheDef)) << ",\n";
1333 OS << " INSTRUCTION_LIST_END = " << Num + 1 << "\n";
1334 OS << " };\n\n";
1335 OS << "} // end namespace " << Namespace << "\n";
1336 OS << "} // end namespace llvm\n";
1337 OS << "#endif // GET_INSTRINFO_ENUM\n\n";
1338
1339 OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
1340 OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
1341 OS << "namespace llvm {\n\n";
1342 OS << "namespace " << Namespace << " {\n";
1343 OS << "namespace Sched {\n";
1344 OS << " enum {\n";
1345 Num = 0;
1346 for (const auto &Class : SchedModels.explicit_classes())
1347 OS << " " << Class.Name << "\t= " << Num++ << ",\n";
1348 OS << " SCHED_LIST_END = " << Num << "\n";
1349 OS << " };\n";
1350 OS << "} // end namespace Sched\n";
1351 OS << "} // end namespace " << Namespace << "\n";
1352 OS << "} // end namespace llvm\n";
1353
1354 OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
1355}
1356
1357static void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
1358 RK.startTimer(Name: "Analyze DAG patterns");
1359 InstrInfoEmitter(RK).run(OS);
1360 RK.startTimer(Name: "Emit map table");
1361 EmitMapTable(RK, OS);
1362}
1363
1364static TableGen::Emitter::Opt X("gen-instr-info", EmitInstrInfo,
1365 "Generate instruction descriptions");
1366

source code of llvm/utils/TableGen/InstrInfoEmitter.cpp