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