PPCAsmPrinter.cpp revision 2ead458ae8423d6ecaec7cbd45e1e2c71ce9e618
1//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// 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 file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to PowerPC assembly language. This printer is 12// the output mechanism used by `llc'. 13// 14// Documentation at http://developer.apple.com/documentation/DeveloperTools/ 15// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 16// 17//===----------------------------------------------------------------------===// 18 19#define DEBUG_TYPE "asmprinter" 20#include "PPC.h" 21#include "PPCPredicates.h" 22#include "PPCTargetMachine.h" 23#include "PPCSubtarget.h" 24#include "llvm/Analysis/DebugInfo.h" 25#include "llvm/Constants.h" 26#include "llvm/DerivedTypes.h" 27#include "llvm/Module.h" 28#include "llvm/Assembly/Writer.h" 29#include "llvm/CodeGen/AsmPrinter.h" 30#include "llvm/CodeGen/MachineFunctionPass.h" 31#include "llvm/CodeGen/MachineInstr.h" 32#include "llvm/CodeGen/MachineInstrBuilder.h" 33#include "llvm/CodeGen/MachineModuleInfoImpls.h" 34#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 35#include "llvm/MC/MCAsmInfo.h" 36#include "llvm/MC/MCContext.h" 37#include "llvm/MC/MCExpr.h" 38#include "llvm/MC/MCInst.h" 39#include "llvm/MC/MCSectionMachO.h" 40#include "llvm/MC/MCStreamer.h" 41#include "llvm/MC/MCSymbol.h" 42#include "llvm/Target/Mangler.h" 43#include "llvm/Target/TargetRegisterInfo.h" 44#include "llvm/Target/TargetInstrInfo.h" 45#include "llvm/Target/TargetOptions.h" 46#include "llvm/Target/TargetRegistry.h" 47#include "llvm/Support/CommandLine.h" 48#include "llvm/Support/Debug.h" 49#include "llvm/Support/MathExtras.h" 50#include "llvm/Support/ErrorHandling.h" 51#include "llvm/Support/raw_ostream.h" 52#include "llvm/ADT/StringExtras.h" 53#include "llvm/ADT/StringSet.h" 54#include "llvm/ADT/SmallString.h" 55#include "InstPrinter/PPCInstPrinter.h" 56using namespace llvm; 57 58// This option tells the asmprinter to use the new (experimental) MCInstPrinter 59// path. 60static cl::opt<bool> UseInstPrinter("enable-ppc-inst-printer", 61 cl::ReallyHidden 62 //, cl::init(true) 63 ); 64 65namespace { 66 class PPCAsmPrinter : public AsmPrinter { 67 protected: 68 DenseMap<MCSymbol*, MCSymbol*> TOC; 69 const PPCSubtarget &Subtarget; 70 uint64_t LabelID; 71 public: 72 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 73 : AsmPrinter(TM, Streamer), 74 Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {} 75 76 virtual const char *getPassName() const { 77 return "PowerPC Assembly Printer"; 78 } 79 80 unsigned enumRegToMachineReg(unsigned enumReg) { 81 switch (enumReg) { 82 default: llvm_unreachable("Unhandled register!"); 83 case PPC::CR0: return 0; 84 case PPC::CR1: return 1; 85 case PPC::CR2: return 2; 86 case PPC::CR3: return 3; 87 case PPC::CR4: return 4; 88 case PPC::CR5: return 5; 89 case PPC::CR6: return 6; 90 case PPC::CR7: return 7; 91 } 92 llvm_unreachable(0); 93 } 94 95 /// printInstruction - This method is automatically generated by tablegen 96 /// from the instruction set description. This method returns true if the 97 /// machine instruction was sufficiently described to print it, otherwise it 98 /// returns false. 99 void printInstruction(const MachineInstr *MI, raw_ostream &O); 100 static const char *getRegisterName(unsigned RegNo); 101 102 103 virtual void EmitInstruction(const MachineInstr *MI); 104 void printOp(const MachineOperand &MO, raw_ostream &O); 105 106 /// stripRegisterPrefix - This method strips the character prefix from a 107 /// register name so that only the number is left. Used by for linux asm. 108 const char *stripRegisterPrefix(const char *RegName) { 109 switch (RegName[0]) { 110 case 'r': 111 case 'f': 112 case 'v': return RegName + 1; 113 case 'c': if (RegName[1] == 'r') return RegName + 2; 114 } 115 116 return RegName; 117 } 118 119 /// printRegister - Print register according to target requirements. 120 /// 121 void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){ 122 unsigned RegNo = MO.getReg(); 123 assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); 124 125 // If we should use 0 for R0. 126 if (R0AsZero && RegNo == PPC::R0) { 127 O << "0"; 128 return; 129 } 130 131 const char *RegName = getRegisterName(RegNo); 132 // Linux assembler (Others?) does not take register mnemonics. 133 // FIXME - What about special registers used in mfspr/mtspr? 134 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 135 O << RegName; 136 } 137 138 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 139 const MachineOperand &MO = MI->getOperand(OpNo); 140 if (MO.isReg()) { 141 printRegister(MO, false, O); 142 } else if (MO.isImm()) { 143 O << MO.getImm(); 144 } else { 145 printOp(MO, O); 146 } 147 } 148 149 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 150 unsigned AsmVariant, const char *ExtraCode, 151 raw_ostream &O); 152 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 153 unsigned AsmVariant, const char *ExtraCode, 154 raw_ostream &O); 155 156 157 void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo, 158 raw_ostream &O) { 159 char value = MI->getOperand(OpNo).getImm(); 160 value = (value << (32-5)) >> (32-5); 161 O << (int)value; 162 } 163 void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo, 164 raw_ostream &O) { 165 unsigned char value = MI->getOperand(OpNo).getImm(); 166 assert(value <= 31 && "Invalid u5imm argument!"); 167 O << (unsigned int)value; 168 } 169 void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo, 170 raw_ostream &O) { 171 unsigned char value = MI->getOperand(OpNo).getImm(); 172 assert(value <= 63 && "Invalid u6imm argument!"); 173 O << (unsigned int)value; 174 } 175 void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, 176 raw_ostream &O) { 177 O << (short)MI->getOperand(OpNo).getImm(); 178 } 179 void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo, 180 raw_ostream &O) { 181 O << (unsigned short)MI->getOperand(OpNo).getImm(); 182 } 183 void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo, 184 raw_ostream &O) { 185 if (MI->getOperand(OpNo).isImm()) { 186 O << (short)(MI->getOperand(OpNo).getImm()*4); 187 } else { 188 O << "lo16("; 189 printOp(MI->getOperand(OpNo), O); 190 if (TM.getRelocationModel() == Reloc::PIC_) 191 O << "-\"L" << getFunctionNumber() << "$pb\")"; 192 else 193 O << ')'; 194 } 195 } 196 void printBranchOperand(const MachineInstr *MI, unsigned OpNo, 197 raw_ostream &O) { 198 // Branches can take an immediate operand. This is used by the branch 199 // selection pass to print $+8, an eight byte displacement from the PC. 200 if (MI->getOperand(OpNo).isImm()) { 201 O << "$+" << MI->getOperand(OpNo).getImm()*4; 202 } else { 203 printOp(MI->getOperand(OpNo), O); 204 } 205 } 206 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 207 raw_ostream &O) { 208 const MachineOperand &MO = MI->getOperand(OpNo); 209 if (TM.getRelocationModel() != Reloc::Static) { 210 if (MO.isGlobal()) { 211 const GlobalValue *GV = MO.getGlobal(); 212 if (GV->isDeclaration() || GV->isWeakForLinker()) { 213 // Dynamically-resolved functions need a stub for the function. 214 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); 215 MachineModuleInfoImpl::StubValueTy &StubSym = 216 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 217 if (StubSym.getPointer() == 0) 218 StubSym = MachineModuleInfoImpl:: 219 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 220 O << *Sym; 221 return; 222 } 223 } 224 if (MO.isSymbol()) { 225 SmallString<128> TempNameStr; 226 TempNameStr += StringRef(MO.getSymbolName()); 227 TempNameStr += StringRef("$stub"); 228 229 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); 230 MachineModuleInfoImpl::StubValueTy &StubSym = 231 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 232 if (StubSym.getPointer() == 0) 233 StubSym = MachineModuleInfoImpl:: 234 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 235 O << *Sym; 236 return; 237 } 238 } 239 240 printOp(MI->getOperand(OpNo), O); 241 } 242 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, 243 raw_ostream &O) { 244 O << (int)MI->getOperand(OpNo).getImm()*4; 245 } 246 void printPICLabel(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 247 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 248 O << "\"L" << getFunctionNumber() << "$pb\":"; 249 } 250 void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 251 if (MI->getOperand(OpNo).isImm()) { 252 printS16ImmOperand(MI, OpNo, O); 253 } else { 254 if (Subtarget.isDarwin()) O << "ha16("; 255 printOp(MI->getOperand(OpNo), O); 256 if (TM.getRelocationModel() == Reloc::PIC_) 257 O << "-\"L" << getFunctionNumber() << "$pb\""; 258 if (Subtarget.isDarwin()) 259 O << ')'; 260 else 261 O << "@ha"; 262 } 263 } 264 void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 265 if (MI->getOperand(OpNo).isImm()) { 266 printS16ImmOperand(MI, OpNo, O); 267 } else { 268 if (Subtarget.isDarwin()) O << "lo16("; 269 printOp(MI->getOperand(OpNo), O); 270 if (TM.getRelocationModel() == Reloc::PIC_) 271 O << "-\"L" << getFunctionNumber() << "$pb\""; 272 if (Subtarget.isDarwin()) 273 O << ')'; 274 else 275 O << "@l"; 276 } 277 } 278 void printcrbitm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 279 unsigned CCReg = MI->getOperand(OpNo).getReg(); 280 unsigned RegNo = enumRegToMachineReg(CCReg); 281 O << (0x80 >> RegNo); 282 } 283 // The new addressing mode printers. 284 void printMemRegImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 285 printSymbolLo(MI, OpNo, O); 286 O << '('; 287 if (MI->getOperand(OpNo+1).isReg() && 288 MI->getOperand(OpNo+1).getReg() == PPC::R0) 289 O << "0"; 290 else 291 printOperand(MI, OpNo+1, O); 292 O << ')'; 293 } 294 void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo, 295 raw_ostream &O) { 296 if (MI->getOperand(OpNo).isImm()) 297 printS16X4ImmOperand(MI, OpNo, O); 298 else 299 printSymbolLo(MI, OpNo, O); 300 O << '('; 301 if (MI->getOperand(OpNo+1).isReg() && 302 MI->getOperand(OpNo+1).getReg() == PPC::R0) 303 O << "0"; 304 else 305 printOperand(MI, OpNo+1, O); 306 O << ')'; 307 } 308 309 void printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 310 // When used as the base register, r0 reads constant zero rather than 311 // the value contained in the register. For this reason, the darwin 312 // assembler requires that we print r0 as 0 (no r) when used as the base. 313 const MachineOperand &MO = MI->getOperand(OpNo); 314 printRegister(MO, true, O); 315 O << ", "; 316 printOperand(MI, OpNo+1, O); 317 } 318 319 void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo, 320 raw_ostream &O) { 321 const MachineOperand &MO = MI->getOperand(OpNo); 322 assert(MO.isGlobal()); 323 MCSymbol *Sym = Mang->getSymbol(MO.getGlobal()); 324 325 // Map symbol -> label of TOC entry. 326 MCSymbol *&TOCEntry = TOC[Sym]; 327 if (TOCEntry == 0) 328 TOCEntry = OutContext. 329 GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) + 330 "C" + Twine(LabelID++)); 331 332 O << *TOCEntry << "@toc"; 333 } 334 335 void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 336 raw_ostream &O, const char *Modifier); 337 338 MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 339 340 MachineLocation Location; 341 assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 342 // Frame address. Currently handles register +- offset only. 343 if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm()) 344 Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm()); 345 else { 346 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 347 } 348 return Location; 349 } 350 }; 351 352 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 353 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 354 public: 355 explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 356 : PPCAsmPrinter(TM, Streamer) {} 357 358 virtual const char *getPassName() const { 359 return "Linux PPC Assembly Printer"; 360 } 361 362 bool doFinalization(Module &M); 363 364 virtual void EmitFunctionEntryLabel(); 365 }; 366 367 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 368 /// OS X 369 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 370 public: 371 explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 372 : PPCAsmPrinter(TM, Streamer) {} 373 374 virtual const char *getPassName() const { 375 return "Darwin PPC Assembly Printer"; 376 } 377 378 bool doFinalization(Module &M); 379 void EmitStartOfAsmFile(Module &M); 380 381 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 382 }; 383} // end of anonymous namespace 384 385// Include the auto-generated portion of the assembly writer 386#include "PPCGenAsmWriter.inc" 387 388void PPCAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { 389 switch (MO.getType()) { 390 case MachineOperand::MO_Immediate: 391 llvm_unreachable("printOp() does not handle immediate values"); 392 393 case MachineOperand::MO_MachineBasicBlock: 394 O << *MO.getMBB()->getSymbol(); 395 return; 396 case MachineOperand::MO_JumpTableIndex: 397 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 398 << '_' << MO.getIndex(); 399 // FIXME: PIC relocation model 400 return; 401 case MachineOperand::MO_ConstantPoolIndex: 402 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 403 << '_' << MO.getIndex(); 404 return; 405 case MachineOperand::MO_BlockAddress: 406 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 407 return; 408 case MachineOperand::MO_ExternalSymbol: { 409 // Computing the address of an external symbol, not calling it. 410 if (TM.getRelocationModel() == Reloc::Static) { 411 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 412 return; 413 } 414 415 MCSymbol *NLPSym = 416 OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+ 417 MO.getSymbolName()+"$non_lazy_ptr"); 418 MachineModuleInfoImpl::StubValueTy &StubSym = 419 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym); 420 if (StubSym.getPointer() == 0) 421 StubSym = MachineModuleInfoImpl:: 422 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 423 424 O << *NLPSym; 425 return; 426 } 427 case MachineOperand::MO_GlobalAddress: { 428 // Computing the address of a global symbol, not calling it. 429 const GlobalValue *GV = MO.getGlobal(); 430 MCSymbol *SymToPrint; 431 432 // External or weakly linked global variables need non-lazily-resolved stubs 433 if (TM.getRelocationModel() != Reloc::Static && 434 (GV->isDeclaration() || GV->isWeakForLinker())) { 435 if (!GV->hasHiddenVisibility()) { 436 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 437 MachineModuleInfoImpl::StubValueTy &StubSym = 438 MMI->getObjFileInfo<MachineModuleInfoMachO>() 439 .getGVStubEntry(SymToPrint); 440 if (StubSym.getPointer() == 0) 441 StubSym = MachineModuleInfoImpl:: 442 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 443 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 444 GV->hasAvailableExternallyLinkage()) { 445 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 446 447 MachineModuleInfoImpl::StubValueTy &StubSym = 448 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 449 getHiddenGVStubEntry(SymToPrint); 450 if (StubSym.getPointer() == 0) 451 StubSym = MachineModuleInfoImpl:: 452 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 453 } else { 454 SymToPrint = Mang->getSymbol(GV); 455 } 456 } else { 457 SymToPrint = Mang->getSymbol(GV); 458 } 459 460 O << *SymToPrint; 461 462 printOffset(MO.getOffset(), O); 463 return; 464 } 465 466 default: 467 O << "<unknown operand type: " << MO.getType() << ">"; 468 return; 469 } 470} 471 472/// PrintAsmOperand - Print out an operand for an inline asm expression. 473/// 474bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 475 unsigned AsmVariant, 476 const char *ExtraCode, raw_ostream &O) { 477 // Does this asm operand have a single letter operand modifier? 478 if (ExtraCode && ExtraCode[0]) { 479 if (ExtraCode[1] != 0) return true; // Unknown modifier. 480 481 switch (ExtraCode[0]) { 482 default: return true; // Unknown modifier. 483 case 'c': // Don't print "$" before a global var name or constant. 484 // PPC never has a prefix. 485 printOperand(MI, OpNo, O); 486 return false; 487 case 'L': // Write second word of DImode reference. 488 // Verify that this operand has two consecutive registers. 489 if (!MI->getOperand(OpNo).isReg() || 490 OpNo+1 == MI->getNumOperands() || 491 !MI->getOperand(OpNo+1).isReg()) 492 return true; 493 ++OpNo; // Return the high-part. 494 break; 495 case 'I': 496 // Write 'i' if an integer constant, otherwise nothing. Used to print 497 // addi vs add, etc. 498 if (MI->getOperand(OpNo).isImm()) 499 O << "i"; 500 return false; 501 } 502 } 503 504 printOperand(MI, OpNo, O); 505 return false; 506} 507 508// At the moment, all inline asm memory operands are a single register. 509// In any case, the output of this routine should always be just one 510// assembler operand. 511 512bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 513 unsigned AsmVariant, 514 const char *ExtraCode, 515 raw_ostream &O) { 516 if (ExtraCode && ExtraCode[0]) 517 return true; // Unknown modifier. 518 assert (MI->getOperand(OpNo).isReg()); 519 O << "0("; 520 printOperand(MI, OpNo, O); 521 O << ")"; 522 return false; 523} 524 525void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 526 raw_ostream &O, const char *Modifier){ 527 assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!"); 528 unsigned Code = MI->getOperand(OpNo).getImm(); 529 if (!strcmp(Modifier, "cc")) { 530 switch ((PPC::Predicate)Code) { 531 case PPC::PRED_ALWAYS: return; // Don't print anything for always. 532 case PPC::PRED_LT: O << "lt"; return; 533 case PPC::PRED_LE: O << "le"; return; 534 case PPC::PRED_EQ: O << "eq"; return; 535 case PPC::PRED_GE: O << "ge"; return; 536 case PPC::PRED_GT: O << "gt"; return; 537 case PPC::PRED_NE: O << "ne"; return; 538 case PPC::PRED_UN: O << "un"; return; 539 case PPC::PRED_NU: O << "nu"; return; 540 } 541 542 } else { 543 assert(!strcmp(Modifier, "reg") && 544 "Need to specify 'cc' or 'reg' as predicate op modifier!"); 545 // Don't print the register for 'always'. 546 if (Code == PPC::PRED_ALWAYS) return; 547 printOperand(MI, OpNo+1, O); 548 } 549} 550 551 552/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 553/// the current output stream. 554/// 555void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 556 if (UseInstPrinter) { 557 MCInst TmpInst; 558 559 // Lower multi-instruction pseudo operations. 560 switch (MI->getOpcode()) { 561 default: break; 562 563 case PPC::MFCRpseud: 564 // Transform: %R3 = MFCRpseud %CR7 565 // Into: %R3 = MFCR ;; cr7 566 OutStreamer.AddComment(getRegisterName(MI->getOperand(1).getReg())); 567 TmpInst.setOpcode(PPC::MFCR); 568 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 569 OutStreamer.EmitInstruction(TmpInst); 570 return; 571 } 572 573 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 574 OutStreamer.EmitInstruction(TmpInst); 575 return; 576 } 577 578 579 SmallString<128> Str; 580 raw_svector_ostream O(Str); 581 582 if (MI->getOpcode() == TargetOpcode::DBG_VALUE) { 583 unsigned NOps = MI->getNumOperands(); 584 assert(NOps==4); 585 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 586 // cast away const; DIetc do not take const operands for some reason. 587 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 588 O << V.getName(); 589 O << " <- "; 590 // Frame address. Currently handles register +- offset only. 591 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 592 O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O); 593 O << ']'; 594 O << "+"; 595 printOperand(MI, NOps-2, O); 596 OutStreamer.EmitRawText(O.str()); 597 return; 598 } 599 // Check for slwi/srwi mnemonics. 600 if (MI->getOpcode() == PPC::RLWINM) { 601 unsigned char SH = MI->getOperand(2).getImm(); 602 unsigned char MB = MI->getOperand(3).getImm(); 603 unsigned char ME = MI->getOperand(4).getImm(); 604 bool useSubstituteMnemonic = false; 605 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 606 O << "\tslwi "; useSubstituteMnemonic = true; 607 } 608 if (SH <= 31 && MB == (32-SH) && ME == 31) { 609 O << "\tsrwi "; useSubstituteMnemonic = true; 610 SH = 32-SH; 611 } 612 if (useSubstituteMnemonic) { 613 printOperand(MI, 0, O); 614 O << ", "; 615 printOperand(MI, 1, O); 616 O << ", " << (unsigned int)SH; 617 OutStreamer.EmitRawText(O.str()); 618 return; 619 } 620 } 621 622 if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && 623 MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 624 O << "\tmr "; 625 printOperand(MI, 0, O); 626 O << ", "; 627 printOperand(MI, 1, O); 628 OutStreamer.EmitRawText(O.str()); 629 return; 630 } 631 632 if (MI->getOpcode() == PPC::RLDICR) { 633 unsigned char SH = MI->getOperand(2).getImm(); 634 unsigned char ME = MI->getOperand(3).getImm(); 635 // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 636 if (63-SH == ME) { 637 O << "\tsldi "; 638 printOperand(MI, 0, O); 639 O << ", "; 640 printOperand(MI, 1, O); 641 O << ", " << (unsigned int)SH; 642 OutStreamer.EmitRawText(O.str()); 643 return; 644 } 645 } 646 647 printInstruction(MI, O); 648 OutStreamer.EmitRawText(O.str()); 649} 650 651void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 652 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 653 return AsmPrinter::EmitFunctionEntryLabel(); 654 655 // Emit an official procedure descriptor. 656 // FIXME 64-bit SVR4: Use MCSection here! 657 OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\"")); 658 OutStreamer.EmitRawText(StringRef("\t.align 3")); 659 OutStreamer.EmitLabel(CurrentFnSym); 660 OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) + 661 ",.TOC.@tocbase"); 662 OutStreamer.EmitRawText(StringRef("\t.previous")); 663 OutStreamer.EmitRawText(".L." + Twine(CurrentFnSym->getName()) + ":"); 664} 665 666 667bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 668 const TargetData *TD = TM.getTargetData(); 669 670 bool isPPC64 = TD->getPointerSizeInBits() == 64; 671 672 if (isPPC64 && !TOC.empty()) { 673 // FIXME 64-bit SVR4: Use MCSection here? 674 OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\"")); 675 676 // FIXME: This is nondeterminstic! 677 for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 678 E = TOC.end(); I != E; ++I) { 679 OutStreamer.EmitLabel(I->second); 680 OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) + 681 "[TC]," + I->first->getName()); 682 } 683 } 684 685 return AsmPrinter::doFinalization(M); 686} 687 688void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 689 static const char *const CPUDirectives[] = { 690 "", 691 "ppc", 692 "ppc601", 693 "ppc602", 694 "ppc603", 695 "ppc7400", 696 "ppc750", 697 "ppc970", 698 "ppc64" 699 }; 700 701 unsigned Directive = Subtarget.getDarwinDirective(); 702 if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970) 703 Directive = PPC::DIR_970; 704 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 705 Directive = PPC::DIR_7400; 706 if (Subtarget.isPPC64() && Directive < PPC::DIR_970) 707 Directive = PPC::DIR_64; 708 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 709 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 710 711 // Prime text sections so they are adjacent. This reduces the likelihood a 712 // large data or debug section causes a branch to exceed 16M limit. 713 const TargetLoweringObjectFileMachO &TLOFMacho = 714 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 715 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 716 if (TM.getRelocationModel() == Reloc::PIC_) { 717 OutStreamer.SwitchSection( 718 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 719 MCSectionMachO::S_SYMBOL_STUBS | 720 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 721 32, SectionKind::getText())); 722 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 723 OutStreamer.SwitchSection( 724 OutContext.getMachOSection("__TEXT","__symbol_stub1", 725 MCSectionMachO::S_SYMBOL_STUBS | 726 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 727 16, SectionKind::getText())); 728 } 729 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 730} 731 732static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 733 // Remove $stub suffix, add $lazy_ptr. 734 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5); 735 TmpStr += "$lazy_ptr"; 736 return Ctx.GetOrCreateSymbol(TmpStr.str()); 737} 738 739static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 740 // Add $tmp suffix to $stub, yielding $stub$tmp. 741 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()); 742 TmpStr += "$tmp"; 743 return Ctx.GetOrCreateSymbol(TmpStr.str()); 744} 745 746void PPCDarwinAsmPrinter:: 747EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 748 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 749 750 const TargetLoweringObjectFileMachO &TLOFMacho = 751 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 752 753 // .lazy_symbol_pointer 754 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 755 756 // Output stubs for dynamically-linked functions 757 if (TM.getRelocationModel() == Reloc::PIC_) { 758 const MCSection *StubSection = 759 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 760 MCSectionMachO::S_SYMBOL_STUBS | 761 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 762 32, SectionKind::getText()); 763 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 764 OutStreamer.SwitchSection(StubSection); 765 EmitAlignment(4); 766 767 MCSymbol *Stub = Stubs[i].first; 768 MCSymbol *RawSym = Stubs[i].second.getPointer(); 769 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 770 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 771 772 OutStreamer.EmitLabel(Stub); 773 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 774 // FIXME: MCize this. 775 OutStreamer.EmitRawText(StringRef("\tmflr r0")); 776 OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName())); 777 OutStreamer.EmitLabel(AnonSymbol); 778 OutStreamer.EmitRawText(StringRef("\tmflr r11")); 779 OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+ 780 "-" + AnonSymbol->getName() + ")"); 781 OutStreamer.EmitRawText(StringRef("\tmtlr r0")); 782 783 if (isPPC64) 784 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 785 "-" + AnonSymbol->getName() + ")(r11)"); 786 else 787 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 788 "-" + AnonSymbol->getName() + ")(r11)"); 789 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 790 OutStreamer.EmitRawText(StringRef("\tbctr")); 791 792 OutStreamer.SwitchSection(LSPSection); 793 OutStreamer.EmitLabel(LazyPtr); 794 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 795 796 if (isPPC64) 797 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 798 else 799 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 800 } 801 OutStreamer.AddBlankLine(); 802 return; 803 } 804 805 const MCSection *StubSection = 806 OutContext.getMachOSection("__TEXT","__symbol_stub1", 807 MCSectionMachO::S_SYMBOL_STUBS | 808 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 809 16, SectionKind::getText()); 810 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 811 MCSymbol *Stub = Stubs[i].first; 812 MCSymbol *RawSym = Stubs[i].second.getPointer(); 813 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 814 815 OutStreamer.SwitchSection(StubSection); 816 EmitAlignment(4); 817 OutStreamer.EmitLabel(Stub); 818 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 819 OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")"); 820 if (isPPC64) 821 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 822 ")(r11)"); 823 else 824 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 825 ")(r11)"); 826 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 827 OutStreamer.EmitRawText(StringRef("\tbctr")); 828 OutStreamer.SwitchSection(LSPSection); 829 OutStreamer.EmitLabel(LazyPtr); 830 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 831 832 if (isPPC64) 833 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 834 else 835 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 836 } 837 838 OutStreamer.AddBlankLine(); 839} 840 841 842bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 843 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 844 845 // Darwin/PPC always uses mach-o. 846 const TargetLoweringObjectFileMachO &TLOFMacho = 847 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 848 MachineModuleInfoMachO &MMIMacho = 849 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 850 851 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 852 if (!Stubs.empty()) 853 EmitFunctionStubs(Stubs); 854 855 if (MAI->doesSupportExceptionHandling() && MMI) { 856 // Add the (possibly multiple) personalities to the set of global values. 857 // Only referenced functions get into the Personalities list. 858 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 859 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 860 E = Personalities.end(); I != E; ++I) { 861 if (*I) { 862 MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 863 MachineModuleInfoImpl::StubValueTy &StubSym = 864 MMIMacho.getGVStubEntry(NLPSym); 865 StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true); 866 } 867 } 868 } 869 870 // Output stubs for dynamically-linked functions. 871 Stubs = MMIMacho.GetGVStubList(); 872 873 // Output macho stubs for external and common global variables. 874 if (!Stubs.empty()) { 875 // Switch with ".non_lazy_symbol_pointer" directive. 876 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 877 EmitAlignment(isPPC64 ? 3 : 2); 878 879 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 880 // L_foo$stub: 881 OutStreamer.EmitLabel(Stubs[i].first); 882 // .indirect_symbol _foo 883 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 884 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 885 886 if (MCSym.getInt()) 887 // External to current translation unit. 888 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 889 else 890 // Internal to current translation unit. 891 // 892 // When we place the LSDA into the TEXT section, the type info pointers 893 // need to be indirect and pc-rel. We accomplish this by using NLPs. 894 // However, sometimes the types are local to the file. So we need to 895 // fill in the value for the NLP in those cases. 896 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 897 OutContext), 898 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 899 } 900 901 Stubs.clear(); 902 OutStreamer.AddBlankLine(); 903 } 904 905 Stubs = MMIMacho.GetHiddenGVStubList(); 906 if (!Stubs.empty()) { 907 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 908 EmitAlignment(isPPC64 ? 3 : 2); 909 910 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 911 // L_foo$stub: 912 OutStreamer.EmitLabel(Stubs[i].first); 913 // .long _foo 914 OutStreamer.EmitValue(MCSymbolRefExpr:: 915 Create(Stubs[i].second.getPointer(), 916 OutContext), 917 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 918 } 919 920 Stubs.clear(); 921 OutStreamer.AddBlankLine(); 922 } 923 924 // Funny Darwin hack: This flag tells the linker that no global symbols 925 // contain code that falls through to other global symbols (e.g. the obvious 926 // implementation of multiple entry points). If this doesn't occur, the 927 // linker can safely perform dead code stripping. Since LLVM never generates 928 // code that does this, it is always safe to set. 929 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 930 931 return AsmPrinter::doFinalization(M); 932} 933 934/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 935/// for a MachineFunction to the given output stream, in a format that the 936/// Darwin assembler can deal with. 937/// 938static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 939 MCStreamer &Streamer) { 940 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 941 942 if (Subtarget->isDarwin()) 943 return new PPCDarwinAsmPrinter(tm, Streamer); 944 return new PPCLinuxAsmPrinter(tm, Streamer); 945} 946 947static MCInstPrinter *createPPCMCInstPrinter(const Target &T, 948 unsigned SyntaxVariant, 949 const MCAsmInfo &MAI) { 950 return new PPCInstPrinter(MAI, SyntaxVariant); 951} 952 953 954// Force static initialization. 955extern "C" void LLVMInitializePowerPCAsmPrinter() { 956 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 957 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 958 959 TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); 960 TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); 961} 962