PPCAsmPrinter.cpp revision 349c2787cf9e174c8aa955bf8e3b09a405b2aece
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 "InstPrinter/PPCInstPrinter.h" 22#include "MCTargetDesc/PPCPredicates.h" 23#include "PPCSubtarget.h" 24#include "PPCTargetMachine.h" 25#include "llvm/ADT/MapVector.h" 26#include "llvm/ADT/SmallString.h" 27#include "llvm/ADT/StringExtras.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/Constants.h" 36#include "llvm/DebugInfo.h" 37#include "llvm/DerivedTypes.h" 38#include "llvm/MC/MCAsmInfo.h" 39#include "llvm/MC/MCContext.h" 40#include "llvm/MC/MCExpr.h" 41#include "llvm/MC/MCInst.h" 42#include "llvm/MC/MCInstBuilder.h" 43#include "llvm/MC/MCSectionELF.h" 44#include "llvm/MC/MCSectionMachO.h" 45#include "llvm/MC/MCStreamer.h" 46#include "llvm/MC/MCSymbol.h" 47#include "llvm/Module.h" 48#include "llvm/Support/CommandLine.h" 49#include "llvm/Support/Debug.h" 50#include "llvm/Support/ELF.h" 51#include "llvm/Support/ErrorHandling.h" 52#include "llvm/Support/MathExtras.h" 53#include "llvm/Support/TargetRegistry.h" 54#include "llvm/Support/raw_ostream.h" 55#include "llvm/Target/Mangler.h" 56#include "llvm/Target/TargetInstrInfo.h" 57#include "llvm/Target/TargetOptions.h" 58#include "llvm/Target/TargetRegisterInfo.h" 59using namespace llvm; 60 61namespace { 62 class PPCAsmPrinter : public AsmPrinter { 63 protected: 64 MapVector<MCSymbol*, MCSymbol*> TOC; 65 const PPCSubtarget &Subtarget; 66 uint64_t TOCLabelID; 67 public: 68 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 69 : AsmPrinter(TM, Streamer), 70 Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {} 71 72 virtual const char *getPassName() const { 73 return "PowerPC Assembly Printer"; 74 } 75 76 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym); 77 78 virtual void EmitInstruction(const MachineInstr *MI); 79 80 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 81 82 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 83 unsigned AsmVariant, const char *ExtraCode, 84 raw_ostream &O); 85 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 86 unsigned AsmVariant, const char *ExtraCode, 87 raw_ostream &O); 88 89 MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 90 MachineLocation Location; 91 assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 92 // Frame address. Currently handles register +- offset only. 93 if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm()) 94 Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm()); 95 else { 96 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 97 } 98 return Location; 99 } 100 }; 101 102 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 103 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 104 public: 105 explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 106 : PPCAsmPrinter(TM, Streamer) {} 107 108 virtual const char *getPassName() const { 109 return "Linux PPC Assembly Printer"; 110 } 111 112 bool doFinalization(Module &M); 113 114 virtual void EmitFunctionEntryLabel(); 115 116 void EmitFunctionBodyEnd(); 117 }; 118 119 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 120 /// OS X 121 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 122 public: 123 explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 124 : PPCAsmPrinter(TM, Streamer) {} 125 126 virtual const char *getPassName() const { 127 return "Darwin PPC Assembly Printer"; 128 } 129 130 bool doFinalization(Module &M); 131 void EmitStartOfAsmFile(Module &M); 132 133 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 134 }; 135} // end of anonymous namespace 136 137/// stripRegisterPrefix - This method strips the character prefix from a 138/// register name so that only the number is left. Used by for linux asm. 139static const char *stripRegisterPrefix(const char *RegName) { 140 switch (RegName[0]) { 141 case 'r': 142 case 'f': 143 case 'v': return RegName + 1; 144 case 'c': if (RegName[1] == 'r') return RegName + 2; 145 } 146 147 return RegName; 148} 149 150void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 151 raw_ostream &O) { 152 const MachineOperand &MO = MI->getOperand(OpNo); 153 154 switch (MO.getType()) { 155 case MachineOperand::MO_Register: { 156 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 157 // Linux assembler (Others?) does not take register mnemonics. 158 // FIXME - What about special registers used in mfspr/mtspr? 159 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 160 O << RegName; 161 return; 162 } 163 case MachineOperand::MO_Immediate: 164 O << MO.getImm(); 165 return; 166 167 case MachineOperand::MO_MachineBasicBlock: 168 O << *MO.getMBB()->getSymbol(); 169 return; 170 case MachineOperand::MO_JumpTableIndex: 171 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 172 << '_' << MO.getIndex(); 173 // FIXME: PIC relocation model 174 return; 175 case MachineOperand::MO_ConstantPoolIndex: 176 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 177 << '_' << MO.getIndex(); 178 return; 179 case MachineOperand::MO_BlockAddress: 180 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 181 return; 182 case MachineOperand::MO_ExternalSymbol: { 183 // Computing the address of an external symbol, not calling it. 184 if (TM.getRelocationModel() == Reloc::Static) { 185 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 186 return; 187 } 188 189 MCSymbol *NLPSym = 190 OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+ 191 MO.getSymbolName()+"$non_lazy_ptr"); 192 MachineModuleInfoImpl::StubValueTy &StubSym = 193 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym); 194 if (StubSym.getPointer() == 0) 195 StubSym = MachineModuleInfoImpl:: 196 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 197 198 O << *NLPSym; 199 return; 200 } 201 case MachineOperand::MO_GlobalAddress: { 202 // Computing the address of a global symbol, not calling it. 203 const GlobalValue *GV = MO.getGlobal(); 204 MCSymbol *SymToPrint; 205 206 // External or weakly linked global variables need non-lazily-resolved stubs 207 if (TM.getRelocationModel() != Reloc::Static && 208 (GV->isDeclaration() || GV->isWeakForLinker())) { 209 if (!GV->hasHiddenVisibility()) { 210 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 211 MachineModuleInfoImpl::StubValueTy &StubSym = 212 MMI->getObjFileInfo<MachineModuleInfoMachO>() 213 .getGVStubEntry(SymToPrint); 214 if (StubSym.getPointer() == 0) 215 StubSym = MachineModuleInfoImpl:: 216 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 217 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 218 GV->hasAvailableExternallyLinkage()) { 219 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 220 221 MachineModuleInfoImpl::StubValueTy &StubSym = 222 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 223 getHiddenGVStubEntry(SymToPrint); 224 if (StubSym.getPointer() == 0) 225 StubSym = MachineModuleInfoImpl:: 226 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 227 } else { 228 SymToPrint = Mang->getSymbol(GV); 229 } 230 } else { 231 SymToPrint = Mang->getSymbol(GV); 232 } 233 234 O << *SymToPrint; 235 236 printOffset(MO.getOffset(), O); 237 return; 238 } 239 240 default: 241 O << "<unknown operand type: " << MO.getType() << ">"; 242 return; 243 } 244} 245 246/// PrintAsmOperand - Print out an operand for an inline asm expression. 247/// 248bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 249 unsigned AsmVariant, 250 const char *ExtraCode, raw_ostream &O) { 251 // Does this asm operand have a single letter operand modifier? 252 if (ExtraCode && ExtraCode[0]) { 253 if (ExtraCode[1] != 0) return true; // Unknown modifier. 254 255 switch (ExtraCode[0]) { 256 default: 257 // See if this is a generic print operand 258 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 259 case 'c': // Don't print "$" before a global var name or constant. 260 break; // PPC never has a prefix. 261 case 'L': // Write second word of DImode reference. 262 // Verify that this operand has two consecutive registers. 263 if (!MI->getOperand(OpNo).isReg() || 264 OpNo+1 == MI->getNumOperands() || 265 !MI->getOperand(OpNo+1).isReg()) 266 return true; 267 ++OpNo; // Return the high-part. 268 break; 269 case 'I': 270 // Write 'i' if an integer constant, otherwise nothing. Used to print 271 // addi vs add, etc. 272 if (MI->getOperand(OpNo).isImm()) 273 O << "i"; 274 return false; 275 } 276 } 277 278 printOperand(MI, OpNo, O); 279 return false; 280} 281 282// At the moment, all inline asm memory operands are a single register. 283// In any case, the output of this routine should always be just one 284// assembler operand. 285 286bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 287 unsigned AsmVariant, 288 const char *ExtraCode, 289 raw_ostream &O) { 290 if (ExtraCode && ExtraCode[0]) { 291 if (ExtraCode[1] != 0) return true; // Unknown modifier. 292 293 switch (ExtraCode[0]) { 294 default: return true; // Unknown modifier. 295 case 'y': // A memory reference for an X-form instruction 296 { 297 const char *RegName = "r0"; 298 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 299 O << RegName << ", "; 300 printOperand(MI, OpNo, O); 301 return false; 302 } 303 } 304 } 305 306 assert(MI->getOperand(OpNo).isReg()); 307 O << "0("; 308 printOperand(MI, OpNo, O); 309 O << ")"; 310 return false; 311} 312 313 314/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 315/// exists for it. If not, create one. Then return a symbol that references 316/// the TOC entry. 317MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { 318 319 MCSymbol *&TOCEntry = TOC[Sym]; 320 321 // To avoid name clash check if the name already exists. 322 while (TOCEntry == 0) { 323 if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) + 324 "C" + Twine(TOCLabelID++)) == 0) { 325 TOCEntry = GetTempSymbol("C", TOCLabelID); 326 } 327 } 328 329 return TOCEntry; 330} 331 332 333/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 334/// the current output stream. 335/// 336void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 337 MCInst TmpInst; 338 339 // Lower multi-instruction pseudo operations. 340 switch (MI->getOpcode()) { 341 default: break; 342 case TargetOpcode::DBG_VALUE: { 343 if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return; 344 345 SmallString<32> Str; 346 raw_svector_ostream O(Str); 347 unsigned NOps = MI->getNumOperands(); 348 assert(NOps==4); 349 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 350 // cast away const; DIetc do not take const operands for some reason. 351 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 352 O << V.getName(); 353 O << " <- "; 354 // Frame address. Currently handles register +- offset only. 355 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 356 O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O); 357 O << ']'; 358 O << "+"; 359 printOperand(MI, NOps-2, O); 360 OutStreamer.EmitRawText(O.str()); 361 return; 362 } 363 364 case PPC::MovePCtoLR: 365 case PPC::MovePCtoLR8: { 366 // Transform %LR = MovePCtoLR 367 // Into this, where the label is the PIC base: 368 // bl L1$pb 369 // L1$pb: 370 MCSymbol *PICBase = MF->getPICBaseSymbol(); 371 372 // Emit the 'bl'. 373 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here. 374 // FIXME: We would like an efficient form for this, so we don't have to do 375 // a lot of extra uniquing. 376 .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 377 378 // Emit the label. 379 OutStreamer.EmitLabel(PICBase); 380 return; 381 } 382 case PPC::LDtocJTI: 383 case PPC::LDtocCPT: 384 case PPC::LDtoc: { 385 // Transform %X3 = LDtoc <ga:@min1>, %X2 386 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 387 388 // Change the opcode to LD, and the global address operand to be a 389 // reference to the TOC entry we will synthesize later. 390 TmpInst.setOpcode(PPC::LD); 391 const MachineOperand &MO = MI->getOperand(1); 392 393 // Map symbol -> label of TOC entry 394 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); 395 MCSymbol *MOSymbol = 0; 396 if (MO.isGlobal()) 397 MOSymbol = Mang->getSymbol(MO.getGlobal()); 398 else if (MO.isCPI()) 399 MOSymbol = GetCPISymbol(MO.getIndex()); 400 else if (MO.isJTI()) 401 MOSymbol = GetJTISymbol(MO.getIndex()); 402 403 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 404 405 const MCExpr *Exp = 406 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY, 407 OutContext); 408 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 409 OutStreamer.EmitInstruction(TmpInst); 410 return; 411 } 412 413 case PPC::ADDIStocHA: { 414 // Transform %Xd = ADDIStocHA %X2, <ga:@sym> 415 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 416 417 // Change the opcode to ADDIS8. If the global address is external, 418 // has common linkage, is a function address, or is a jump table 419 // address, then generate a TOC entry and reference that. Otherwise 420 // reference the symbol directly. 421 TmpInst.setOpcode(PPC::ADDIS8); 422 const MachineOperand &MO = MI->getOperand(2); 423 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) && 424 "Invalid operand for ADDIStocHA!"); 425 MCSymbol *MOSymbol = 0; 426 bool IsExternal = false; 427 bool IsFunction = false; 428 bool IsCommon = false; 429 430 if (MO.isGlobal()) { 431 const GlobalValue *GValue = MO.getGlobal(); 432 MOSymbol = Mang->getSymbol(GValue); 433 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GValue); 434 IsExternal = GVar && !GVar->hasInitializer(); 435 IsCommon = GVar && GValue->hasCommonLinkage(); 436 IsFunction = !GVar; 437 } else if (MO.isCPI()) 438 MOSymbol = GetCPISymbol(MO.getIndex()); 439 else if (MO.isJTI()) 440 MOSymbol = GetJTISymbol(MO.getIndex()); 441 442 if (IsExternal || IsFunction || IsCommon || MO.isJTI()) 443 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 444 445 const MCExpr *Exp = 446 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA, 447 OutContext); 448 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 449 OutStreamer.EmitInstruction(TmpInst); 450 return; 451 } 452 case PPC::LDtocL: { 453 // Transform %Xd = LDtocL <ga:@sym>, %Xs 454 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 455 456 // Change the opcode to LDrs, which is a form of LD with the offset 457 // specified by a SymbolLo. If the global address is external, has 458 // common linkage, or is a jump table address, then reference the 459 // associated TOC entry. Otherwise reference the symbol directly. 460 TmpInst.setOpcode(PPC::LDrs); 461 const MachineOperand &MO = MI->getOperand(1); 462 assert((MO.isGlobal() || MO.isJTI()) && "Invalid operand for LDtocL!"); 463 MCSymbol *MOSymbol = 0; 464 465 if (MO.isJTI()) 466 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 467 else { 468 const GlobalValue *GValue = MO.getGlobal(); 469 MOSymbol = Mang->getSymbol(GValue); 470 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GValue); 471 472 if (!GVar || !GVar->hasInitializer() || GValue->hasCommonLinkage()) 473 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 474 } 475 476 const MCExpr *Exp = 477 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 478 OutContext); 479 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 480 OutStreamer.EmitInstruction(TmpInst); 481 return; 482 } 483 case PPC::ADDItocL: { 484 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 485 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 486 487 // Change the opcode to ADDI8L. If the global address is external, then 488 // generate a TOC entry and reference that. Otherwise reference the 489 // symbol directly. 490 TmpInst.setOpcode(PPC::ADDI8L); 491 const MachineOperand &MO = MI->getOperand(2); 492 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 493 MCSymbol *MOSymbol = 0; 494 bool IsExternal = false; 495 bool IsFunction = false; 496 497 if (MO.isGlobal()) { 498 const GlobalValue *GValue = MO.getGlobal(); 499 MOSymbol = Mang->getSymbol(GValue); 500 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GValue); 501 IsExternal = GVar && !GVar->hasInitializer(); 502 IsFunction = !GVar; 503 } else if (MO.isCPI()) 504 MOSymbol = GetCPISymbol(MO.getIndex()); 505 506 if (IsFunction || IsExternal) 507 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 508 509 const MCExpr *Exp = 510 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 511 OutContext); 512 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 513 OutStreamer.EmitInstruction(TmpInst); 514 return; 515 } 516 case PPC::LDgotTPREL: { 517 // Transform %Xd = LDgotTPREL <ga:@sym>, %Xs 518 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 519 520 // Change the opcode to LDrs, which is a form of LD with the offset 521 // specified by a SymbolLo. 522 TmpInst.setOpcode(PPC::LDrs); 523 const MachineOperand &MO = MI->getOperand(1); 524 const GlobalValue *GValue = MO.getGlobal(); 525 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 526 const MCExpr *Exp = 527 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_DS, 528 OutContext); 529 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 530 OutStreamer.EmitInstruction(TmpInst); 531 return; 532 } 533 case PPC::ADDIStlsgdHA: { 534 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 535 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 536 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 537 const MachineOperand &MO = MI->getOperand(2); 538 const GlobalValue *GValue = MO.getGlobal(); 539 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 540 const MCExpr *SymGotTlsGD = 541 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA, 542 OutContext); 543 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 544 .addReg(MI->getOperand(0).getReg()) 545 .addReg(PPC::X2) 546 .addExpr(SymGotTlsGD)); 547 return; 548 } 549 case PPC::ADDItlsgdL: { 550 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 551 // Into: %Xd = ADDI8L %Xs, sym@got@tlsgd@l 552 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 553 const MachineOperand &MO = MI->getOperand(2); 554 const GlobalValue *GValue = MO.getGlobal(); 555 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 556 const MCExpr *SymGotTlsGD = 557 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO, 558 OutContext); 559 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 560 .addReg(MI->getOperand(0).getReg()) 561 .addReg(MI->getOperand(1).getReg()) 562 .addExpr(SymGotTlsGD)); 563 return; 564 } 565 case PPC::GETtlsADDR: { 566 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 567 // Into: BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd) 568 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 569 570 StringRef Name = "__tls_get_addr"; 571 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 572 const MCSymbolRefExpr *TlsRef = 573 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 574 const MachineOperand &MO = MI->getOperand(2); 575 const GlobalValue *GValue = MO.getGlobal(); 576 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 577 const MCExpr *SymVar = 578 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, 579 OutContext); 580 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD) 581 .addExpr(TlsRef) 582 .addExpr(SymVar)); 583 return; 584 } 585 case PPC::ADDIStlsldHA: { 586 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 587 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 588 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 589 const MachineOperand &MO = MI->getOperand(2); 590 const GlobalValue *GValue = MO.getGlobal(); 591 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 592 const MCExpr *SymGotTlsLD = 593 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA, 594 OutContext); 595 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 596 .addReg(MI->getOperand(0).getReg()) 597 .addReg(PPC::X2) 598 .addExpr(SymGotTlsLD)); 599 return; 600 } 601 case PPC::ADDItlsldL: { 602 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 603 // Into: %Xd = ADDI8L %Xs, sym@got@tlsld@l 604 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 605 const MachineOperand &MO = MI->getOperand(2); 606 const GlobalValue *GValue = MO.getGlobal(); 607 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 608 const MCExpr *SymGotTlsLD = 609 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO, 610 OutContext); 611 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 612 .addReg(MI->getOperand(0).getReg()) 613 .addReg(MI->getOperand(1).getReg()) 614 .addExpr(SymGotTlsLD)); 615 return; 616 } 617 case PPC::GETtlsldADDR: { 618 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 619 // Into: BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld) 620 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 621 622 StringRef Name = "__tls_get_addr"; 623 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 624 const MCSymbolRefExpr *TlsRef = 625 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 626 const MachineOperand &MO = MI->getOperand(2); 627 const GlobalValue *GValue = MO.getGlobal(); 628 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 629 const MCExpr *SymVar = 630 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, 631 OutContext); 632 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD) 633 .addExpr(TlsRef) 634 .addExpr(SymVar)); 635 return; 636 } 637 case PPC::ADDISdtprelHA: { 638 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 639 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 640 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 641 const MachineOperand &MO = MI->getOperand(2); 642 const GlobalValue *GValue = MO.getGlobal(); 643 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 644 const MCExpr *SymDtprel = 645 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA, 646 OutContext); 647 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 648 .addReg(MI->getOperand(0).getReg()) 649 .addReg(PPC::X3) 650 .addExpr(SymDtprel)); 651 return; 652 } 653 case PPC::ADDIdtprelL: { 654 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 655 // Into: %Xd = ADDI8L %Xs, sym@dtprel@l 656 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 657 const MachineOperand &MO = MI->getOperand(2); 658 const GlobalValue *GValue = MO.getGlobal(); 659 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 660 const MCExpr *SymDtprel = 661 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO, 662 OutContext); 663 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 664 .addReg(MI->getOperand(0).getReg()) 665 .addReg(MI->getOperand(1).getReg()) 666 .addExpr(SymDtprel)); 667 return; 668 } 669 case PPC::MFCRpseud: 670 case PPC::MFCR8pseud: 671 // Transform: %R3 = MFCRpseud %CR7 672 // Into: %R3 = MFCR ;; cr7 673 OutStreamer.AddComment(PPCInstPrinter:: 674 getRegisterName(MI->getOperand(1).getReg())); 675 OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR) 676 .addReg(MI->getOperand(0).getReg())); 677 return; 678 case PPC::SYNC: 679 // In Book E sync is called msync, handle this special case here... 680 if (Subtarget.isBookE()) { 681 OutStreamer.EmitRawText(StringRef("\tmsync")); 682 return; 683 } 684 } 685 686 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 687 OutStreamer.EmitInstruction(TmpInst); 688} 689 690void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 691 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 692 return AsmPrinter::EmitFunctionEntryLabel(); 693 694 // Emit an official procedure descriptor. 695 const MCSection *Current = OutStreamer.getCurrentSection(); 696 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 697 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 698 SectionKind::getReadOnly()); 699 OutStreamer.SwitchSection(Section); 700 OutStreamer.EmitLabel(CurrentFnSym); 701 OutStreamer.EmitValueToAlignment(8); 702 MCSymbol *Symbol1 = 703 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 704 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 705 // entry point. 706 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 707 8/*size*/, 0/*addrspace*/); 708 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 709 // Generates a R_PPC64_TOC relocation for TOC base insertion. 710 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 711 MCSymbolRefExpr::VK_PPC_TOC, OutContext), 712 8/*size*/, 0/*addrspace*/); 713 // Emit a null environment pointer. 714 OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */); 715 OutStreamer.SwitchSection(Current); 716 717 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 718 ".L." + Twine(CurrentFnSym->getName())); 719 OutStreamer.EmitLabel(RealFnSym); 720 CurrentFnSymForSize = RealFnSym; 721} 722 723 724bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 725 const DataLayout *TD = TM.getDataLayout(); 726 727 bool isPPC64 = TD->getPointerSizeInBits() == 64; 728 729 if (isPPC64 && !TOC.empty()) { 730 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 731 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 732 SectionKind::getReadOnly()); 733 OutStreamer.SwitchSection(Section); 734 735 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 736 E = TOC.end(); I != E; ++I) { 737 OutStreamer.EmitLabel(I->second); 738 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 739 OutStreamer.EmitTCEntry(*S); 740 } 741 } 742 743 return AsmPrinter::doFinalization(M); 744} 745 746/// EmitFunctionBodyEnd - Print the traceback table before the .size 747/// directive. 748/// 749void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 750 // Only the 64-bit target requires a traceback table. For now, 751 // we only emit the word of zeroes that GDB requires to find 752 // the end of the function, and zeroes for the eight-byte 753 // mandatory fields. 754 // FIXME: We should fill in the eight-byte mandatory fields as described in 755 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 756 // currently make use of these fields). 757 if (Subtarget.isPPC64()) { 758 OutStreamer.EmitIntValue(0, 4/*size*/); 759 OutStreamer.EmitIntValue(0, 8/*size*/); 760 } 761} 762 763void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 764 static const char *const CPUDirectives[] = { 765 "", 766 "ppc", 767 "ppc440", 768 "ppc601", 769 "ppc602", 770 "ppc603", 771 "ppc7400", 772 "ppc750", 773 "ppc970", 774 "ppcA2", 775 "ppce500mc", 776 "ppce5500", 777 "power6", 778 "power7", 779 "ppc64" 780 }; 781 782 unsigned Directive = Subtarget.getDarwinDirective(); 783 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 784 Directive = PPC::DIR_970; 785 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 786 Directive = PPC::DIR_7400; 787 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 788 Directive = PPC::DIR_64; 789 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 790 791 // FIXME: This is a total hack, finish mc'izing the PPC backend. 792 if (OutStreamer.hasRawTextSupport()) 793 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 794 795 // Prime text sections so they are adjacent. This reduces the likelihood a 796 // large data or debug section causes a branch to exceed 16M limit. 797 const TargetLoweringObjectFileMachO &TLOFMacho = 798 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 799 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 800 if (TM.getRelocationModel() == Reloc::PIC_) { 801 OutStreamer.SwitchSection( 802 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 803 MCSectionMachO::S_SYMBOL_STUBS | 804 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 805 32, SectionKind::getText())); 806 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 807 OutStreamer.SwitchSection( 808 OutContext.getMachOSection("__TEXT","__symbol_stub1", 809 MCSectionMachO::S_SYMBOL_STUBS | 810 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 811 16, SectionKind::getText())); 812 } 813 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 814} 815 816static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 817 // Remove $stub suffix, add $lazy_ptr. 818 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 819 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 820} 821 822static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 823 // Add $tmp suffix to $stub, yielding $stub$tmp. 824 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 825} 826 827void PPCDarwinAsmPrinter:: 828EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 829 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 830 831 const TargetLoweringObjectFileMachO &TLOFMacho = 832 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 833 834 // .lazy_symbol_pointer 835 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 836 837 // Output stubs for dynamically-linked functions 838 if (TM.getRelocationModel() == Reloc::PIC_) { 839 const MCSection *StubSection = 840 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 841 MCSectionMachO::S_SYMBOL_STUBS | 842 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 843 32, SectionKind::getText()); 844 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 845 OutStreamer.SwitchSection(StubSection); 846 EmitAlignment(4); 847 848 MCSymbol *Stub = Stubs[i].first; 849 MCSymbol *RawSym = Stubs[i].second.getPointer(); 850 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 851 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 852 853 OutStreamer.EmitLabel(Stub); 854 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 855 856 // mflr r0 857 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 858 // FIXME: MCize this. 859 OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName())); 860 OutStreamer.EmitLabel(AnonSymbol); 861 // mflr r11 862 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 863 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 864 const MCExpr *Sub = 865 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext), 866 MCSymbolRefExpr::Create(AnonSymbol, OutContext), 867 OutContext); 868 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) 869 .addReg(PPC::R11) 870 .addReg(PPC::R11) 871 .addExpr(Sub)); 872 // mtlr r0 873 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 874 875 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 876 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 877 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 878 .addReg(PPC::R12) 879 .addExpr(Sub).addExpr(Sub) 880 .addReg(PPC::R11)); 881 // mtctr r12 882 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 883 // bctr 884 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 885 886 OutStreamer.SwitchSection(LSPSection); 887 OutStreamer.EmitLabel(LazyPtr); 888 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 889 890 MCSymbol *DyldStubBindingHelper = 891 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 892 if (isPPC64) { 893 // .quad dyld_stub_binding_helper 894 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 895 } else { 896 // .long dyld_stub_binding_helper 897 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 898 } 899 } 900 OutStreamer.AddBlankLine(); 901 return; 902 } 903 904 const MCSection *StubSection = 905 OutContext.getMachOSection("__TEXT","__symbol_stub1", 906 MCSectionMachO::S_SYMBOL_STUBS | 907 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 908 16, SectionKind::getText()); 909 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 910 MCSymbol *Stub = Stubs[i].first; 911 MCSymbol *RawSym = Stubs[i].second.getPointer(); 912 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 913 914 OutStreamer.SwitchSection(StubSection); 915 EmitAlignment(4); 916 OutStreamer.EmitLabel(Stub); 917 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 918 // lis r11, ha16(LazyPtr) 919 const MCExpr *LazyPtrHa16 = 920 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16, 921 OutContext); 922 OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS) 923 .addReg(PPC::R11) 924 .addExpr(LazyPtrHa16)); 925 926 const MCExpr *LazyPtrLo16 = 927 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16, 928 OutContext); 929 // ldu r12, lo16(LazyPtr)(r11) 930 // lwzu r12, lo16(LazyPtr)(r11) 931 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 932 .addReg(PPC::R12) 933 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 934 .addReg(PPC::R11)); 935 936 // mtctr r12 937 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 938 // bctr 939 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 940 941 OutStreamer.SwitchSection(LSPSection); 942 OutStreamer.EmitLabel(LazyPtr); 943 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 944 945 MCSymbol *DyldStubBindingHelper = 946 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 947 if (isPPC64) { 948 // .quad dyld_stub_binding_helper 949 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 950 } else { 951 // .long dyld_stub_binding_helper 952 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 953 } 954 } 955 956 OutStreamer.AddBlankLine(); 957} 958 959 960bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 961 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 962 963 // Darwin/PPC always uses mach-o. 964 const TargetLoweringObjectFileMachO &TLOFMacho = 965 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 966 MachineModuleInfoMachO &MMIMacho = 967 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 968 969 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 970 if (!Stubs.empty()) 971 EmitFunctionStubs(Stubs); 972 973 if (MAI->doesSupportExceptionHandling() && MMI) { 974 // Add the (possibly multiple) personalities to the set of global values. 975 // Only referenced functions get into the Personalities list. 976 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 977 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 978 E = Personalities.end(); I != E; ++I) { 979 if (*I) { 980 MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 981 MachineModuleInfoImpl::StubValueTy &StubSym = 982 MMIMacho.getGVStubEntry(NLPSym); 983 StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true); 984 } 985 } 986 } 987 988 // Output stubs for dynamically-linked functions. 989 Stubs = MMIMacho.GetGVStubList(); 990 991 // Output macho stubs for external and common global variables. 992 if (!Stubs.empty()) { 993 // Switch with ".non_lazy_symbol_pointer" directive. 994 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 995 EmitAlignment(isPPC64 ? 3 : 2); 996 997 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 998 // L_foo$stub: 999 OutStreamer.EmitLabel(Stubs[i].first); 1000 // .indirect_symbol _foo 1001 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1002 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1003 1004 if (MCSym.getInt()) 1005 // External to current translation unit. 1006 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 1007 else 1008 // Internal to current translation unit. 1009 // 1010 // When we place the LSDA into the TEXT section, the type info pointers 1011 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1012 // However, sometimes the types are local to the file. So we need to 1013 // fill in the value for the NLP in those cases. 1014 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1015 OutContext), 1016 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 1017 } 1018 1019 Stubs.clear(); 1020 OutStreamer.AddBlankLine(); 1021 } 1022 1023 Stubs = MMIMacho.GetHiddenGVStubList(); 1024 if (!Stubs.empty()) { 1025 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1026 EmitAlignment(isPPC64 ? 3 : 2); 1027 1028 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1029 // L_foo$stub: 1030 OutStreamer.EmitLabel(Stubs[i].first); 1031 // .long _foo 1032 OutStreamer.EmitValue(MCSymbolRefExpr:: 1033 Create(Stubs[i].second.getPointer(), 1034 OutContext), 1035 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 1036 } 1037 1038 Stubs.clear(); 1039 OutStreamer.AddBlankLine(); 1040 } 1041 1042 // Funny Darwin hack: This flag tells the linker that no global symbols 1043 // contain code that falls through to other global symbols (e.g. the obvious 1044 // implementation of multiple entry points). If this doesn't occur, the 1045 // linker can safely perform dead code stripping. Since LLVM never generates 1046 // code that does this, it is always safe to set. 1047 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1048 1049 return AsmPrinter::doFinalization(M); 1050} 1051 1052/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1053/// for a MachineFunction to the given output stream, in a format that the 1054/// Darwin assembler can deal with. 1055/// 1056static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 1057 MCStreamer &Streamer) { 1058 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 1059 1060 if (Subtarget->isDarwin()) 1061 return new PPCDarwinAsmPrinter(tm, Streamer); 1062 return new PPCLinuxAsmPrinter(tm, Streamer); 1063} 1064 1065// Force static initialization. 1066extern "C" void LLVMInitializePowerPCAsmPrinter() { 1067 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1068 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1069} 1070