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