1 //===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This tablegen backend is emits an assembly printer for the current target. 11 // Note that this is currently fairly skeletal, but will grow over time. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "AsmWriterEmitter.h" 16 #include "AsmWriterInst.h" 17 #include "CodeGenTarget.h" 18 #include "StringToOffsetTable.h" 19 #include "SequenceToOffsetTable.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/MathExtras.h" 23 #include "llvm/TableGen/Error.h" 24 #include "llvm/TableGen/Record.h" 25 #include <algorithm> 26 using namespace llvm; 27 28 static void PrintCases(std::vector<std::pair<std::string, 29 AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { 30 O << " case " << OpsToPrint.back().first << ": "; 31 AsmWriterOperand TheOp = OpsToPrint.back().second; 32 OpsToPrint.pop_back(); 33 34 // Check to see if any other operands are identical in this list, and if so, 35 // emit a case label for them. 36 for (unsigned i = OpsToPrint.size(); i != 0; --i) 37 if (OpsToPrint[i-1].second == TheOp) { 38 O << "\n case " << OpsToPrint[i-1].first << ": "; 39 OpsToPrint.erase(OpsToPrint.begin()+i-1); 40 } 41 42 // Finally, emit the code. 43 O << TheOp.getCode(); 44 O << "break;\n"; 45 } 46 47 48 /// EmitInstructions - Emit the last instruction in the vector and any other 49 /// instructions that are suitably similar to it. 50 static void EmitInstructions(std::vector<AsmWriterInst> &Insts, 51 raw_ostream &O) { 52 AsmWriterInst FirstInst = Insts.back(); 53 Insts.pop_back(); 54 55 std::vector<AsmWriterInst> SimilarInsts; 56 unsigned DifferingOperand = ~0; 57 for (unsigned i = Insts.size(); i != 0; --i) { 58 unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); 59 if (DiffOp != ~1U) { 60 if (DifferingOperand == ~0U) // First match! 61 DifferingOperand = DiffOp; 62 63 // If this differs in the same operand as the rest of the instructions in 64 // this class, move it to the SimilarInsts list. 65 if (DifferingOperand == DiffOp || DiffOp == ~0U) { 66 SimilarInsts.push_back(Insts[i-1]); 67 Insts.erase(Insts.begin()+i-1); 68 } 69 } 70 } 71 72 O << " case " << FirstInst.CGI->Namespace << "::" 73 << FirstInst.CGI->TheDef->getName() << ":\n"; 74 for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) 75 O << " case " << SimilarInsts[i].CGI->Namespace << "::" 76 << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; 77 for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { 78 if (i != DifferingOperand) { 79 // If the operand is the same for all instructions, just print it. 80 O << " " << FirstInst.Operands[i].getCode(); 81 } else { 82 // If this is the operand that varies between all of the instructions, 83 // emit a switch for just this operand now. 84 O << " switch (MI->getOpcode()) {\n"; 85 std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint; 86 OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" + 87 FirstInst.CGI->TheDef->getName(), 88 FirstInst.Operands[i])); 89 90 for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { 91 AsmWriterInst &AWI = SimilarInsts[si]; 92 OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+ 93 AWI.CGI->TheDef->getName(), 94 AWI.Operands[i])); 95 } 96 std::reverse(OpsToPrint.begin(), OpsToPrint.end()); 97 while (!OpsToPrint.empty()) 98 PrintCases(OpsToPrint, O); 99 O << " }"; 100 } 101 O << "\n"; 102 } 103 O << " break;\n"; 104 } 105 106 void AsmWriterEmitter:: 107 FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 108 std::vector<unsigned> &InstIdxs, 109 std::vector<unsigned> &InstOpsUsed) const { 110 InstIdxs.assign(NumberedInstructions.size(), ~0U); 111 112 // This vector parallels UniqueOperandCommands, keeping track of which 113 // instructions each case are used for. It is a comma separated string of 114 // enums. 115 std::vector<std::string> InstrsForCase; 116 InstrsForCase.resize(UniqueOperandCommands.size()); 117 InstOpsUsed.assign(UniqueOperandCommands.size(), 0); 118 119 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 120 const AsmWriterInst *Inst = getAsmWriterInstByID(i); 121 if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc. 122 123 std::string Command; 124 if (Inst->Operands.empty()) 125 continue; // Instruction already done. 126 127 Command = " " + Inst->Operands[0].getCode() + "\n"; 128 129 // Check to see if we already have 'Command' in UniqueOperandCommands. 130 // If not, add it. 131 bool FoundIt = false; 132 for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx) 133 if (UniqueOperandCommands[idx] == Command) { 134 InstIdxs[i] = idx; 135 InstrsForCase[idx] += ", "; 136 InstrsForCase[idx] += Inst->CGI->TheDef->getName(); 137 FoundIt = true; 138 break; 139 } 140 if (!FoundIt) { 141 InstIdxs[i] = UniqueOperandCommands.size(); 142 UniqueOperandCommands.push_back(Command); 143 InstrsForCase.push_back(Inst->CGI->TheDef->getName()); 144 145 // This command matches one operand so far. 146 InstOpsUsed.push_back(1); 147 } 148 } 149 150 // For each entry of UniqueOperandCommands, there is a set of instructions 151 // that uses it. If the next command of all instructions in the set are 152 // identical, fold it into the command. 153 for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); 154 CommandIdx != e; ++CommandIdx) { 155 156 for (unsigned Op = 1; ; ++Op) { 157 // Scan for the first instruction in the set. 158 std::vector<unsigned>::iterator NIT = 159 std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx); 160 if (NIT == InstIdxs.end()) break; // No commonality. 161 162 // If this instruction has no more operands, we isn't anything to merge 163 // into this command. 164 const AsmWriterInst *FirstInst = 165 getAsmWriterInstByID(NIT-InstIdxs.begin()); 166 if (!FirstInst || FirstInst->Operands.size() == Op) 167 break; 168 169 // Otherwise, scan to see if all of the other instructions in this command 170 // set share the operand. 171 bool AllSame = true; 172 // Keep track of the maximum, number of operands or any 173 // instruction we see in the group. 174 size_t MaxSize = FirstInst->Operands.size(); 175 176 for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); 177 NIT != InstIdxs.end(); 178 NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { 179 // Okay, found another instruction in this command set. If the operand 180 // matches, we're ok, otherwise bail out. 181 const AsmWriterInst *OtherInst = 182 getAsmWriterInstByID(NIT-InstIdxs.begin()); 183 184 if (OtherInst && 185 OtherInst->Operands.size() > FirstInst->Operands.size()) 186 MaxSize = std::max(MaxSize, OtherInst->Operands.size()); 187 188 if (!OtherInst || OtherInst->Operands.size() == Op || 189 OtherInst->Operands[Op] != FirstInst->Operands[Op]) { 190 AllSame = false; 191 break; 192 } 193 } 194 if (!AllSame) break; 195 196 // Okay, everything in this command set has the same next operand. Add it 197 // to UniqueOperandCommands and remember that it was consumed. 198 std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n"; 199 200 UniqueOperandCommands[CommandIdx] += Command; 201 InstOpsUsed[CommandIdx]++; 202 } 203 } 204 205 // Prepend some of the instructions each case is used for onto the case val. 206 for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) { 207 std::string Instrs = InstrsForCase[i]; 208 if (Instrs.size() > 70) { 209 Instrs.erase(Instrs.begin()+70, Instrs.end()); 210 Instrs += "..."; 211 } 212 213 if (!Instrs.empty()) 214 UniqueOperandCommands[i] = " // " + Instrs + "\n" + 215 UniqueOperandCommands[i]; 216 } 217 } 218 219 220 static void UnescapeString(std::string &Str) { 221 for (unsigned i = 0; i != Str.size(); ++i) { 222 if (Str[i] == '\\' && i != Str.size()-1) { 223 switch (Str[i+1]) { 224 default: continue; // Don't execute the code after the switch. 225 case 'a': Str[i] = '\a'; break; 226 case 'b': Str[i] = '\b'; break; 227 case 'e': Str[i] = 27; break; 228 case 'f': Str[i] = '\f'; break; 229 case 'n': Str[i] = '\n'; break; 230 case 'r': Str[i] = '\r'; break; 231 case 't': Str[i] = '\t'; break; 232 case 'v': Str[i] = '\v'; break; 233 case '"': Str[i] = '\"'; break; 234 case '\'': Str[i] = '\''; break; 235 case '\\': Str[i] = '\\'; break; 236 } 237 // Nuke the second character. 238 Str.erase(Str.begin()+i+1); 239 } 240 } 241 } 242 243 /// EmitPrintInstruction - Generate the code for the "printInstruction" method 244 /// implementation. 245 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 246 CodeGenTarget Target(Records); 247 Record *AsmWriter = Target.getAsmWriter(); 248 std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 249 bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter"); 250 const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr"; 251 252 O << 253 "/// printInstruction - This method is automatically generated by tablegen\n" 254 "/// from the instruction set description.\n" 255 "void " << Target.getName() << ClassName 256 << "::printInstruction(const " << MachineInstrClassName 257 << " *MI, raw_ostream &O) {\n"; 258 259 std::vector<AsmWriterInst> Instructions; 260 261 for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 262 E = Target.inst_end(); I != E; ++I) 263 if (!(*I)->AsmString.empty() && 264 (*I)->TheDef->getName() != "PHI") 265 Instructions.push_back( 266 AsmWriterInst(**I, 267 AsmWriter->getValueAsInt("Variant"), 268 AsmWriter->getValueAsInt("FirstOperandColumn"), 269 AsmWriter->getValueAsInt("OperandSpacing"))); 270 271 // Get the instruction numbering. 272 NumberedInstructions = Target.getInstructionsByEnumValue(); 273 274 // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not 275 // all machine instructions are necessarily being printed, so there may be 276 // target instructions not in this map. 277 for (unsigned i = 0, e = Instructions.size(); i != e; ++i) 278 CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); 279 280 // Build an aggregate string, and build a table of offsets into it. 281 SequenceToOffsetTable<std::string> StringTable; 282 283 /// OpcodeInfo - This encodes the index of the string to use for the first 284 /// chunk of the output as well as indices used for operand printing. 285 std::vector<unsigned> OpcodeInfo; 286 287 // Add all strings to the string table upfront so it can generate an optimized 288 // representation. 289 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 290 AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 291 if (AWI != 0 && 292 AWI->Operands[0].OperandType == 293 AsmWriterOperand::isLiteralTextOperand && 294 !AWI->Operands[0].Str.empty()) { 295 std::string Str = AWI->Operands[0].Str; 296 UnescapeString(Str); 297 StringTable.add(Str); 298 } 299 } 300 301 StringTable.layout(); 302 303 unsigned MaxStringIdx = 0; 304 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 305 AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 306 unsigned Idx; 307 if (AWI == 0) { 308 // Something not handled by the asmwriter printer. 309 Idx = ~0U; 310 } else if (AWI->Operands[0].OperandType != 311 AsmWriterOperand::isLiteralTextOperand || 312 AWI->Operands[0].Str.empty()) { 313 // Something handled by the asmwriter printer, but with no leading string. 314 Idx = StringTable.get(""); 315 } else { 316 std::string Str = AWI->Operands[0].Str; 317 UnescapeString(Str); 318 Idx = StringTable.get(Str); 319 MaxStringIdx = std::max(MaxStringIdx, Idx); 320 321 // Nuke the string from the operand list. It is now handled! 322 AWI->Operands.erase(AWI->Operands.begin()); 323 } 324 325 // Bias offset by one since we want 0 as a sentinel. 326 OpcodeInfo.push_back(Idx+1); 327 } 328 329 // Figure out how many bits we used for the string index. 330 unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2); 331 332 // To reduce code size, we compactify common instructions into a few bits 333 // in the opcode-indexed table. 334 unsigned BitsLeft = 32-AsmStrBits; 335 336 std::vector<std::vector<std::string> > TableDrivenOperandPrinters; 337 338 while (1) { 339 std::vector<std::string> UniqueOperandCommands; 340 std::vector<unsigned> InstIdxs; 341 std::vector<unsigned> NumInstOpsHandled; 342 FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, 343 NumInstOpsHandled); 344 345 // If we ran out of operands to print, we're done. 346 if (UniqueOperandCommands.empty()) break; 347 348 // Compute the number of bits we need to represent these cases, this is 349 // ceil(log2(numentries)). 350 unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size()); 351 352 // If we don't have enough bits for this operand, don't include it. 353 if (NumBits > BitsLeft) { 354 DEBUG(errs() << "Not enough bits to densely encode " << NumBits 355 << " more bits\n"); 356 break; 357 } 358 359 // Otherwise, we can include this in the initial lookup table. Add it in. 360 BitsLeft -= NumBits; 361 for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i) 362 if (InstIdxs[i] != ~0U) 363 OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits); 364 365 // Remove the info about this operand. 366 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 367 if (AsmWriterInst *Inst = getAsmWriterInstByID(i)) 368 if (!Inst->Operands.empty()) { 369 unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; 370 assert(NumOps <= Inst->Operands.size() && 371 "Can't remove this many ops!"); 372 Inst->Operands.erase(Inst->Operands.begin(), 373 Inst->Operands.begin()+NumOps); 374 } 375 } 376 377 // Remember the handlers for this set of operands. 378 TableDrivenOperandPrinters.push_back(UniqueOperandCommands); 379 } 380 381 382 383 O<<" static const unsigned OpInfo[] = {\n"; 384 for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 385 O << " " << OpcodeInfo[i] << "U,\t// " 386 << NumberedInstructions[i]->TheDef->getName() << "\n"; 387 } 388 // Add a dummy entry so the array init doesn't end with a comma. 389 O << " 0U\n"; 390 O << " };\n\n"; 391 392 // Emit the string itself. 393 O << " const char AsmStrs[] = {\n"; 394 StringTable.emit(O, printChar); 395 O << " };\n\n"; 396 397 O << " O << \"\\t\";\n\n"; 398 399 O << " // Emit the opcode for the instruction.\n" 400 << " unsigned Bits = OpInfo[MI->getOpcode()];\n" 401 << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 402 << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; 403 404 // Output the table driven operand information. 405 BitsLeft = 32-AsmStrBits; 406 for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { 407 std::vector<std::string> &Commands = TableDrivenOperandPrinters[i]; 408 409 // Compute the number of bits we need to represent these cases, this is 410 // ceil(log2(numentries)). 411 unsigned NumBits = Log2_32_Ceil(Commands.size()); 412 assert(NumBits <= BitsLeft && "consistency error"); 413 414 // Emit code to extract this field from Bits. 415 BitsLeft -= NumBits; 416 417 O << "\n // Fragment " << i << " encoded into " << NumBits 418 << " bits for " << Commands.size() << " unique commands.\n"; 419 420 if (Commands.size() == 2) { 421 // Emit two possibilitys with if/else. 422 O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 423 << ((1 << NumBits)-1) << ") {\n" 424 << Commands[1] 425 << " } else {\n" 426 << Commands[0] 427 << " }\n\n"; 428 } else if (Commands.size() == 1) { 429 // Emit a single possibility. 430 O << Commands[0] << "\n\n"; 431 } else { 432 O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 433 << ((1 << NumBits)-1) << ") {\n" 434 << " default: // unreachable.\n"; 435 436 // Print out all the cases. 437 for (unsigned i = 0, e = Commands.size(); i != e; ++i) { 438 O << " case " << i << ":\n"; 439 O << Commands[i]; 440 O << " break;\n"; 441 } 442 O << " }\n\n"; 443 } 444 } 445 446 // Okay, delete instructions with no operand info left. 447 for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 448 // Entire instruction has been emitted? 449 AsmWriterInst &Inst = Instructions[i]; 450 if (Inst.Operands.empty()) { 451 Instructions.erase(Instructions.begin()+i); 452 --i; --e; 453 } 454 } 455 456 457 // Because this is a vector, we want to emit from the end. Reverse all of the 458 // elements in the vector. 459 std::reverse(Instructions.begin(), Instructions.end()); 460 461 462 // Now that we've emitted all of the operand info that fit into 32 bits, emit 463 // information for those instructions that are left. This is a less dense 464 // encoding, but we expect the main 32-bit table to handle the majority of 465 // instructions. 466 if (!Instructions.empty()) { 467 // Find the opcode # of inline asm. 468 O << " switch (MI->getOpcode()) {\n"; 469 while (!Instructions.empty()) 470 EmitInstructions(Instructions, O); 471 472 O << " }\n"; 473 O << " return;\n"; 474 } 475 476 O << "}\n"; 477 } 478 479 static void 480 emitRegisterNameString(raw_ostream &O, StringRef AltName, 481 const std::vector<CodeGenRegister*> &Registers) { 482 SequenceToOffsetTable<std::string> StringTable; 483 SmallVector<std::string, 4> AsmNames(Registers.size()); 484 for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 485 const CodeGenRegister &Reg = *Registers[i]; 486 std::string &AsmName = AsmNames[i]; 487 488 // "NoRegAltName" is special. We don't need to do a lookup for that, 489 // as it's just a reference to the default register name. 490 if (AltName == "" || AltName == "NoRegAltName") { 491 AsmName = Reg.TheDef->getValueAsString("AsmName"); 492 if (AsmName.empty()) 493 AsmName = Reg.getName(); 494 } else { 495 // Make sure the register has an alternate name for this index. 496 std::vector<Record*> AltNameList = 497 Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices"); 498 unsigned Idx = 0, e; 499 for (e = AltNameList.size(); 500 Idx < e && (AltNameList[Idx]->getName() != AltName); 501 ++Idx) 502 ; 503 // If the register has an alternate name for this index, use it. 504 // Otherwise, leave it empty as an error flag. 505 if (Idx < e) { 506 std::vector<std::string> AltNames = 507 Reg.TheDef->getValueAsListOfStrings("AltNames"); 508 if (AltNames.size() <= Idx) 509 throw TGError(Reg.TheDef->getLoc(), 510 (Twine("Register definition missing alt name for '") + 511 AltName + "'.").str()); 512 AsmName = AltNames[Idx]; 513 } 514 } 515 StringTable.add(AsmName); 516 } 517 518 StringTable.layout(); 519 O << " static const char AsmStrs" << AltName << "[] = {\n"; 520 StringTable.emit(O, printChar); 521 O << " };\n\n"; 522 523 O << " static const unsigned RegAsmOffset" << AltName << "[] = {"; 524 for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 525 if ((i % 14) == 0) 526 O << "\n "; 527 O << StringTable.get(AsmNames[i]) << ", "; 528 } 529 O << "\n };\n" 530 << "\n"; 531 } 532 533 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 534 CodeGenTarget Target(Records); 535 Record *AsmWriter = Target.getAsmWriter(); 536 std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 537 const std::vector<CodeGenRegister*> &Registers = 538 Target.getRegBank().getRegisters(); 539 std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices(); 540 bool hasAltNames = AltNameIndices.size() > 1; 541 542 O << 543 "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" 544 "/// from the register set description. This returns the assembler name\n" 545 "/// for the specified register.\n" 546 "const char *" << Target.getName() << ClassName << "::"; 547 if (hasAltNames) 548 O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; 549 else 550 O << "getRegisterName(unsigned RegNo) {\n"; 551 O << " assert(RegNo && RegNo < " << (Registers.size()+1) 552 << " && \"Invalid register number!\");\n" 553 << "\n"; 554 555 if (hasAltNames) { 556 for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) 557 emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers); 558 } else 559 emitRegisterNameString(O, "", Registers); 560 561 if (hasAltNames) { 562 O << " const unsigned *RegAsmOffset;\n" 563 << " const char *AsmStrs;\n" 564 << " switch(AltIdx) {\n" 565 << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; 566 for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) { 567 StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace"); 568 StringRef AltName(AltNameIndices[i]->getName()); 569 O << " case " << Namespace << "::" << AltName 570 << ":\n" 571 << " AsmStrs = AsmStrs" << AltName << ";\n" 572 << " RegAsmOffset = RegAsmOffset" << AltName << ";\n" 573 << " break;\n"; 574 } 575 O << "}\n"; 576 } 577 578 O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" 579 << " \"Invalid alt name index for register!\");\n" 580 << " return AsmStrs+RegAsmOffset[RegNo-1];\n" 581 << "}\n"; 582 } 583 584 namespace { 585 // IAPrinter - Holds information about an InstAlias. Two InstAliases match if 586 // they both have the same conditionals. In which case, we cannot print out the 587 // alias for that pattern. 588 class IAPrinter { 589 std::vector<std::string> Conds; 590 std::map<StringRef, unsigned> OpMap; 591 std::string Result; 592 std::string AsmString; 593 SmallVector<Record*, 4> ReqFeatures; 594 public: 595 IAPrinter(std::string R, std::string AS) 596 : Result(R), AsmString(AS) {} 597 598 void addCond(const std::string &C) { Conds.push_back(C); } 599 600 void addOperand(StringRef Op, unsigned Idx) { OpMap[Op] = Idx; } 601 unsigned getOpIndex(StringRef Op) { return OpMap[Op]; } 602 bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); } 603 604 void print(raw_ostream &O) { 605 if (Conds.empty() && ReqFeatures.empty()) { 606 O.indent(6) << "return true;\n"; 607 return; 608 } 609 610 O << "if ("; 611 612 for (std::vector<std::string>::iterator 613 I = Conds.begin(), E = Conds.end(); I != E; ++I) { 614 if (I != Conds.begin()) { 615 O << " &&\n"; 616 O.indent(8); 617 } 618 619 O << *I; 620 } 621 622 O << ") {\n"; 623 O.indent(6) << "// " << Result << "\n"; 624 O.indent(6) << "AsmString = \"" << AsmString << "\";\n"; 625 626 for (std::map<StringRef, unsigned>::iterator 627 I = OpMap.begin(), E = OpMap.end(); I != E; ++I) 628 O.indent(6) << "OpMap.push_back(std::make_pair(\"" << I->first << "\", " 629 << I->second << "));\n"; 630 631 O.indent(6) << "break;\n"; 632 O.indent(4) << '}'; 633 } 634 635 bool operator==(const IAPrinter &RHS) { 636 if (Conds.size() != RHS.Conds.size()) 637 return false; 638 639 unsigned Idx = 0; 640 for (std::vector<std::string>::iterator 641 I = Conds.begin(), E = Conds.end(); I != E; ++I) 642 if (*I != RHS.Conds[Idx++]) 643 return false; 644 645 return true; 646 } 647 648 bool operator()(const IAPrinter &RHS) { 649 if (Conds.size() < RHS.Conds.size()) 650 return true; 651 652 unsigned Idx = 0; 653 for (std::vector<std::string>::iterator 654 I = Conds.begin(), E = Conds.end(); I != E; ++I) 655 if (*I != RHS.Conds[Idx++]) 656 return *I < RHS.Conds[Idx++]; 657 658 return false; 659 } 660 }; 661 662 } // end anonymous namespace 663 664 static void EmitGetMapOperandNumber(raw_ostream &O) { 665 O << "static unsigned getMapOperandNumber(" 666 << "const SmallVectorImpl<std::pair<StringRef, unsigned> > &OpMap,\n"; 667 O << " StringRef Name) {\n"; 668 O << " for (SmallVectorImpl<std::pair<StringRef, unsigned> >::" 669 << "const_iterator\n"; 670 O << " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n"; 671 O << " if (I->first == Name)\n"; 672 O << " return I->second;\n"; 673 O << " llvm_unreachable(\"Operand not in map!\");\n"; 674 O << "}\n\n"; 675 } 676 677 static unsigned CountNumOperands(StringRef AsmString) { 678 unsigned NumOps = 0; 679 std::pair<StringRef, StringRef> ASM = AsmString.split(' '); 680 681 while (!ASM.second.empty()) { 682 ++NumOps; 683 ASM = ASM.second.split(' '); 684 } 685 686 return NumOps; 687 } 688 689 static unsigned CountResultNumOperands(StringRef AsmString) { 690 unsigned NumOps = 0; 691 std::pair<StringRef, StringRef> ASM = AsmString.split('\t'); 692 693 if (!ASM.second.empty()) { 694 size_t I = ASM.second.find('{'); 695 StringRef Str = ASM.second; 696 if (I != StringRef::npos) 697 Str = ASM.second.substr(I, ASM.second.find('|', I)); 698 699 ASM = Str.split(' '); 700 701 do { 702 ++NumOps; 703 ASM = ASM.second.split(' '); 704 } while (!ASM.second.empty()); 705 } 706 707 return NumOps; 708 } 709 710 void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { 711 CodeGenTarget Target(Records); 712 Record *AsmWriter = Target.getAsmWriter(); 713 714 if (!AsmWriter->getValueAsBit("isMCAsmWriter")) 715 return; 716 717 O << "\n#ifdef PRINT_ALIAS_INSTR\n"; 718 O << "#undef PRINT_ALIAS_INSTR\n\n"; 719 720 // Emit the method that prints the alias instruction. 721 std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 722 723 std::vector<Record*> AllInstAliases = 724 Records.getAllDerivedDefinitions("InstAlias"); 725 726 // Create a map from the qualified name to a list of potential matches. 727 std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap; 728 for (std::vector<Record*>::iterator 729 I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { 730 CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); 731 const Record *R = *I; 732 if (!R->getValueAsBit("EmitAlias")) 733 continue; // We were told not to emit the alias, but to emit the aliasee. 734 const DagInit *DI = R->getValueAsDag("ResultInst"); 735 const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator()); 736 AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); 737 } 738 739 // A map of which conditions need to be met for each instruction operand 740 // before it can be matched to the mnemonic. 741 std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap; 742 743 for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator 744 I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { 745 std::vector<CodeGenInstAlias*> &Aliases = I->second; 746 747 for (std::vector<CodeGenInstAlias*>::iterator 748 II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { 749 const CodeGenInstAlias *CGA = *II; 750 unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); 751 unsigned NumResultOps = 752 CountResultNumOperands(CGA->ResultInst->AsmString); 753 754 // Don't emit the alias if it has more operands than what it's aliasing. 755 if (NumResultOps < CountNumOperands(CGA->AsmString)) 756 continue; 757 758 IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(), 759 CGA->AsmString); 760 761 std::string Cond; 762 Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo); 763 IAP->addCond(Cond); 764 765 std::map<StringRef, unsigned> OpMap; 766 bool CantHandle = false; 767 768 for (unsigned i = 0, e = LastOpNo; i != e; ++i) { 769 const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i]; 770 771 switch (RO.Kind) { 772 case CodeGenInstAlias::ResultOperand::K_Record: { 773 const Record *Rec = RO.getRecord(); 774 StringRef ROName = RO.getName(); 775 776 777 if (Rec->isSubClassOf("RegisterOperand")) 778 Rec = Rec->getValueAsDef("RegClass"); 779 if (Rec->isSubClassOf("RegisterClass")) { 780 Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()"; 781 IAP->addCond(Cond); 782 783 if (!IAP->isOpMapped(ROName)) { 784 IAP->addOperand(ROName, i); 785 Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" + 786 CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)" 787 ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())"; 788 IAP->addCond(Cond); 789 } else { 790 Cond = std::string("MI->getOperand(") + 791 llvm::utostr(i) + ").getReg() == MI->getOperand(" + 792 llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()"; 793 IAP->addCond(Cond); 794 } 795 } else { 796 assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 797 // FIXME: We may need to handle these situations. 798 delete IAP; 799 IAP = 0; 800 CantHandle = true; 801 break; 802 } 803 804 break; 805 } 806 case CodeGenInstAlias::ResultOperand::K_Imm: 807 Cond = std::string("MI->getOperand(") + 808 llvm::utostr(i) + ").getImm() == " + 809 llvm::utostr(CGA->ResultOperands[i].getImm()); 810 IAP->addCond(Cond); 811 break; 812 case CodeGenInstAlias::ResultOperand::K_Reg: 813 // If this is zero_reg, something's playing tricks we're not 814 // equipped to handle. 815 if (!CGA->ResultOperands[i].getRegister()) { 816 CantHandle = true; 817 break; 818 } 819 820 Cond = std::string("MI->getOperand(") + 821 llvm::utostr(i) + ").getReg() == " + Target.getName() + 822 "::" + CGA->ResultOperands[i].getRegister()->getName(); 823 IAP->addCond(Cond); 824 break; 825 } 826 827 if (!IAP) break; 828 } 829 830 if (CantHandle) continue; 831 IAPrinterMap[I->first].push_back(IAP); 832 } 833 } 834 835 std::string Header; 836 raw_string_ostream HeaderO(Header); 837 838 HeaderO << "bool " << Target.getName() << ClassName 839 << "::printAliasInstr(const MCInst" 840 << " *MI, raw_ostream &OS) {\n"; 841 842 std::string Cases; 843 raw_string_ostream CasesO(Cases); 844 845 for (std::map<std::string, std::vector<IAPrinter*> >::iterator 846 I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) { 847 std::vector<IAPrinter*> &IAPs = I->second; 848 std::vector<IAPrinter*> UniqueIAPs; 849 850 for (std::vector<IAPrinter*>::iterator 851 II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) { 852 IAPrinter *LHS = *II; 853 bool IsDup = false; 854 for (std::vector<IAPrinter*>::iterator 855 III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) { 856 IAPrinter *RHS = *III; 857 if (LHS != RHS && *LHS == *RHS) { 858 IsDup = true; 859 break; 860 } 861 } 862 863 if (!IsDup) UniqueIAPs.push_back(LHS); 864 } 865 866 if (UniqueIAPs.empty()) continue; 867 868 CasesO.indent(2) << "case " << I->first << ":\n"; 869 870 for (std::vector<IAPrinter*>::iterator 871 II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) { 872 IAPrinter *IAP = *II; 873 CasesO.indent(4); 874 IAP->print(CasesO); 875 CasesO << '\n'; 876 } 877 878 CasesO.indent(4) << "return false;\n"; 879 } 880 881 if (CasesO.str().empty()) { 882 O << HeaderO.str(); 883 O << " return false;\n"; 884 O << "}\n\n"; 885 O << "#endif // PRINT_ALIAS_INSTR\n"; 886 return; 887 } 888 889 EmitGetMapOperandNumber(O); 890 891 O << HeaderO.str(); 892 O.indent(2) << "StringRef AsmString;\n"; 893 O.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n"; 894 O.indent(2) << "switch (MI->getOpcode()) {\n"; 895 O.indent(2) << "default: return false;\n"; 896 O << CasesO.str(); 897 O.indent(2) << "}\n\n"; 898 899 // Code that prints the alias, replacing the operands with the ones from the 900 // MCInst. 901 O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n"; 902 O << " OS << '\\t' << ASM.first;\n"; 903 904 O << " if (!ASM.second.empty()) {\n"; 905 O << " OS << '\\t';\n"; 906 O << " for (StringRef::iterator\n"; 907 O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n"; 908 O << " if (*I == '$') {\n"; 909 O << " StringRef::iterator Start = ++I;\n"; 910 O << " while (I != E &&\n"; 911 O << " ((*I >= 'a' && *I <= 'z') ||\n"; 912 O << " (*I >= 'A' && *I <= 'Z') ||\n"; 913 O << " (*I >= '0' && *I <= '9') ||\n"; 914 O << " *I == '_'))\n"; 915 O << " ++I;\n"; 916 O << " StringRef Name(Start, I - Start);\n"; 917 O << " printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n"; 918 O << " } else {\n"; 919 O << " OS << *I++;\n"; 920 O << " }\n"; 921 O << " }\n"; 922 O << " }\n\n"; 923 924 O << " return true;\n"; 925 O << "}\n\n"; 926 927 O << "#endif // PRINT_ALIAS_INSTR\n"; 928 } 929 930 void AsmWriterEmitter::run(raw_ostream &O) { 931 EmitSourceFileHeader("Assembly Writer Source Fragment", O); 932 933 EmitPrintInstruction(O); 934 EmitGetRegisterName(O); 935 EmitPrintAliasInstruction(O); 936 } 937 938