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