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