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