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