1296417Sdim//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. --*- C++ -*-===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This tablegen backend is responsible for emitting a description of the target 10193323Sed// instruction set for the code generator. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14239462Sdim#include "CodeGenDAGPatterns.h" 15314564Sdim#include "CodeGenInstruction.h" 16239462Sdim#include "CodeGenSchedule.h" 17193323Sed#include "CodeGenTarget.h" 18341825Sdim#include "PredicateExpander.h" 19249423Sdim#include "SequenceToOffsetTable.h" 20243830Sdim#include "TableGenBackends.h" 21314564Sdim#include "llvm/ADT/ArrayRef.h" 22239462Sdim#include "llvm/ADT/StringExtras.h" 23314564Sdim#include "llvm/Support/Casting.h" 24314564Sdim#include "llvm/Support/raw_ostream.h" 25243830Sdim#include "llvm/TableGen/Error.h" 26226633Sdim#include "llvm/TableGen/Record.h" 27239462Sdim#include "llvm/TableGen/TableGenBackend.h" 28314564Sdim#include <cassert> 29314564Sdim#include <cstdint> 30239462Sdim#include <map> 31314564Sdim#include <string> 32314564Sdim#include <utility> 33239462Sdim#include <vector> 34296417Sdim 35193323Sedusing namespace llvm; 36193323Sed 37239462Sdimnamespace { 38314564Sdim 39239462Sdimclass InstrInfoEmitter { 40239462Sdim RecordKeeper &Records; 41239462Sdim CodeGenDAGPatterns CDP; 42239462Sdim const CodeGenSchedModels &SchedModels; 43239462Sdim 44239462Sdimpublic: 45239462Sdim InstrInfoEmitter(RecordKeeper &R): 46239462Sdim Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {} 47239462Sdim 48239462Sdim // run - Output the instruction set description. 49239462Sdim void run(raw_ostream &OS); 50239462Sdim 51239462Sdimprivate: 52239462Sdim void emitEnums(raw_ostream &OS); 53239462Sdim 54239462Sdim typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; 55261991Sdim 56261991Sdim /// The keys of this map are maps which have OpName enum values as their keys 57261991Sdim /// and instruction operand indices as their values. The values of this map 58261991Sdim /// are lists of instruction names. 59261991Sdim typedef std::map<std::map<unsigned, unsigned>, 60314564Sdim std::vector<std::string>> OpNameMapTy; 61261991Sdim typedef std::map<std::string, unsigned>::iterator StrUintMapIter; 62341825Sdim 63341825Sdim /// Generate member functions in the target-specific GenInstrInfo class. 64341825Sdim /// 65341825Sdim /// This method is used to custom expand TIIPredicate definitions. 66341825Sdim /// See file llvm/Target/TargetInstPredicates.td for a description of what is 67341825Sdim /// a TIIPredicate and how to use it. 68344779Sdim void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName, 69344779Sdim bool ExpandDefinition = true); 70341825Sdim 71341825Sdim /// Expand TIIPredicate definitions to functions that accept a const MCInst 72341825Sdim /// reference. 73344779Sdim void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName); 74239462Sdim void emitRecord(const CodeGenInstruction &Inst, unsigned Num, 75239462Sdim Record *InstrInfo, 76239462Sdim std::map<std::vector<Record*>, unsigned> &EL, 77239462Sdim const OperandInfoMapTy &OpInfo, 78239462Sdim raw_ostream &OS); 79353358Sdim void emitOperandTypeMappings( 80353358Sdim raw_ostream &OS, const CodeGenTarget &Target, 81353358Sdim ArrayRef<const CodeGenInstruction *> NumberedInstructions); 82261991Sdim void initOperandMapData( 83309124Sdim ArrayRef<const CodeGenInstruction *> NumberedInstructions, 84321369Sdim StringRef Namespace, 85276479Sdim std::map<std::string, unsigned> &Operands, 86276479Sdim OpNameMapTy &OperandMap); 87261991Sdim void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target, 88309124Sdim ArrayRef<const CodeGenInstruction*> NumberedInstructions); 89239462Sdim 90239462Sdim // Operand information. 91239462Sdim void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); 92239462Sdim std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); 93239462Sdim}; 94314564Sdim 95296417Sdim} // end anonymous namespace 96239462Sdim 97193323Sedstatic void PrintDefList(const std::vector<Record*> &Uses, 98195340Sed unsigned Num, raw_ostream &OS) { 99296417Sdim OS << "static const MCPhysReg ImplicitList" << Num << "[] = { "; 100309124Sdim for (Record *U : Uses) 101309124Sdim OS << getQualifiedName(U) << ", "; 102193323Sed OS << "0 };\n"; 103193323Sed} 104193323Sed 105193323Sed//===----------------------------------------------------------------------===// 106193323Sed// Operand Info Emission. 107193323Sed//===----------------------------------------------------------------------===// 108193323Sed 109193323Sedstd::vector<std::string> 110193323SedInstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { 111193323Sed std::vector<std::string> Result; 112224145Sdim 113276479Sdim for (auto &Op : Inst.Operands) { 114193323Sed // Handle aggregate operands and normal operands the same way by expanding 115193323Sed // either case into a list of operands for this op. 116218893Sdim std::vector<CGIOperandList::OperandInfo> OperandList; 117193323Sed 118193323Sed // This might be a multiple operand thing. Targets like X86 have 119193323Sed // registers in their multi-operand operands. It may also be an anonymous 120193323Sed // operand, which has a single operand, but no declared class for the 121193323Sed // operand. 122276479Sdim DagInit *MIOI = Op.MIOperandInfo; 123224145Sdim 124193323Sed if (!MIOI || MIOI->getNumArgs() == 0) { 125193323Sed // Single, anonymous, operand. 126276479Sdim OperandList.push_back(Op); 127193323Sed } else { 128276479Sdim for (unsigned j = 0, e = Op.MINumOperands; j != e; ++j) { 129276479Sdim OperandList.push_back(Op); 130193323Sed 131314564Sdim auto *OpR = cast<DefInit>(MIOI->getArg(j))->getDef(); 132193323Sed OperandList.back().Rec = OpR; 133193323Sed } 134193323Sed } 135193323Sed 136193323Sed for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { 137193323Sed Record *OpR = OperandList[j].Rec; 138193323Sed std::string Res; 139224145Sdim 140224145Sdim if (OpR->isSubClassOf("RegisterOperand")) 141224145Sdim OpR = OpR->getValueAsDef("RegClass"); 142193323Sed if (OpR->isSubClassOf("RegisterClass")) 143193323Sed Res += getQualifiedName(OpR) + "RegClassID, "; 144198090Srdivacky else if (OpR->isSubClassOf("PointerLikeRegClass")) 145198090Srdivacky Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; 146193323Sed else 147210299Sed // -1 means the operand does not have a fixed register class. 148210299Sed Res += "-1, "; 149224145Sdim 150193323Sed // Fill in applicable flags. 151193323Sed Res += "0"; 152224145Sdim 153193323Sed // Ptr value whose register class is resolved via callback. 154198090Srdivacky if (OpR->isSubClassOf("PointerLikeRegClass")) 155224145Sdim Res += "|(1<<MCOI::LookupPtrRegClass)"; 156193323Sed 157193323Sed // Predicate operands. Check to see if the original unexpanded operand 158261991Sdim // was of type PredicateOp. 159276479Sdim if (Op.Rec->isSubClassOf("PredicateOp")) 160224145Sdim Res += "|(1<<MCOI::Predicate)"; 161224145Sdim 162193323Sed // Optional def operands. Check to see if the original unexpanded operand 163193323Sed // was of type OptionalDefOperand. 164276479Sdim if (Op.Rec->isSubClassOf("OptionalDefOperand")) 165224145Sdim Res += "|(1<<MCOI::OptionalDef)"; 166193323Sed 167360784Sdim // Branch target operands. Check to see if the original unexpanded 168360784Sdim // operand was of type BranchTargetOperand. 169360784Sdim if (Op.Rec->isSubClassOf("BranchTargetOperand")) 170360784Sdim Res += "|(1<<MCOI::BranchTarget)"; 171360784Sdim 172234353Sdim // Fill in operand type. 173280031Sdim Res += ", "; 174276479Sdim assert(!Op.OperandType.empty() && "Invalid operand type."); 175276479Sdim Res += Op.OperandType; 176234353Sdim 177193323Sed // Fill in constraint info. 178203954Srdivacky Res += ", "; 179224145Sdim 180218893Sdim const CGIOperandList::ConstraintInfo &Constraint = 181276479Sdim Op.Constraints[j]; 182203954Srdivacky if (Constraint.isNone()) 183203954Srdivacky Res += "0"; 184203954Srdivacky else if (Constraint.isEarlyClobber()) 185224145Sdim Res += "(1 << MCOI::EARLY_CLOBBER)"; 186203954Srdivacky else { 187203954Srdivacky assert(Constraint.isTied()); 188203954Srdivacky Res += "((" + utostr(Constraint.getTiedOperand()) + 189224145Sdim " << 16) | (1 << MCOI::TIED_TO))"; 190203954Srdivacky } 191224145Sdim 192193323Sed Result.push_back(Res); 193193323Sed } 194193323Sed } 195193323Sed 196193323Sed return Result; 197193323Sed} 198193323Sed 199224145Sdimvoid InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, 200193323Sed OperandInfoMapTy &OperandInfoIDs) { 201193323Sed // ID #0 is for no operand info. 202193323Sed unsigned OperandListNum = 0; 203193323Sed OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; 204224145Sdim 205193323Sed OS << "\n"; 206193323Sed const CodeGenTarget &Target = CDP.getTargetInfo(); 207309124Sdim for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) { 208276479Sdim std::vector<std::string> OperandInfo = GetOperandInfo(*Inst); 209193323Sed unsigned &N = OperandInfoIDs[OperandInfo]; 210193323Sed if (N != 0) continue; 211224145Sdim 212193323Sed N = ++OperandListNum; 213224145Sdim OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; 214276479Sdim for (const std::string &Info : OperandInfo) 215276479Sdim OS << "{ " << Info << " }, "; 216193323Sed OS << "};\n"; 217193323Sed } 218193323Sed} 219193323Sed 220261991Sdim/// Initialize data structures for generating operand name mappings. 221353358Sdim/// 222261991Sdim/// \param Operands [out] A map used to generate the OpName enum with operand 223261991Sdim/// names as its keys and operand enum values as its values. 224261991Sdim/// \param OperandMap [out] A map for representing the operand name mappings for 225261991Sdim/// each instructions. This is used to generate the OperandMap table as 226261991Sdim/// well as the getNamedOperandIdx() function. 227261991Sdimvoid InstrInfoEmitter::initOperandMapData( 228309124Sdim ArrayRef<const CodeGenInstruction *> NumberedInstructions, 229321369Sdim StringRef Namespace, 230261991Sdim std::map<std::string, unsigned> &Operands, 231261991Sdim OpNameMapTy &OperandMap) { 232261991Sdim unsigned NumOperands = 0; 233276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 234276479Sdim if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) 235261991Sdim continue; 236261991Sdim std::map<unsigned, unsigned> OpList; 237276479Sdim for (const auto &Info : Inst->Operands) { 238261991Sdim StrUintMapIter I = Operands.find(Info.Name); 239261991Sdim 240261991Sdim if (I == Operands.end()) { 241261991Sdim I = Operands.insert(Operands.begin(), 242261991Sdim std::pair<std::string, unsigned>(Info.Name, NumOperands++)); 243261991Sdim } 244261991Sdim OpList[I->second] = Info.MIOperandNo; 245261991Sdim } 246321369Sdim OperandMap[OpList].push_back(Namespace.str() + "::" + 247314564Sdim Inst->TheDef->getName().str()); 248261991Sdim } 249261991Sdim} 250261991Sdim 251261991Sdim/// Generate a table and function for looking up the indices of operands by 252261991Sdim/// name. 253261991Sdim/// 254261991Sdim/// This code generates: 255261991Sdim/// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry 256261991Sdim/// for each operand name. 257261991Sdim/// - A 2-dimensional table called OperandMap for mapping OpName enum values to 258261991Sdim/// operand indices. 259261991Sdim/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) 260261991Sdim/// for looking up the operand index for an instruction, given a value from 261261991Sdim/// OpName enum 262261991Sdimvoid InstrInfoEmitter::emitOperandNameMappings(raw_ostream &OS, 263261991Sdim const CodeGenTarget &Target, 264309124Sdim ArrayRef<const CodeGenInstruction*> NumberedInstructions) { 265321369Sdim StringRef Namespace = Target.getInstNamespace(); 266261991Sdim std::string OpNameNS = "OpName"; 267261991Sdim // Map of operand names to their enumeration value. This will be used to 268261991Sdim // generate the OpName enum. 269261991Sdim std::map<std::string, unsigned> Operands; 270261991Sdim OpNameMapTy OperandMap; 271261991Sdim 272261991Sdim initOperandMapData(NumberedInstructions, Namespace, Operands, OperandMap); 273261991Sdim 274261991Sdim OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n"; 275261991Sdim OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n"; 276288943Sdim OS << "namespace llvm {\n"; 277261991Sdim OS << "namespace " << Namespace << " {\n"; 278309124Sdim OS << "namespace " << OpNameNS << " {\n"; 279261991Sdim OS << "enum {\n"; 280276479Sdim for (const auto &Op : Operands) 281276479Sdim OS << " " << Op.first << " = " << Op.second << ",\n"; 282261991Sdim 283261991Sdim OS << "OPERAND_LAST"; 284261991Sdim OS << "\n};\n"; 285296417Sdim OS << "} // end namespace OpName\n"; 286296417Sdim OS << "} // end namespace " << Namespace << "\n"; 287296417Sdim OS << "} // end namespace llvm\n"; 288309124Sdim OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n"; 289261991Sdim 290261991Sdim OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n"; 291261991Sdim OS << "#undef GET_INSTRINFO_NAMED_OPS\n"; 292288943Sdim OS << "namespace llvm {\n"; 293261991Sdim OS << "namespace " << Namespace << " {\n"; 294280031Sdim OS << "LLVM_READONLY\n"; 295261991Sdim OS << "int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n"; 296261991Sdim if (!Operands.empty()) { 297261991Sdim OS << " static const int16_t OperandMap [][" << Operands.size() 298261991Sdim << "] = {\n"; 299276479Sdim for (const auto &Entry : OperandMap) { 300276479Sdim const std::map<unsigned, unsigned> &OpList = Entry.first; 301261991Sdim OS << "{"; 302261991Sdim 303261991Sdim // Emit a row of the OperandMap table 304276479Sdim for (unsigned i = 0, e = Operands.size(); i != e; ++i) 305276479Sdim OS << (OpList.count(i) == 0 ? -1 : (int)OpList.find(i)->second) << ", "; 306261991Sdim 307261991Sdim OS << "},\n"; 308261991Sdim } 309261991Sdim OS << "};\n"; 310261991Sdim 311261991Sdim OS << " switch(Opcode) {\n"; 312261991Sdim unsigned TableIndex = 0; 313276479Sdim for (const auto &Entry : OperandMap) { 314276479Sdim for (const std::string &Name : Entry.second) 315276479Sdim OS << " case " << Name << ":\n"; 316261991Sdim 317261991Sdim OS << " return OperandMap[" << TableIndex++ << "][NamedIdx];\n"; 318261991Sdim } 319261991Sdim OS << " default: return -1;\n"; 320261991Sdim OS << " }\n"; 321261991Sdim } else { 322261991Sdim // There are no operands, so no need to emit anything 323261991Sdim OS << " return -1;\n"; 324261991Sdim } 325261991Sdim OS << "}\n"; 326296417Sdim OS << "} // end namespace " << Namespace << "\n"; 327296417Sdim OS << "} // end namespace llvm\n"; 328309124Sdim OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n"; 329261991Sdim} 330261991Sdim 331261991Sdim/// Generate an enum for all the operand types for this target, under the 332261991Sdim/// llvm::TargetNamespace::OpTypes namespace. 333261991Sdim/// Operand types are all definitions derived of the Operand Target.td class. 334353358Sdimvoid InstrInfoEmitter::emitOperandTypeMappings( 335353358Sdim raw_ostream &OS, const CodeGenTarget &Target, 336353358Sdim ArrayRef<const CodeGenInstruction *> NumberedInstructions) { 337261991Sdim 338321369Sdim StringRef Namespace = Target.getInstNamespace(); 339261991Sdim std::vector<Record *> Operands = Records.getAllDerivedDefinitions("Operand"); 340360784Sdim std::vector<Record *> RegisterOperands = 341360784Sdim Records.getAllDerivedDefinitions("RegisterOperand"); 342360784Sdim std::vector<Record *> RegisterClasses = 343360784Sdim Records.getAllDerivedDefinitions("RegisterClass"); 344261991Sdim 345309124Sdim OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 346261991Sdim OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n"; 347288943Sdim OS << "namespace llvm {\n"; 348261991Sdim OS << "namespace " << Namespace << " {\n"; 349309124Sdim OS << "namespace OpTypes {\n"; 350261991Sdim OS << "enum OperandType {\n"; 351261991Sdim 352276479Sdim unsigned EnumVal = 0; 353360784Sdim for (const std::vector<Record *> *RecordsToAdd : 354360784Sdim {&Operands, &RegisterOperands, &RegisterClasses}) { 355360784Sdim for (const Record *Op : *RecordsToAdd) { 356360784Sdim if (!Op->isAnonymous()) 357360784Sdim OS << " " << Op->getName() << " = " << EnumVal << ",\n"; 358360784Sdim ++EnumVal; 359360784Sdim } 360261991Sdim } 361261991Sdim 362261991Sdim OS << " OPERAND_TYPE_LIST_END" << "\n};\n"; 363296417Sdim OS << "} // end namespace OpTypes\n"; 364296417Sdim OS << "} // end namespace " << Namespace << "\n"; 365296417Sdim OS << "} // end namespace llvm\n"; 366309124Sdim OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n"; 367353358Sdim 368353358Sdim OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n"; 369353358Sdim OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n"; 370353358Sdim OS << "namespace llvm {\n"; 371353358Sdim OS << "namespace " << Namespace << " {\n"; 372353358Sdim OS << "LLVM_READONLY\n"; 373360784Sdim OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n"; 374360784Sdim // TODO: Factor out instructions with same operands to compress the tables. 375353358Sdim if (!NumberedInstructions.empty()) { 376353358Sdim std::vector<int> OperandOffsets; 377353358Sdim std::vector<Record *> OperandRecords; 378353358Sdim int CurrentOffset = 0; 379353358Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 380353358Sdim OperandOffsets.push_back(CurrentOffset); 381353358Sdim for (const auto &Op : Inst->Operands) { 382353358Sdim const DagInit *MIOI = Op.MIOperandInfo; 383353358Sdim if (!MIOI || MIOI->getNumArgs() == 0) { 384353358Sdim // Single, anonymous, operand. 385353358Sdim OperandRecords.push_back(Op.Rec); 386353358Sdim ++CurrentOffset; 387353358Sdim } else { 388353358Sdim for (Init *Arg : make_range(MIOI->arg_begin(), MIOI->arg_end())) { 389353358Sdim OperandRecords.push_back(cast<DefInit>(Arg)->getDef()); 390353358Sdim ++CurrentOffset; 391353358Sdim } 392353358Sdim } 393353358Sdim } 394353358Sdim } 395353358Sdim 396353358Sdim // Emit the table of offsets for the opcode lookup. 397353358Sdim OS << " const int Offsets[] = {\n"; 398353358Sdim for (int I = 0, E = OperandOffsets.size(); I != E; ++I) 399353358Sdim OS << " " << OperandOffsets[I] << ",\n"; 400353358Sdim OS << " };\n"; 401353358Sdim 402353358Sdim // Add an entry for the end so that we don't need to special case it below. 403353358Sdim OperandOffsets.push_back(OperandRecords.size()); 404353358Sdim // Emit the actual operand types in a flat table. 405353358Sdim OS << " const int OpcodeOperandTypes[] = {\n "; 406353358Sdim for (int I = 0, E = OperandRecords.size(), CurOffset = 1; I != E; ++I) { 407353358Sdim // We print each Opcode's operands in its own row. 408353358Sdim if (I == OperandOffsets[CurOffset]) { 409353358Sdim OS << "\n "; 410353358Sdim // If there are empty rows, mark them with an empty comment. 411353358Sdim while (OperandOffsets[++CurOffset] == I) 412353358Sdim OS << "/**/\n "; 413353358Sdim } 414353358Sdim Record *OpR = OperandRecords[I]; 415360784Sdim if ((OpR->isSubClassOf("Operand") || 416360784Sdim OpR->isSubClassOf("RegisterOperand") || 417360784Sdim OpR->isSubClassOf("RegisterClass")) && 418360784Sdim !OpR->isAnonymous()) 419353358Sdim OS << "OpTypes::" << OpR->getName(); 420353358Sdim else 421353358Sdim OS << -1; 422353358Sdim OS << ", "; 423353358Sdim } 424353358Sdim OS << "\n };\n"; 425353358Sdim 426353358Sdim OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n"; 427353358Sdim } else { 428353358Sdim OS << " llvm_unreachable(\"No instructions defined\");\n"; 429353358Sdim } 430353358Sdim OS << "}\n"; 431353358Sdim OS << "} // end namespace " << Namespace << "\n"; 432353358Sdim OS << "} // end namespace llvm\n"; 433360784Sdim OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n"; 434261991Sdim} 435261991Sdim 436344779Sdimvoid InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS, 437344779Sdim StringRef TargetName) { 438341825Sdim RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 439341825Sdim if (TIIPredicates.empty()) 440341825Sdim return; 441341825Sdim 442344779Sdim OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n"; 443344779Sdim OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 444341825Sdim 445344779Sdim OS << "namespace llvm {\n"; 446344779Sdim OS << "class MCInst;\n\n"; 447341825Sdim 448344779Sdim OS << "namespace " << TargetName << "_MC {\n\n"; 449341825Sdim 450341825Sdim for (const Record *Rec : TIIPredicates) { 451344779Sdim OS << "bool " << Rec->getValueAsString("FunctionName") 452341825Sdim << "(const MCInst &MI);\n"; 453341825Sdim } 454341825Sdim 455360784Sdim OS << "\n} // end namespace " << TargetName << "_MC\n"; 456360784Sdim OS << "} // end namespace llvm\n\n"; 457341825Sdim 458344779Sdim OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n"; 459341825Sdim 460344779Sdim OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n"; 461344779Sdim OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n"; 462341825Sdim 463344779Sdim OS << "namespace llvm {\n"; 464344779Sdim OS << "namespace " << TargetName << "_MC {\n\n"; 465341825Sdim 466344779Sdim PredicateExpander PE(TargetName); 467341825Sdim PE.setExpandForMC(true); 468344779Sdim 469341825Sdim for (const Record *Rec : TIIPredicates) { 470344779Sdim OS << "bool " << Rec->getValueAsString("FunctionName"); 471344779Sdim OS << "(const MCInst &MI) {\n"; 472344779Sdim 473344779Sdim OS.indent(PE.getIndentLevel() * 2); 474344779Sdim PE.expandStatement(OS, Rec->getValueAsDef("Body")); 475344779Sdim OS << "\n}\n\n"; 476341825Sdim } 477341825Sdim 478360784Sdim OS << "} // end namespace " << TargetName << "_MC\n"; 479360784Sdim OS << "} // end namespace llvm\n\n"; 480341825Sdim 481344779Sdim OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; 482341825Sdim} 483341825Sdim 484344779Sdimvoid InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, 485344779Sdim StringRef TargetName, 486344779Sdim bool ExpandDefinition) { 487341825Sdim RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); 488341825Sdim if (TIIPredicates.empty()) 489341825Sdim return; 490341825Sdim 491344779Sdim PredicateExpander PE(TargetName); 492341825Sdim PE.setExpandForMC(false); 493341825Sdim 494341825Sdim for (const Record *Rec : TIIPredicates) { 495344779Sdim OS << (ExpandDefinition ? "" : "static ") << "bool "; 496344779Sdim if (ExpandDefinition) 497344779Sdim OS << TargetName << "InstrInfo::"; 498344779Sdim OS << Rec->getValueAsString("FunctionName"); 499344779Sdim OS << "(const MachineInstr &MI)"; 500344779Sdim if (!ExpandDefinition) { 501344779Sdim OS << ";\n"; 502344779Sdim continue; 503344779Sdim } 504344779Sdim 505344779Sdim OS << " {\n"; 506344779Sdim OS.indent(PE.getIndentLevel() * 2); 507344779Sdim PE.expandStatement(OS, Rec->getValueAsDef("Body")); 508344779Sdim OS << "\n}\n\n"; 509341825Sdim } 510341825Sdim} 511341825Sdim 512193323Sed//===----------------------------------------------------------------------===// 513193323Sed// Main Output. 514193323Sed//===----------------------------------------------------------------------===// 515193323Sed 516193323Sed// run - Emit the main instruction description records for the target... 517195340Sedvoid InstrInfoEmitter::run(raw_ostream &OS) { 518309124Sdim emitSourceFileHeader("Target Instruction Enum Values and Descriptors", OS); 519224145Sdim emitEnums(OS); 520224145Sdim 521309124Sdim OS << "#ifdef GET_INSTRINFO_MC_DESC\n"; 522224145Sdim OS << "#undef GET_INSTRINFO_MC_DESC\n"; 523224145Sdim 524193323Sed OS << "namespace llvm {\n\n"; 525193323Sed 526193323Sed CodeGenTarget &Target = CDP.getTargetInfo(); 527193323Sed const std::string &TargetName = Target.getName(); 528193323Sed Record *InstrInfo = Target.getInstructionSet(); 529193323Sed 530193323Sed // Keep track of all of the def lists we have emitted already. 531193323Sed std::map<std::vector<Record*>, unsigned> EmittedLists; 532193323Sed unsigned ListNumber = 0; 533224145Sdim 534193323Sed // Emit all of the instruction's implicit uses and defs. 535309124Sdim for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { 536276479Sdim Record *Inst = II->TheDef; 537193323Sed std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 538193323Sed if (!Uses.empty()) { 539193323Sed unsigned &IL = EmittedLists[Uses]; 540193323Sed if (!IL) PrintDefList(Uses, IL = ++ListNumber, OS); 541193323Sed } 542193323Sed std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 543193323Sed if (!Defs.empty()) { 544193323Sed unsigned &IL = EmittedLists[Defs]; 545193323Sed if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); 546193323Sed } 547193323Sed } 548193323Sed 549193323Sed OperandInfoMapTy OperandInfoIDs; 550224145Sdim 551193323Sed // Emit all of the operand info records. 552193323Sed EmitOperandInfo(OS, OperandInfoIDs); 553224145Sdim 554224145Sdim // Emit all of the MCInstrDesc records in their ENUM ordering. 555193323Sed // 556234353Sdim OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; 557309124Sdim ArrayRef<const CodeGenInstruction*> NumberedInstructions = 558205407Srdivacky Target.getInstructionsByEnumValue(); 559193323Sed 560234353Sdim SequenceToOffsetTable<std::string> InstrNames; 561276479Sdim unsigned Num = 0; 562276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 563276479Sdim // Keep a list of the instruction names. 564276479Sdim InstrNames.add(Inst->TheDef->getName()); 565276479Sdim // Emit the record into the table. 566276479Sdim emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS); 567234353Sdim } 568276479Sdim OS << "};\n\n"; 569234353Sdim 570276479Sdim // Emit the array of instruction names. 571234353Sdim InstrNames.layout(); 572234353Sdim OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; 573234353Sdim InstrNames.emit(OS, printChar); 574234353Sdim OS << "};\n\n"; 575234353Sdim 576234353Sdim OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; 577276479Sdim Num = 0; 578276479Sdim for (const CodeGenInstruction *Inst : NumberedInstructions) { 579276479Sdim // Newline every eight entries. 580276479Sdim if (Num % 8 == 0) 581234353Sdim OS << "\n "; 582276479Sdim OS << InstrNames.get(Inst->TheDef->getName()) << "U, "; 583276479Sdim ++Num; 584234353Sdim } 585234353Sdim 586234353Sdim OS << "\n};\n\n"; 587234353Sdim 588224145Sdim // MCInstrInfo initialization routine. 589224145Sdim OS << "static inline void Init" << TargetName 590224145Sdim << "MCInstrInfo(MCInstrInfo *II) {\n"; 591224145Sdim OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " 592234353Sdim << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, " 593224145Sdim << NumberedInstructions.size() << ");\n}\n\n"; 594224145Sdim 595360784Sdim OS << "} // end namespace llvm\n"; 596224145Sdim 597224145Sdim OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; 598224145Sdim 599224145Sdim // Create a TargetInstrInfo subclass to hide the MC layer initialization. 600309124Sdim OS << "#ifdef GET_INSTRINFO_HEADER\n"; 601224145Sdim OS << "#undef GET_INSTRINFO_HEADER\n"; 602224145Sdim 603224145Sdim std::string ClassName = TargetName + "GenInstrInfo"; 604224145Sdim OS << "namespace llvm {\n"; 605249423Sdim OS << "struct " << ClassName << " : public TargetInstrInfo {\n" 606288943Sdim << " explicit " << ClassName 607309124Sdim << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n" 608341825Sdim << " ~" << ClassName << "() override = default;\n"; 609224145Sdim 610341825Sdim 611360784Sdim OS << "\n};\n} // end namespace llvm\n"; 612341825Sdim 613224145Sdim OS << "#endif // GET_INSTRINFO_HEADER\n\n"; 614224145Sdim 615344779Sdim OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n"; 616344779Sdim OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n"; 617344779Sdim emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */false); 618344779Sdim OS << "\n"; 619344779Sdim OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n"; 620344779Sdim 621344779Sdim OS << "#ifdef GET_INSTRINFO_HELPERS\n"; 622344779Sdim OS << "#undef GET_INSTRINFO_HELPERS\n\n"; 623344779Sdim emitTIIHelperMethods(OS, TargetName, /* ExpandDefintion = */true); 624344779Sdim OS << "#endif // GET_INSTRINFO_HELPERS\n\n"; 625344779Sdim 626309124Sdim OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n"; 627261991Sdim OS << "#undef GET_INSTRINFO_CTOR_DTOR\n"; 628224145Sdim 629224145Sdim OS << "namespace llvm {\n"; 630234353Sdim OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; 631234353Sdim OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; 632234353Sdim OS << "extern const char " << TargetName << "InstrNameData[];\n"; 633288943Sdim OS << ClassName << "::" << ClassName 634309124Sdim << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int ReturnOpcode)\n" 635309124Sdim << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, ReturnOpcode) {\n" 636288943Sdim << " InitMCInstrInfo(" << TargetName << "Insts, " << TargetName 637288943Sdim << "InstrNameIndices, " << TargetName << "InstrNameData, " 638296417Sdim << NumberedInstructions.size() << ");\n}\n"; 639360784Sdim OS << "} // end namespace llvm\n"; 640224145Sdim 641261991Sdim OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; 642261991Sdim 643261991Sdim emitOperandNameMappings(OS, Target, NumberedInstructions); 644261991Sdim 645353358Sdim emitOperandTypeMappings(OS, Target, NumberedInstructions); 646341825Sdim 647344779Sdim emitMCIIHelperMethods(OS, TargetName); 648193323Sed} 649193323Sed 650193323Sedvoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 651193323Sed Record *InstrInfo, 652193323Sed std::map<std::vector<Record*>, unsigned> &EmittedLists, 653193323Sed const OperandInfoMapTy &OpInfo, 654195340Sed raw_ostream &OS) { 655193323Sed int MinOperands = 0; 656243830Sdim if (!Inst.Operands.empty()) 657193323Sed // Each logical operand can be multiple MI operands. 658218893Sdim MinOperands = Inst.Operands.back().MIOperandNo + 659218893Sdim Inst.Operands.back().MINumOperands; 660193323Sed 661193323Sed OS << " { "; 662193323Sed OS << Num << ",\t" << MinOperands << ",\t" 663224145Sdim << Inst.Operands.NumDefs << ",\t" 664288943Sdim << Inst.TheDef->getValueAsInt("Size") << ",\t" 665288943Sdim << SchedModels.getSchedClassIdx(Inst) << ",\t0"; 666193323Sed 667341825Sdim CodeGenTarget &Target = CDP.getTargetInfo(); 668341825Sdim 669288943Sdim // Emit all of the target independent flags... 670360784Sdim if (Inst.isPreISelOpcode) OS << "|(1ULL<<MCID::PreISelOpcode)"; 671288943Sdim if (Inst.isPseudo) OS << "|(1ULL<<MCID::Pseudo)"; 672288943Sdim if (Inst.isReturn) OS << "|(1ULL<<MCID::Return)"; 673344779Sdim if (Inst.isEHScopeReturn) OS << "|(1ULL<<MCID::EHScopeReturn)"; 674288943Sdim if (Inst.isBranch) OS << "|(1ULL<<MCID::Branch)"; 675288943Sdim if (Inst.isIndirectBranch) OS << "|(1ULL<<MCID::IndirectBranch)"; 676288943Sdim if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)"; 677288943Sdim if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)"; 678341825Sdim if (Inst.isMoveReg) OS << "|(1ULL<<MCID::MoveReg)"; 679288943Sdim if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)"; 680314564Sdim if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)"; 681341825Sdim if (Inst.isTrap) OS << "|(1ULL<<MCID::Trap)"; 682288943Sdim if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)"; 683288943Sdim if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)"; 684288943Sdim if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)"; 685288943Sdim if (Inst.isCall) OS << "|(1ULL<<MCID::Call)"; 686288943Sdim if (Inst.canFoldAsLoad) OS << "|(1ULL<<MCID::FoldableAsLoad)"; 687288943Sdim if (Inst.mayLoad) OS << "|(1ULL<<MCID::MayLoad)"; 688288943Sdim if (Inst.mayStore) OS << "|(1ULL<<MCID::MayStore)"; 689353358Sdim if (Inst.mayRaiseFPException) OS << "|(1ULL<<MCID::MayRaiseFPException)"; 690288943Sdim if (Inst.isPredicable) OS << "|(1ULL<<MCID::Predicable)"; 691288943Sdim if (Inst.isConvertibleToThreeAddress) OS << "|(1ULL<<MCID::ConvertibleTo3Addr)"; 692288943Sdim if (Inst.isCommutable) OS << "|(1ULL<<MCID::Commutable)"; 693288943Sdim if (Inst.isTerminator) OS << "|(1ULL<<MCID::Terminator)"; 694288943Sdim if (Inst.isReMaterializable) OS << "|(1ULL<<MCID::Rematerializable)"; 695288943Sdim if (Inst.isNotDuplicable) OS << "|(1ULL<<MCID::NotDuplicable)"; 696288943Sdim if (Inst.Operands.hasOptionalDef) OS << "|(1ULL<<MCID::HasOptionalDef)"; 697288943Sdim if (Inst.usesCustomInserter) OS << "|(1ULL<<MCID::UsesCustomInserter)"; 698288943Sdim if (Inst.hasPostISelHook) OS << "|(1ULL<<MCID::HasPostISelHook)"; 699288943Sdim if (Inst.Operands.isVariadic)OS << "|(1ULL<<MCID::Variadic)"; 700288943Sdim if (Inst.hasSideEffects) OS << "|(1ULL<<MCID::UnmodeledSideEffects)"; 701288943Sdim if (Inst.isAsCheapAsAMove) OS << "|(1ULL<<MCID::CheapAsAMove)"; 702341825Sdim if (!Target.getAllowRegisterRenaming() || Inst.hasExtraSrcRegAllocReq) 703341825Sdim OS << "|(1ULL<<MCID::ExtraSrcRegAllocReq)"; 704341825Sdim if (!Target.getAllowRegisterRenaming() || Inst.hasExtraDefRegAllocReq) 705341825Sdim OS << "|(1ULL<<MCID::ExtraDefRegAllocReq)"; 706288943Sdim if (Inst.isRegSequence) OS << "|(1ULL<<MCID::RegSequence)"; 707288943Sdim if (Inst.isExtractSubreg) OS << "|(1ULL<<MCID::ExtractSubreg)"; 708288943Sdim if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)"; 709288943Sdim if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)"; 710344779Sdim if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)"; 711360784Sdim if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)"; 712193323Sed 713193323Sed // Emit all of the target-specific flags... 714206274Srdivacky BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); 715243830Sdim if (!TSF) 716353358Sdim PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?"); 717206274Srdivacky uint64_t Value = 0; 718206274Srdivacky for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) { 719314564Sdim if (const auto *Bit = dyn_cast<BitInit>(TSF->getBit(i))) 720206274Srdivacky Value |= uint64_t(Bit->getValue()) << i; 721206274Srdivacky else 722353358Sdim PrintFatalError(Inst.TheDef->getLoc(), 723353358Sdim "Invalid TSFlags bit in " + Inst.TheDef->getName()); 724206274Srdivacky } 725206274Srdivacky OS << ", 0x"; 726206274Srdivacky OS.write_hex(Value); 727210299Sed OS << "ULL, "; 728193323Sed 729193323Sed // Emit the implicit uses and defs lists... 730193323Sed std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 731193323Sed if (UseList.empty()) 732276479Sdim OS << "nullptr, "; 733193323Sed else 734193323Sed OS << "ImplicitList" << EmittedLists[UseList] << ", "; 735193323Sed 736193323Sed std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 737193323Sed if (DefList.empty()) 738276479Sdim OS << "nullptr, "; 739193323Sed else 740193323Sed OS << "ImplicitList" << EmittedLists[DefList] << ", "; 741193323Sed 742193323Sed // Emit the operand info. 743193323Sed std::vector<std::string> OperandInfo = GetOperandInfo(Inst); 744193323Sed if (OperandInfo.empty()) 745276479Sdim OS << "nullptr"; 746193323Sed else 747193323Sed OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; 748206274Srdivacky 749261991Sdim if (Inst.HasComplexDeprecationPredicate) 750261991Sdim // Emit a function pointer to the complex predicate method. 751288943Sdim OS << ", -1 " 752261991Sdim << ",&get" << Inst.DeprecatedReason << "DeprecationInfo"; 753261991Sdim else if (!Inst.DeprecatedReason.empty()) 754261991Sdim // Emit the Subtarget feature. 755288943Sdim OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason 756288943Sdim << " ,nullptr"; 757261991Sdim else 758261991Sdim // Instruction isn't deprecated. 759288943Sdim OS << ", -1 ,nullptr"; 760261991Sdim 761193323Sed OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 762193323Sed} 763224145Sdim 764224145Sdim// emitEnums - Print out enum values for all of the instructions. 765224145Sdimvoid InstrInfoEmitter::emitEnums(raw_ostream &OS) { 766309124Sdim OS << "#ifdef GET_INSTRINFO_ENUM\n"; 767224145Sdim OS << "#undef GET_INSTRINFO_ENUM\n"; 768224145Sdim 769224145Sdim OS << "namespace llvm {\n\n"; 770224145Sdim 771224145Sdim CodeGenTarget Target(Records); 772224145Sdim 773224145Sdim // We must emit the PHI opcode first... 774321369Sdim StringRef Namespace = Target.getInstNamespace(); 775234353Sdim 776288943Sdim if (Namespace.empty()) 777288943Sdim PrintFatalError("No instructions defined!"); 778224145Sdim 779224145Sdim OS << "namespace " << Namespace << " {\n"; 780224145Sdim OS << " enum {\n"; 781276479Sdim unsigned Num = 0; 782309124Sdim for (const CodeGenInstruction *Inst : Target.getInstructionsByEnumValue()) 783276479Sdim OS << " " << Inst->TheDef->getName() << "\t= " << Num++ << ",\n"; 784309124Sdim OS << " INSTRUCTION_LIST_END = " << Num << "\n"; 785280031Sdim OS << " };\n\n"; 786360784Sdim OS << "} // end namespace " << Namespace << "\n"; 787360784Sdim OS << "} // end namespace llvm\n"; 788327952Sdim OS << "#endif // GET_INSTRINFO_ENUM\n\n"; 789327952Sdim 790327952Sdim OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n"; 791327952Sdim OS << "#undef GET_INSTRINFO_SCHED_ENUM\n"; 792327952Sdim OS << "namespace llvm {\n\n"; 793327952Sdim OS << "namespace " << Namespace << " {\n"; 794261991Sdim OS << "namespace Sched {\n"; 795261991Sdim OS << " enum {\n"; 796276479Sdim Num = 0; 797276479Sdim for (const auto &Class : SchedModels.explicit_classes()) 798276479Sdim OS << " " << Class.Name << "\t= " << Num++ << ",\n"; 799309124Sdim OS << " SCHED_LIST_END = " << Num << "\n"; 800280031Sdim OS << " };\n"; 801360784Sdim OS << "} // end namespace Sched\n"; 802360784Sdim OS << "} // end namespace " << Namespace << "\n"; 803360784Sdim OS << "} // end namespace llvm\n"; 804224145Sdim 805327952Sdim OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n"; 806224145Sdim} 807239462Sdim 808239462Sdimnamespace llvm { 809239462Sdim 810239462Sdimvoid EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { 811239462Sdim InstrInfoEmitter(RK).run(OS); 812243830Sdim EmitMapTable(RK, OS); 813239462Sdim} 814239462Sdim 815360784Sdim} // end namespace llvm 816