1 //===- VarLenCodeEmitterGen.cpp - CEG for variable-length insts -----------===// 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 // The CodeEmitterGen component for variable-length instructions. 10 // 11 // The basic CodeEmitterGen is almost exclusively designed for fixed- 12 // length instructions. A good analogy for its encoding scheme is how printf 13 // works: The (immutable) formatting string represent the fixed values in the 14 // encoded instruction. Placeholders (i.e. %something), on the other hand, 15 // represent encoding for instruction operands. 16 // ``` 17 // printf("1101 %src 1001 %dst", <encoded value for operand `src`>, 18 // <encoded value for operand `dst`>); 19 // ``` 20 // VarLenCodeEmitterGen in this file provides an alternative encoding scheme 21 // that works more like a C++ stream operator: 22 // ``` 23 // OS << 0b1101; 24 // if (Cond) 25 // OS << OperandEncoding0; 26 // OS << 0b1001 << OperandEncoding1; 27 // ``` 28 // You are free to concatenate arbitrary types (and sizes) of encoding 29 // fragments on any bit position, bringing more flexibilities on defining 30 // encoding for variable-length instructions. 31 // 32 // In a more specific way, instruction encoding is represented by a DAG type 33 // `Inst` field. Here is an example: 34 // ``` 35 // dag Inst = (descend 0b1101, (operand "$src", 4), 0b1001, 36 // (operand "$dst", 4)); 37 // ``` 38 // It represents the following instruction encoding: 39 // ``` 40 // MSB LSB 41 // 1101<encoding for operand src>1001<encoding for operand dst> 42 // ``` 43 // For more details about DAG operators in the above snippet, please 44 // refer to \file include/llvm/Target/Target.td. 45 // 46 // VarLenCodeEmitter will convert the above DAG into the same helper function 47 // generated by CodeEmitter, `MCCodeEmitter::getBinaryCodeForInstr` (except 48 // for few details). 49 // 50 //===----------------------------------------------------------------------===// 51 52 #include "VarLenCodeEmitterGen.h" 53 #include "CodeGenHwModes.h" 54 #include "CodeGenInstruction.h" 55 #include "CodeGenTarget.h" 56 #include "InfoByHwMode.h" 57 #include "llvm/ADT/ArrayRef.h" 58 #include "llvm/ADT/DenseMap.h" 59 #include "llvm/Support/raw_ostream.h" 60 #include "llvm/TableGen/Error.h" 61 #include "llvm/TableGen/Record.h" 62 63 using namespace llvm; 64 65 namespace { 66 67 class VarLenCodeEmitterGen { 68 RecordKeeper &Records; 69 70 struct EncodingSegment { 71 unsigned BitWidth; 72 const Init *Value; 73 StringRef CustomEncoder = ""; 74 }; 75 76 class VarLenInst { 77 RecordVal *TheDef; 78 size_t NumBits; 79 80 // Set if any of the segment is not fixed value. 81 bool HasDynamicSegment; 82 83 SmallVector<EncodingSegment, 4> Segments; 84 85 void buildRec(const DagInit *DI); 86 87 StringRef getCustomEncoderName(const Init *EI) const { 88 if (const auto *DI = dyn_cast<DagInit>(EI)) { 89 if (DI->getNumArgs() && isa<StringInit>(DI->getArg(0))) 90 return cast<StringInit>(DI->getArg(0))->getValue(); 91 } 92 return ""; 93 } 94 95 public: 96 VarLenInst() : TheDef(nullptr), NumBits(0U), HasDynamicSegment(false) {} 97 98 explicit VarLenInst(const DagInit *DI, RecordVal *TheDef); 99 100 /// Number of bits 101 size_t size() const { return NumBits; } 102 103 using const_iterator = decltype(Segments)::const_iterator; 104 105 const_iterator begin() const { return Segments.begin(); } 106 const_iterator end() const { return Segments.end(); } 107 size_t getNumSegments() const { return Segments.size(); } 108 109 bool isFixedValueOnly() const { return !HasDynamicSegment; } 110 }; 111 112 DenseMap<Record *, VarLenInst> VarLenInsts; 113 114 // Emit based values (i.e. fixed bits in the encoded instructions) 115 void emitInstructionBaseValues( 116 raw_ostream &OS, 117 ArrayRef<const CodeGenInstruction *> NumberedInstructions, 118 CodeGenTarget &Target, int HwMode = -1); 119 120 std::string getInstructionCase(Record *R, CodeGenTarget &Target); 121 std::string getInstructionCaseForEncoding(Record *R, Record *EncodingDef, 122 CodeGenTarget &Target); 123 124 public: 125 explicit VarLenCodeEmitterGen(RecordKeeper &R) : Records(R) {} 126 127 void run(raw_ostream &OS); 128 }; 129 130 } // end anonymous namespace 131 132 VarLenCodeEmitterGen::VarLenInst::VarLenInst(const DagInit *DI, 133 RecordVal *TheDef) 134 : TheDef(TheDef), NumBits(0U) { 135 buildRec(DI); 136 for (const auto &S : Segments) 137 NumBits += S.BitWidth; 138 } 139 140 void VarLenCodeEmitterGen::VarLenInst::buildRec(const DagInit *DI) { 141 assert(TheDef && "The def record is nullptr ?"); 142 143 std::string Op = DI->getOperator()->getAsString(); 144 145 if (Op == "ascend" || Op == "descend") { 146 bool Reverse = Op == "descend"; 147 int i = Reverse ? DI->getNumArgs() - 1 : 0; 148 int e = Reverse ? -1 : DI->getNumArgs(); 149 int s = Reverse ? -1 : 1; 150 for (; i != e; i += s) { 151 const Init *Arg = DI->getArg(i); 152 if (const auto *BI = dyn_cast<BitsInit>(Arg)) { 153 if (!BI->isComplete()) 154 PrintFatalError(TheDef->getLoc(), 155 "Expecting complete bits init in `" + Op + "`"); 156 Segments.push_back({BI->getNumBits(), BI}); 157 } else if (const auto *BI = dyn_cast<BitInit>(Arg)) { 158 if (!BI->isConcrete()) 159 PrintFatalError(TheDef->getLoc(), 160 "Expecting concrete bit init in `" + Op + "`"); 161 Segments.push_back({1, BI}); 162 } else if (const auto *SubDI = dyn_cast<DagInit>(Arg)) { 163 buildRec(SubDI); 164 } else { 165 PrintFatalError(TheDef->getLoc(), "Unrecognized type of argument in `" + 166 Op + "`: " + Arg->getAsString()); 167 } 168 } 169 } else if (Op == "operand") { 170 // (operand <operand name>, <# of bits>, [(encoder <custom encoder>)]) 171 if (DI->getNumArgs() < 2) 172 PrintFatalError(TheDef->getLoc(), 173 "Expecting at least 2 arguments for `operand`"); 174 HasDynamicSegment = true; 175 const Init *OperandName = DI->getArg(0), *NumBits = DI->getArg(1); 176 if (!isa<StringInit>(OperandName) || !isa<IntInit>(NumBits)) 177 PrintFatalError(TheDef->getLoc(), "Invalid argument types for `operand`"); 178 179 auto NumBitsVal = cast<IntInit>(NumBits)->getValue(); 180 if (NumBitsVal <= 0) 181 PrintFatalError(TheDef->getLoc(), "Invalid number of bits for `operand`"); 182 183 StringRef CustomEncoder; 184 if (DI->getNumArgs() >= 3) 185 CustomEncoder = getCustomEncoderName(DI->getArg(2)); 186 Segments.push_back( 187 {static_cast<unsigned>(NumBitsVal), OperandName, CustomEncoder}); 188 } else if (Op == "slice") { 189 // (slice <operand name>, <high / low bit>, <low / high bit>, 190 // [(encoder <custom encoder>)]) 191 if (DI->getNumArgs() < 3) 192 PrintFatalError(TheDef->getLoc(), 193 "Expecting at least 3 arguments for `slice`"); 194 HasDynamicSegment = true; 195 Init *OperandName = DI->getArg(0), *HiBit = DI->getArg(1), 196 *LoBit = DI->getArg(2); 197 if (!isa<StringInit>(OperandName) || !isa<IntInit>(HiBit) || 198 !isa<IntInit>(LoBit)) 199 PrintFatalError(TheDef->getLoc(), "Invalid argument types for `slice`"); 200 201 auto HiBitVal = cast<IntInit>(HiBit)->getValue(), 202 LoBitVal = cast<IntInit>(LoBit)->getValue(); 203 if (HiBitVal < 0 || LoBitVal < 0) 204 PrintFatalError(TheDef->getLoc(), "Invalid bit range for `slice`"); 205 bool NeedSwap = false; 206 unsigned NumBits = 0U; 207 if (HiBitVal < LoBitVal) { 208 NeedSwap = true; 209 NumBits = static_cast<unsigned>(LoBitVal - HiBitVal + 1); 210 } else { 211 NumBits = static_cast<unsigned>(HiBitVal - LoBitVal + 1); 212 } 213 214 StringRef CustomEncoder; 215 if (DI->getNumArgs() >= 4) 216 CustomEncoder = getCustomEncoderName(DI->getArg(3)); 217 218 if (NeedSwap) { 219 // Normalization: Hi bit should always be the second argument. 220 Init *const NewArgs[] = {OperandName, LoBit, HiBit}; 221 Segments.push_back({NumBits, 222 DagInit::get(DI->getOperator(), nullptr, NewArgs, {}), 223 CustomEncoder}); 224 } else { 225 Segments.push_back({NumBits, DI, CustomEncoder}); 226 } 227 } 228 } 229 230 void VarLenCodeEmitterGen::run(raw_ostream &OS) { 231 CodeGenTarget Target(Records); 232 auto Insts = Records.getAllDerivedDefinitions("Instruction"); 233 234 auto NumberedInstructions = Target.getInstructionsByEnumValue(); 235 const CodeGenHwModes &HWM = Target.getHwModes(); 236 237 // The set of HwModes used by instruction encodings. 238 std::set<unsigned> HwModes; 239 for (const CodeGenInstruction *CGI : NumberedInstructions) { 240 Record *R = CGI->TheDef; 241 242 // Create the corresponding VarLenInst instance. 243 if (R->getValueAsString("Namespace") == "TargetOpcode" || 244 R->getValueAsBit("isPseudo")) 245 continue; 246 247 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 248 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 249 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 250 for (auto &KV : EBM) { 251 HwModes.insert(KV.first); 252 Record *EncodingDef = KV.second; 253 RecordVal *RV = EncodingDef->getValue("Inst"); 254 DagInit *DI = cast<DagInit>(RV->getValue()); 255 VarLenInsts.insert({EncodingDef, VarLenInst(DI, RV)}); 256 } 257 continue; 258 } 259 } 260 RecordVal *RV = R->getValue("Inst"); 261 DagInit *DI = cast<DagInit>(RV->getValue()); 262 VarLenInsts.insert({R, VarLenInst(DI, RV)}); 263 } 264 265 // Emit function declaration 266 OS << "void " << Target.getName() 267 << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n" 268 << " SmallVectorImpl<MCFixup> &Fixups,\n" 269 << " APInt &Inst,\n" 270 << " APInt &Scratch,\n" 271 << " const MCSubtargetInfo &STI) const {\n"; 272 273 // Emit instruction base values 274 if (HwModes.empty()) { 275 emitInstructionBaseValues(OS, NumberedInstructions, Target); 276 } else { 277 for (unsigned HwMode : HwModes) 278 emitInstructionBaseValues(OS, NumberedInstructions, Target, (int)HwMode); 279 } 280 281 if (!HwModes.empty()) { 282 OS << " const unsigned **Index;\n"; 283 OS << " const uint64_t *InstBits;\n"; 284 OS << " unsigned HwMode = STI.getHwMode();\n"; 285 OS << " switch (HwMode) {\n"; 286 OS << " default: llvm_unreachable(\"Unknown hardware mode!\"); break;\n"; 287 for (unsigned I : HwModes) { 288 OS << " case " << I << ": InstBits = InstBits_" << HWM.getMode(I).Name 289 << "; Index = Index_" << HWM.getMode(I).Name << "; break;\n"; 290 } 291 OS << " };\n"; 292 } 293 294 // Emit helper function to retrieve base values. 295 OS << " auto getInstBits = [&](unsigned Opcode) -> APInt {\n" 296 << " unsigned NumBits = Index[Opcode][0];\n" 297 << " if (!NumBits)\n" 298 << " return APInt::getZeroWidth();\n" 299 << " unsigned Idx = Index[Opcode][1];\n" 300 << " ArrayRef<uint64_t> Data(&InstBits[Idx], " 301 << "APInt::getNumWords(NumBits));\n" 302 << " return APInt(NumBits, Data);\n" 303 << " };\n"; 304 305 // Map to accumulate all the cases. 306 std::map<std::string, std::vector<std::string>> CaseMap; 307 308 // Construct all cases statement for each opcode 309 for (Record *R : Insts) { 310 if (R->getValueAsString("Namespace") == "TargetOpcode" || 311 R->getValueAsBit("isPseudo")) 312 continue; 313 std::string InstName = 314 (R->getValueAsString("Namespace") + "::" + R->getName()).str(); 315 std::string Case = getInstructionCase(R, Target); 316 317 CaseMap[Case].push_back(std::move(InstName)); 318 } 319 320 // Emit initial function code 321 OS << " const unsigned opcode = MI.getOpcode();\n" 322 << " switch (opcode) {\n"; 323 324 // Emit each case statement 325 for (const auto &C : CaseMap) { 326 const std::string &Case = C.first; 327 const auto &InstList = C.second; 328 329 ListSeparator LS("\n"); 330 for (const auto &InstName : InstList) 331 OS << LS << " case " << InstName << ":"; 332 333 OS << " {\n"; 334 OS << Case; 335 OS << " break;\n" 336 << " }\n"; 337 } 338 // Default case: unhandled opcode 339 OS << " default:\n" 340 << " std::string msg;\n" 341 << " raw_string_ostream Msg(msg);\n" 342 << " Msg << \"Not supported instr: \" << MI;\n" 343 << " report_fatal_error(Msg.str().c_str());\n" 344 << " }\n"; 345 OS << "}\n\n"; 346 } 347 348 static void emitInstBits(raw_ostream &IS, raw_ostream &SS, const APInt &Bits, 349 unsigned &Index) { 350 if (!Bits.getNumWords()) { 351 IS.indent(4) << "{/*NumBits*/0, /*Index*/0},"; 352 return; 353 } 354 355 IS.indent(4) << "{/*NumBits*/" << Bits.getBitWidth() << ", " 356 << "/*Index*/" << Index << "},"; 357 358 SS.indent(4); 359 for (unsigned I = 0; I < Bits.getNumWords(); ++I, ++Index) 360 SS << "UINT64_C(" << utostr(Bits.getRawData()[I]) << "),"; 361 } 362 363 void VarLenCodeEmitterGen::emitInstructionBaseValues( 364 raw_ostream &OS, ArrayRef<const CodeGenInstruction *> NumberedInstructions, 365 CodeGenTarget &Target, int HwMode) { 366 std::string IndexArray, StorageArray; 367 raw_string_ostream IS(IndexArray), SS(StorageArray); 368 369 const CodeGenHwModes &HWM = Target.getHwModes(); 370 if (HwMode == -1) { 371 IS << " static const unsigned Index[][2] = {\n"; 372 SS << " static const uint64_t InstBits[] = {\n"; 373 } else { 374 StringRef Name = HWM.getMode(HwMode).Name; 375 IS << " static const unsigned Index_" << Name << "[][2] = {\n"; 376 SS << " static const uint64_t InstBits_" << Name << "[] = {\n"; 377 } 378 379 unsigned NumFixedValueWords = 0U; 380 for (const CodeGenInstruction *CGI : NumberedInstructions) { 381 Record *R = CGI->TheDef; 382 383 if (R->getValueAsString("Namespace") == "TargetOpcode" || 384 R->getValueAsBit("isPseudo")) { 385 IS.indent(4) << "{/*NumBits*/0, /*Index*/0},\n"; 386 continue; 387 } 388 389 Record *EncodingDef = R; 390 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 391 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 392 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 393 if (EBM.hasMode(HwMode)) 394 EncodingDef = EBM.get(HwMode); 395 } 396 } 397 398 auto It = VarLenInsts.find(EncodingDef); 399 if (It == VarLenInsts.end()) 400 PrintFatalError(EncodingDef, "VarLenInst not found for this record"); 401 const VarLenInst &VLI = It->second; 402 403 unsigned i = 0U, BitWidth = VLI.size(); 404 405 // Start by filling in fixed values. 406 APInt Value(BitWidth, 0); 407 auto SI = VLI.begin(), SE = VLI.end(); 408 // Scan through all the segments that have fixed-bits values. 409 while (i < BitWidth && SI != SE) { 410 unsigned SegmentNumBits = SI->BitWidth; 411 if (const auto *BI = dyn_cast<BitsInit>(SI->Value)) { 412 for (unsigned Idx = 0U; Idx != SegmentNumBits; ++Idx) { 413 auto *B = cast<BitInit>(BI->getBit(Idx)); 414 Value.setBitVal(i + Idx, B->getValue()); 415 } 416 } 417 if (const auto *BI = dyn_cast<BitInit>(SI->Value)) 418 Value.setBitVal(i, BI->getValue()); 419 420 i += SegmentNumBits; 421 ++SI; 422 } 423 424 emitInstBits(IS, SS, Value, NumFixedValueWords); 425 IS << '\t' << "// " << R->getName() << "\n"; 426 if (Value.getNumWords()) 427 SS << '\t' << "// " << R->getName() << "\n"; 428 } 429 IS.indent(4) << "{/*NumBits*/0, /*Index*/0}\n };\n"; 430 SS.indent(4) << "UINT64_C(0)\n };\n"; 431 432 OS << IS.str() << SS.str(); 433 } 434 435 std::string VarLenCodeEmitterGen::getInstructionCase(Record *R, 436 CodeGenTarget &Target) { 437 std::string Case; 438 if (const RecordVal *RV = R->getValue("EncodingInfos")) { 439 if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) { 440 const CodeGenHwModes &HWM = Target.getHwModes(); 441 EncodingInfoByHwMode EBM(DI->getDef(), HWM); 442 Case += " switch (HwMode) {\n"; 443 Case += " default: llvm_unreachable(\"Unhandled HwMode\");\n"; 444 for (auto &KV : EBM) { 445 Case += " case " + itostr(KV.first) + ": {\n"; 446 Case += getInstructionCaseForEncoding(R, KV.second, Target); 447 Case += " break;\n"; 448 Case += " }\n"; 449 } 450 Case += " }\n"; 451 return Case; 452 } 453 } 454 return getInstructionCaseForEncoding(R, R, Target); 455 } 456 457 std::string VarLenCodeEmitterGen::getInstructionCaseForEncoding( 458 Record *R, Record *EncodingDef, CodeGenTarget &Target) { 459 auto It = VarLenInsts.find(EncodingDef); 460 if (It == VarLenInsts.end()) 461 PrintFatalError(EncodingDef, "Parsed encoding record not found"); 462 const VarLenInst &VLI = It->second; 463 size_t BitWidth = VLI.size(); 464 465 CodeGenInstruction &CGI = Target.getInstruction(R); 466 467 std::string Case; 468 raw_string_ostream SS(Case); 469 // Resize the scratch buffer. 470 if (BitWidth && !VLI.isFixedValueOnly()) 471 SS.indent(6) << "Scratch = Scratch.zextOrSelf(" << BitWidth << ");\n"; 472 // Populate based value. 473 SS.indent(6) << "Inst = getInstBits(opcode);\n"; 474 475 // Process each segment in VLI. 476 size_t Offset = 0U; 477 for (const auto &ES : VLI) { 478 unsigned NumBits = ES.BitWidth; 479 const Init *Val = ES.Value; 480 // If it's a StringInit or DagInit, it's a reference to an operand 481 // or part of an operand. 482 if (isa<StringInit>(Val) || isa<DagInit>(Val)) { 483 StringRef OperandName; 484 unsigned LoBit = 0U; 485 if (const auto *SV = dyn_cast<StringInit>(Val)) { 486 OperandName = SV->getValue(); 487 } else { 488 // Normalized: (slice <operand name>, <high bit>, <low bit>) 489 const auto *DV = cast<DagInit>(Val); 490 OperandName = cast<StringInit>(DV->getArg(0))->getValue(); 491 LoBit = static_cast<unsigned>(cast<IntInit>(DV->getArg(2))->getValue()); 492 } 493 494 auto OpIdx = CGI.Operands.ParseOperandName(OperandName); 495 unsigned FlatOpIdx = CGI.Operands.getFlattenedOperandNumber(OpIdx); 496 StringRef CustomEncoder = CGI.Operands[OpIdx.first].EncoderMethodName; 497 if (ES.CustomEncoder.size()) 498 CustomEncoder = ES.CustomEncoder; 499 500 SS.indent(6) << "Scratch.clearAllBits();\n"; 501 SS.indent(6) << "// op: " << OperandName.drop_front(1) << "\n"; 502 if (CustomEncoder.empty()) 503 SS.indent(6) << "getMachineOpValue(MI, MI.getOperand(" 504 << utostr(FlatOpIdx) << ")"; 505 else 506 SS.indent(6) << CustomEncoder << "(MI, /*OpIdx=*/" << utostr(FlatOpIdx); 507 508 SS << ", /*Pos=*/" << utostr(Offset) << ", Scratch, Fixups, STI);\n"; 509 510 SS.indent(6) << "Inst.insertBits(" 511 << "Scratch.extractBits(" << utostr(NumBits) << ", " 512 << utostr(LoBit) << ")" 513 << ", " << Offset << ");\n"; 514 } 515 Offset += NumBits; 516 } 517 518 StringRef PostEmitter = R->getValueAsString("PostEncoderMethod"); 519 if (!PostEmitter.empty()) 520 SS.indent(6) << "Inst = " << PostEmitter << "(MI, Inst, STI);\n"; 521 522 return Case; 523 } 524 525 namespace llvm { 526 527 void emitVarLenCodeEmitter(RecordKeeper &R, raw_ostream &OS) { 528 VarLenCodeEmitterGen(R).run(OS); 529 } 530 531 } // end namespace llvm 532