LLVM API Documentation
00001 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to PowerPC assembly language. This printer is 00012 // the output mechanism used by `llc'. 00013 // 00014 // Documentation at http://developer.apple.com/documentation/DeveloperTools/ 00015 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 00016 // 00017 //===----------------------------------------------------------------------===// 00018 00019 #include "PPC.h" 00020 #include "InstPrinter/PPCInstPrinter.h" 00021 #include "PPCMachineFunctionInfo.h" 00022 #include "MCTargetDesc/PPCMCExpr.h" 00023 #include "MCTargetDesc/PPCPredicates.h" 00024 #include "PPCSubtarget.h" 00025 #include "PPCTargetMachine.h" 00026 #include "PPCTargetStreamer.h" 00027 #include "llvm/ADT/MapVector.h" 00028 #include "llvm/ADT/SmallString.h" 00029 #include "llvm/ADT/StringExtras.h" 00030 #include "llvm/CodeGen/AsmPrinter.h" 00031 #include "llvm/CodeGen/MachineConstantPool.h" 00032 #include "llvm/CodeGen/MachineFunctionPass.h" 00033 #include "llvm/CodeGen/MachineInstr.h" 00034 #include "llvm/CodeGen/MachineInstrBuilder.h" 00035 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00036 #include "llvm/CodeGen/MachineRegisterInfo.h" 00037 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 00038 #include "llvm/IR/Constants.h" 00039 #include "llvm/IR/DebugInfo.h" 00040 #include "llvm/IR/DerivedTypes.h" 00041 #include "llvm/IR/Mangler.h" 00042 #include "llvm/IR/Module.h" 00043 #include "llvm/MC/MCAsmInfo.h" 00044 #include "llvm/MC/MCContext.h" 00045 #include "llvm/MC/MCExpr.h" 00046 #include "llvm/MC/MCInst.h" 00047 #include "llvm/MC/MCInstBuilder.h" 00048 #include "llvm/MC/MCSectionELF.h" 00049 #include "llvm/MC/MCSectionMachO.h" 00050 #include "llvm/MC/MCStreamer.h" 00051 #include "llvm/MC/MCSymbol.h" 00052 #include "llvm/Support/CommandLine.h" 00053 #include "llvm/Support/Debug.h" 00054 #include "llvm/Support/ELF.h" 00055 #include "llvm/Support/ErrorHandling.h" 00056 #include "llvm/Support/MathExtras.h" 00057 #include "llvm/Support/TargetRegistry.h" 00058 #include "llvm/Support/raw_ostream.h" 00059 #include "llvm/Target/TargetInstrInfo.h" 00060 #include "llvm/Target/TargetOptions.h" 00061 #include "llvm/Target/TargetRegisterInfo.h" 00062 using namespace llvm; 00063 00064 #define DEBUG_TYPE "asmprinter" 00065 00066 namespace { 00067 class PPCAsmPrinter : public AsmPrinter { 00068 protected: 00069 MapVector<MCSymbol*, MCSymbol*> TOC; 00070 const PPCSubtarget &Subtarget; 00071 uint64_t TOCLabelID; 00072 public: 00073 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 00074 : AsmPrinter(TM, Streamer), 00075 Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {} 00076 00077 const char *getPassName() const override { 00078 return "PowerPC Assembly Printer"; 00079 } 00080 00081 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym); 00082 00083 void EmitInstruction(const MachineInstr *MI) override; 00084 00085 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 00086 00087 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00088 unsigned AsmVariant, const char *ExtraCode, 00089 raw_ostream &O) override; 00090 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00091 unsigned AsmVariant, const char *ExtraCode, 00092 raw_ostream &O) override; 00093 }; 00094 00095 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 00096 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 00097 public: 00098 explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 00099 : PPCAsmPrinter(TM, Streamer) {} 00100 00101 const char *getPassName() const override { 00102 return "Linux PPC Assembly Printer"; 00103 } 00104 00105 bool doFinalization(Module &M) override; 00106 void EmitStartOfAsmFile(Module &M) override; 00107 00108 void EmitFunctionEntryLabel() override; 00109 00110 void EmitFunctionBodyStart() override; 00111 void EmitFunctionBodyEnd() override; 00112 }; 00113 00114 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 00115 /// OS X 00116 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 00117 public: 00118 explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 00119 : PPCAsmPrinter(TM, Streamer) {} 00120 00121 const char *getPassName() const override { 00122 return "Darwin PPC Assembly Printer"; 00123 } 00124 00125 bool doFinalization(Module &M) override; 00126 void EmitStartOfAsmFile(Module &M) override; 00127 00128 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 00129 }; 00130 } // end of anonymous namespace 00131 00132 /// stripRegisterPrefix - This method strips the character prefix from a 00133 /// register name so that only the number is left. Used by for linux asm. 00134 static const char *stripRegisterPrefix(const char *RegName) { 00135 switch (RegName[0]) { 00136 case 'r': 00137 case 'f': 00138 case 'v': 00139 if (RegName[1] == 's') 00140 return RegName + 2; 00141 return RegName + 1; 00142 case 'c': if (RegName[1] == 'r') return RegName + 2; 00143 } 00144 00145 return RegName; 00146 } 00147 00148 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 00149 raw_ostream &O) { 00150 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00151 const MachineOperand &MO = MI->getOperand(OpNo); 00152 00153 switch (MO.getType()) { 00154 case MachineOperand::MO_Register: { 00155 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 00156 // Linux assembler (Others?) does not take register mnemonics. 00157 // FIXME - What about special registers used in mfspr/mtspr? 00158 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 00159 O << RegName; 00160 return; 00161 } 00162 case MachineOperand::MO_Immediate: 00163 O << MO.getImm(); 00164 return; 00165 00166 case MachineOperand::MO_MachineBasicBlock: 00167 O << *MO.getMBB()->getSymbol(); 00168 return; 00169 case MachineOperand::MO_ConstantPoolIndex: 00170 O << DL->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 00171 << '_' << MO.getIndex(); 00172 return; 00173 case MachineOperand::MO_BlockAddress: 00174 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 00175 return; 00176 case MachineOperand::MO_GlobalAddress: { 00177 // Computing the address of a global symbol, not calling it. 00178 const GlobalValue *GV = MO.getGlobal(); 00179 MCSymbol *SymToPrint; 00180 00181 // External or weakly linked global variables need non-lazily-resolved stubs 00182 if (TM.getRelocationModel() != Reloc::Static && 00183 (GV->isDeclaration() || GV->isWeakForLinker())) { 00184 if (!GV->hasHiddenVisibility()) { 00185 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00186 MachineModuleInfoImpl::StubValueTy &StubSym = 00187 MMI->getObjFileInfo<MachineModuleInfoMachO>() 00188 .getGVStubEntry(SymToPrint); 00189 if (!StubSym.getPointer()) 00190 StubSym = MachineModuleInfoImpl:: 00191 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 00192 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 00193 GV->hasAvailableExternallyLinkage()) { 00194 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00195 00196 MachineModuleInfoImpl::StubValueTy &StubSym = 00197 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 00198 getHiddenGVStubEntry(SymToPrint); 00199 if (!StubSym.getPointer()) 00200 StubSym = MachineModuleInfoImpl:: 00201 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 00202 } else { 00203 SymToPrint = getSymbol(GV); 00204 } 00205 } else { 00206 SymToPrint = getSymbol(GV); 00207 } 00208 00209 O << *SymToPrint; 00210 00211 printOffset(MO.getOffset(), O); 00212 return; 00213 } 00214 00215 default: 00216 O << "<unknown operand type: " << (unsigned)MO.getType() << ">"; 00217 return; 00218 } 00219 } 00220 00221 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00222 /// 00223 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00224 unsigned AsmVariant, 00225 const char *ExtraCode, raw_ostream &O) { 00226 // Does this asm operand have a single letter operand modifier? 00227 if (ExtraCode && ExtraCode[0]) { 00228 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00229 00230 switch (ExtraCode[0]) { 00231 default: 00232 // See if this is a generic print operand 00233 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 00234 case 'c': // Don't print "$" before a global var name or constant. 00235 break; // PPC never has a prefix. 00236 case 'L': // Write second word of DImode reference. 00237 // Verify that this operand has two consecutive registers. 00238 if (!MI->getOperand(OpNo).isReg() || 00239 OpNo+1 == MI->getNumOperands() || 00240 !MI->getOperand(OpNo+1).isReg()) 00241 return true; 00242 ++OpNo; // Return the high-part. 00243 break; 00244 case 'I': 00245 // Write 'i' if an integer constant, otherwise nothing. Used to print 00246 // addi vs add, etc. 00247 if (MI->getOperand(OpNo).isImm()) 00248 O << "i"; 00249 return false; 00250 } 00251 } 00252 00253 printOperand(MI, OpNo, O); 00254 return false; 00255 } 00256 00257 // At the moment, all inline asm memory operands are a single register. 00258 // In any case, the output of this routine should always be just one 00259 // assembler operand. 00260 00261 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00262 unsigned AsmVariant, 00263 const char *ExtraCode, 00264 raw_ostream &O) { 00265 if (ExtraCode && ExtraCode[0]) { 00266 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00267 00268 switch (ExtraCode[0]) { 00269 default: return true; // Unknown modifier. 00270 case 'y': // A memory reference for an X-form instruction 00271 { 00272 const char *RegName = "r0"; 00273 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 00274 O << RegName << ", "; 00275 printOperand(MI, OpNo, O); 00276 return false; 00277 } 00278 case 'U': // Print 'u' for update form. 00279 case 'X': // Print 'x' for indexed form. 00280 { 00281 // FIXME: Currently for PowerPC memory operands are always loaded 00282 // into a register, so we never get an update or indexed form. 00283 // This is bad even for offset forms, since even if we know we 00284 // have a value in -16(r1), we will generate a load into r<n> 00285 // and then load from 0(r<n>). Until that issue is fixed, 00286 // tolerate 'U' and 'X' but don't output anything. 00287 assert(MI->getOperand(OpNo).isReg()); 00288 return false; 00289 } 00290 } 00291 } 00292 00293 assert(MI->getOperand(OpNo).isReg()); 00294 O << "0("; 00295 printOperand(MI, OpNo, O); 00296 O << ")"; 00297 return false; 00298 } 00299 00300 00301 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 00302 /// exists for it. If not, create one. Then return a symbol that references 00303 /// the TOC entry. 00304 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { 00305 const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); 00306 MCSymbol *&TOCEntry = TOC[Sym]; 00307 00308 // To avoid name clash check if the name already exists. 00309 while (!TOCEntry) { 00310 if (OutContext.LookupSymbol(Twine(DL->getPrivateGlobalPrefix()) + 00311 "C" + Twine(TOCLabelID++)) == nullptr) { 00312 TOCEntry = GetTempSymbol("C", TOCLabelID); 00313 } 00314 } 00315 00316 return TOCEntry; 00317 } 00318 00319 00320 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 00321 /// the current output stream. 00322 /// 00323 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 00324 MCInst TmpInst; 00325 bool isPPC64 = Subtarget.isPPC64(); 00326 00327 // Lower multi-instruction pseudo operations. 00328 switch (MI->getOpcode()) { 00329 default: break; 00330 case TargetOpcode::DBG_VALUE: 00331 llvm_unreachable("Should be handled target independently"); 00332 case PPC::MovePCtoLR: 00333 case PPC::MovePCtoLR8: { 00334 // Transform %LR = MovePCtoLR 00335 // Into this, where the label is the PIC base: 00336 // bl L1$pb 00337 // L1$pb: 00338 MCSymbol *PICBase = MF->getPICBaseSymbol(); 00339 00340 // Emit the 'bl'. 00341 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 00342 // FIXME: We would like an efficient form for this, so we don't have to do 00343 // a lot of extra uniquing. 00344 .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 00345 00346 // Emit the label. 00347 OutStreamer.EmitLabel(PICBase); 00348 return; 00349 } 00350 case PPC::GetGBRO: { 00351 // Get the offset from the GOT Base Register to the GOT 00352 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00353 MCSymbol *PICOffset = MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); 00354 TmpInst.setOpcode(PPC::LWZ); 00355 const MCExpr *Exp = 00356 MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); 00357 const MCExpr *PB = 00358 MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), 00359 MCSymbolRefExpr::VK_None, 00360 OutContext); 00361 const MCOperand MO = TmpInst.getOperand(1); 00362 TmpInst.getOperand(1) = MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, 00363 PB, 00364 OutContext)); 00365 TmpInst.addOperand(MO); 00366 EmitToStreamer(OutStreamer, TmpInst); 00367 return; 00368 } 00369 case PPC::UpdateGBR: { 00370 // Update the GOT Base Register to point to the GOT. It may be possible to 00371 // merge this with the PPC::GetGBRO, doing it all in one step. 00372 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00373 TmpInst.setOpcode(PPC::ADD4); 00374 TmpInst.addOperand(TmpInst.getOperand(0)); 00375 EmitToStreamer(OutStreamer, TmpInst); 00376 return; 00377 } 00378 case PPC::LWZtoc: { 00379 // Transform %X3 = LWZtoc <ga:@min1>, %X2 00380 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00381 00382 // Change the opcode to LWZ, and the global address operand to be a 00383 // reference to the GOT entry we will synthesize later. 00384 TmpInst.setOpcode(PPC::LWZ); 00385 const MachineOperand &MO = MI->getOperand(1); 00386 00387 // Map symbol -> label of TOC entry 00388 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); 00389 MCSymbol *MOSymbol = nullptr; 00390 if (MO.isGlobal()) 00391 MOSymbol = getSymbol(MO.getGlobal()); 00392 else if (MO.isCPI()) 00393 MOSymbol = GetCPISymbol(MO.getIndex()); 00394 else if (MO.isJTI()) 00395 MOSymbol = GetJTISymbol(MO.getIndex()); 00396 00397 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 00398 00399 const MCExpr *Exp = 00400 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, 00401 OutContext); 00402 const MCExpr *PB = 00403 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")), 00404 OutContext); 00405 Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); 00406 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 00407 EmitToStreamer(OutStreamer, TmpInst); 00408 return; 00409 } 00410 case PPC::LDtocJTI: 00411 case PPC::LDtocCPT: 00412 case PPC::LDtoc: { 00413 // Transform %X3 = LDtoc <ga:@min1>, %X2 00414 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00415 00416 // Change the opcode to LD, and the global address operand to be a 00417 // reference to the TOC entry we will synthesize later. 00418 TmpInst.setOpcode(PPC::LD); 00419 const MachineOperand &MO = MI->getOperand(1); 00420 00421 // Map symbol -> label of TOC entry 00422 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); 00423 MCSymbol *MOSymbol = nullptr; 00424 if (MO.isGlobal()) 00425 MOSymbol = getSymbol(MO.getGlobal()); 00426 else if (MO.isCPI()) 00427 MOSymbol = GetCPISymbol(MO.getIndex()); 00428 else if (MO.isJTI()) 00429 MOSymbol = GetJTISymbol(MO.getIndex()); 00430 00431 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 00432 00433 const MCExpr *Exp = 00434 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, 00435 OutContext); 00436 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 00437 EmitToStreamer(OutStreamer, TmpInst); 00438 return; 00439 } 00440 00441 case PPC::ADDIStocHA: { 00442 // Transform %Xd = ADDIStocHA %X2, <ga:@sym> 00443 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00444 00445 // Change the opcode to ADDIS8. If the global address is external, has 00446 // common linkage, is a non-local function address, or is a jump table 00447 // address, then generate a TOC entry and reference that. Otherwise 00448 // reference the symbol directly. 00449 TmpInst.setOpcode(PPC::ADDIS8); 00450 const MachineOperand &MO = MI->getOperand(2); 00451 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) && 00452 "Invalid operand for ADDIStocHA!"); 00453 MCSymbol *MOSymbol = nullptr; 00454 bool IsExternal = false; 00455 bool IsNonLocalFunction = false; 00456 bool IsCommon = false; 00457 bool IsAvailExt = false; 00458 00459 if (MO.isGlobal()) { 00460 const GlobalValue *GV = MO.getGlobal(); 00461 MOSymbol = getSymbol(GV); 00462 IsExternal = GV->isDeclaration(); 00463 IsCommon = GV->hasCommonLinkage(); 00464 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 00465 (GV->isDeclaration() || GV->isWeakForLinker()); 00466 IsAvailExt = GV->hasAvailableExternallyLinkage(); 00467 } else if (MO.isCPI()) 00468 MOSymbol = GetCPISymbol(MO.getIndex()); 00469 else if (MO.isJTI()) 00470 MOSymbol = GetJTISymbol(MO.getIndex()); 00471 00472 if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt || 00473 MO.isJTI() || TM.getCodeModel() == CodeModel::Large) 00474 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 00475 00476 const MCExpr *Exp = 00477 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, 00478 OutContext); 00479 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 00480 EmitToStreamer(OutStreamer, TmpInst); 00481 return; 00482 } 00483 case PPC::LDtocL: { 00484 // Transform %Xd = LDtocL <ga:@sym>, %Xs 00485 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00486 00487 // Change the opcode to LD. If the global address is external, has 00488 // common linkage, or is a jump table address, then reference the 00489 // associated TOC entry. Otherwise reference the symbol directly. 00490 TmpInst.setOpcode(PPC::LD); 00491 const MachineOperand &MO = MI->getOperand(1); 00492 assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) && 00493 "Invalid operand for LDtocL!"); 00494 MCSymbol *MOSymbol = nullptr; 00495 00496 if (MO.isJTI()) 00497 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 00498 else if (MO.isCPI()) { 00499 MOSymbol = GetCPISymbol(MO.getIndex()); 00500 if (TM.getCodeModel() == CodeModel::Large) 00501 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 00502 } 00503 else if (MO.isGlobal()) { 00504 const GlobalValue *GValue = MO.getGlobal(); 00505 MOSymbol = getSymbol(GValue); 00506 if (GValue->getType()->getElementType()->isFunctionTy() || 00507 GValue->isDeclaration() || GValue->hasCommonLinkage() || 00508 GValue->hasAvailableExternallyLinkage() || 00509 TM.getCodeModel() == CodeModel::Large) 00510 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 00511 } 00512 00513 const MCExpr *Exp = 00514 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 00515 OutContext); 00516 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 00517 EmitToStreamer(OutStreamer, TmpInst); 00518 return; 00519 } 00520 case PPC::ADDItocL: { 00521 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 00522 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00523 00524 // Change the opcode to ADDI8. If the global address is external, then 00525 // generate a TOC entry and reference that. Otherwise reference the 00526 // symbol directly. 00527 TmpInst.setOpcode(PPC::ADDI8); 00528 const MachineOperand &MO = MI->getOperand(2); 00529 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 00530 MCSymbol *MOSymbol = nullptr; 00531 bool IsExternal = false; 00532 bool IsNonLocalFunction = false; 00533 00534 if (MO.isGlobal()) { 00535 const GlobalValue *GV = MO.getGlobal(); 00536 MOSymbol = getSymbol(GV); 00537 IsExternal = GV->isDeclaration(); 00538 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 00539 (GV->isDeclaration() || GV->isWeakForLinker()); 00540 } else if (MO.isCPI()) 00541 MOSymbol = GetCPISymbol(MO.getIndex()); 00542 00543 if (IsNonLocalFunction || IsExternal || 00544 TM.getCodeModel() == CodeModel::Large) 00545 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 00546 00547 const MCExpr *Exp = 00548 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 00549 OutContext); 00550 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 00551 EmitToStreamer(OutStreamer, TmpInst); 00552 return; 00553 } 00554 case PPC::ADDISgotTprelHA: { 00555 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 00556 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 00557 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 00558 const MachineOperand &MO = MI->getOperand(2); 00559 const GlobalValue *GValue = MO.getGlobal(); 00560 MCSymbol *MOSymbol = getSymbol(GValue); 00561 const MCExpr *SymGotTprel = 00562 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 00563 OutContext); 00564 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 00565 .addReg(MI->getOperand(0).getReg()) 00566 .addReg(PPC::X2) 00567 .addExpr(SymGotTprel)); 00568 return; 00569 } 00570 case PPC::LDgotTprelL: 00571 case PPC::LDgotTprelL32: { 00572 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 00573 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00574 00575 // Change the opcode to LD. 00576 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); 00577 const MachineOperand &MO = MI->getOperand(1); 00578 const GlobalValue *GValue = MO.getGlobal(); 00579 MCSymbol *MOSymbol = getSymbol(GValue); 00580 const MCExpr *Exp = 00581 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, 00582 OutContext); 00583 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 00584 EmitToStreamer(OutStreamer, TmpInst); 00585 return; 00586 } 00587 00588 case PPC::PPC32PICGOT: { 00589 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 00590 MCSymbol *GOTRef = OutContext.CreateTempSymbol(); 00591 MCSymbol *NextInstr = OutContext.CreateTempSymbol(); 00592 00593 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 00594 // FIXME: We would like an efficient form for this, so we don't have to do 00595 // a lot of extra uniquing. 00596 .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext))); 00597 const MCExpr *OffsExpr = 00598 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext), 00599 MCSymbolRefExpr::Create(GOTRef, OutContext), 00600 OutContext); 00601 OutStreamer.EmitLabel(GOTRef); 00602 OutStreamer.EmitValue(OffsExpr, 4); 00603 OutStreamer.EmitLabel(NextInstr); 00604 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR) 00605 .addReg(MI->getOperand(0).getReg())); 00606 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LWZ) 00607 .addReg(MI->getOperand(1).getReg()) 00608 .addImm(0) 00609 .addReg(MI->getOperand(0).getReg())); 00610 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADD4) 00611 .addReg(MI->getOperand(0).getReg()) 00612 .addReg(MI->getOperand(1).getReg()) 00613 .addReg(MI->getOperand(0).getReg())); 00614 return; 00615 } 00616 case PPC::PPC32GOT: { 00617 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 00618 const MCExpr *SymGotTlsL = 00619 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, 00620 OutContext); 00621 const MCExpr *SymGotTlsHA = 00622 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, 00623 OutContext); 00624 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI) 00625 .addReg(MI->getOperand(0).getReg()) 00626 .addExpr(SymGotTlsL)); 00627 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 00628 .addReg(MI->getOperand(0).getReg()) 00629 .addReg(MI->getOperand(0).getReg()) 00630 .addExpr(SymGotTlsHA)); 00631 return; 00632 } 00633 case PPC::ADDIStlsgdHA: { 00634 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 00635 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 00636 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 00637 const MachineOperand &MO = MI->getOperand(2); 00638 const GlobalValue *GValue = MO.getGlobal(); 00639 MCSymbol *MOSymbol = getSymbol(GValue); 00640 const MCExpr *SymGotTlsGD = 00641 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 00642 OutContext); 00643 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 00644 .addReg(MI->getOperand(0).getReg()) 00645 .addReg(PPC::X2) 00646 .addExpr(SymGotTlsGD)); 00647 return; 00648 } 00649 case PPC::ADDItlsgdL: 00650 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 00651 // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l 00652 case PPC::ADDItlsgdL32: { 00653 // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym> 00654 // Into: %Rd = ADDI %Rs, sym@got@tlsgd 00655 const MachineOperand &MO = MI->getOperand(2); 00656 const GlobalValue *GValue = MO.getGlobal(); 00657 MCSymbol *MOSymbol = getSymbol(GValue); 00658 const MCExpr *SymGotTlsGD = 00659 MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? 00660 MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO : 00661 MCSymbolRefExpr::VK_PPC_GOT_TLSGD, 00662 OutContext); 00663 EmitToStreamer(OutStreamer, 00664 MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) 00665 .addReg(MI->getOperand(0).getReg()) 00666 .addReg(MI->getOperand(1).getReg()) 00667 .addExpr(SymGotTlsGD)); 00668 return; 00669 } 00670 case PPC::GETtlsADDR: 00671 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 00672 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd) 00673 case PPC::GETtlsADDR32: { 00674 // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym> 00675 // Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT 00676 00677 StringRef Name = "__tls_get_addr"; 00678 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 00679 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 00680 00681 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() && 00682 TM.getRelocationModel() == Reloc::PIC_) 00683 Kind = MCSymbolRefExpr::VK_PLT; 00684 const MCSymbolRefExpr *TlsRef = 00685 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); 00686 const MachineOperand &MO = MI->getOperand(2); 00687 const GlobalValue *GValue = MO.getGlobal(); 00688 MCSymbol *MOSymbol = getSymbol(GValue); 00689 const MCExpr *SymVar = 00690 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, 00691 OutContext); 00692 EmitToStreamer(OutStreamer, 00693 MCInstBuilder(Subtarget.isPPC64() ? 00694 PPC::BL8_NOP_TLS : PPC::BL_TLS) 00695 .addExpr(TlsRef) 00696 .addExpr(SymVar)); 00697 return; 00698 } 00699 case PPC::ADDIStlsldHA: { 00700 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 00701 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 00702 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 00703 const MachineOperand &MO = MI->getOperand(2); 00704 const GlobalValue *GValue = MO.getGlobal(); 00705 MCSymbol *MOSymbol = getSymbol(GValue); 00706 const MCExpr *SymGotTlsLD = 00707 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 00708 OutContext); 00709 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 00710 .addReg(MI->getOperand(0).getReg()) 00711 .addReg(PPC::X2) 00712 .addExpr(SymGotTlsLD)); 00713 return; 00714 } 00715 case PPC::ADDItlsldL: 00716 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 00717 // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l 00718 case PPC::ADDItlsldL32: { 00719 // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym> 00720 // Into: %Rd = ADDI %Rs, sym@got@tlsld 00721 const MachineOperand &MO = MI->getOperand(2); 00722 const GlobalValue *GValue = MO.getGlobal(); 00723 MCSymbol *MOSymbol = getSymbol(GValue); 00724 const MCExpr *SymGotTlsLD = 00725 MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? 00726 MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO : 00727 MCSymbolRefExpr::VK_PPC_GOT_TLSLD, 00728 OutContext); 00729 EmitToStreamer(OutStreamer, 00730 MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) 00731 .addReg(MI->getOperand(0).getReg()) 00732 .addReg(MI->getOperand(1).getReg()) 00733 .addExpr(SymGotTlsLD)); 00734 return; 00735 } 00736 case PPC::GETtlsldADDR: 00737 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 00738 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld) 00739 case PPC::GETtlsldADDR32: { 00740 // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym> 00741 // Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT 00742 00743 StringRef Name = "__tls_get_addr"; 00744 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 00745 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 00746 00747 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() && 00748 TM.getRelocationModel() == Reloc::PIC_) 00749 Kind = MCSymbolRefExpr::VK_PLT; 00750 00751 const MCSymbolRefExpr *TlsRef = 00752 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); 00753 const MachineOperand &MO = MI->getOperand(2); 00754 const GlobalValue *GValue = MO.getGlobal(); 00755 MCSymbol *MOSymbol = getSymbol(GValue); 00756 const MCExpr *SymVar = 00757 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, 00758 OutContext); 00759 EmitToStreamer(OutStreamer, 00760 MCInstBuilder(Subtarget.isPPC64() ? 00761 PPC::BL8_NOP_TLS : PPC::BL_TLS) 00762 .addExpr(TlsRef) 00763 .addExpr(SymVar)); 00764 return; 00765 } 00766 case PPC::ADDISdtprelHA: 00767 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 00768 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 00769 case PPC::ADDISdtprelHA32: { 00770 // Transform: %Rd = ADDISdtprelHA32 %R3, <ga:@sym> 00771 // Into: %Rd = ADDIS %R3, sym@dtprel@ha 00772 const MachineOperand &MO = MI->getOperand(2); 00773 const GlobalValue *GValue = MO.getGlobal(); 00774 MCSymbol *MOSymbol = getSymbol(GValue); 00775 const MCExpr *SymDtprel = 00776 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 00777 OutContext); 00778 EmitToStreamer(OutStreamer, 00779 MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) 00780 .addReg(MI->getOperand(0).getReg()) 00781 .addReg(Subtarget.isPPC64() ? PPC::X3 : PPC::R3) 00782 .addExpr(SymDtprel)); 00783 return; 00784 } 00785 case PPC::ADDIdtprelL: 00786 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 00787 // Into: %Xd = ADDI8 %Xs, sym@dtprel@l 00788 case PPC::ADDIdtprelL32: { 00789 // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym> 00790 // Into: %Rd = ADDI %Rs, sym@dtprel@l 00791 const MachineOperand &MO = MI->getOperand(2); 00792 const GlobalValue *GValue = MO.getGlobal(); 00793 MCSymbol *MOSymbol = getSymbol(GValue); 00794 const MCExpr *SymDtprel = 00795 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 00796 OutContext); 00797 EmitToStreamer(OutStreamer, 00798 MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) 00799 .addReg(MI->getOperand(0).getReg()) 00800 .addReg(MI->getOperand(1).getReg()) 00801 .addExpr(SymDtprel)); 00802 return; 00803 } 00804 case PPC::MFOCRF: 00805 case PPC::MFOCRF8: 00806 if (!Subtarget.hasMFOCRF()) { 00807 // Transform: %R3 = MFOCRF %CR7 00808 // Into: %R3 = MFCR ;; cr7 00809 unsigned NewOpcode = 00810 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 00811 OutStreamer.AddComment(PPCInstPrinter:: 00812 getRegisterName(MI->getOperand(1).getReg())); 00813 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 00814 .addReg(MI->getOperand(0).getReg())); 00815 return; 00816 } 00817 break; 00818 case PPC::MTOCRF: 00819 case PPC::MTOCRF8: 00820 if (!Subtarget.hasMFOCRF()) { 00821 // Transform: %CR7 = MTOCRF %R3 00822 // Into: MTCRF mask, %R3 ;; cr7 00823 unsigned NewOpcode = 00824 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 00825 unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 00826 ->getEncodingValue(MI->getOperand(0).getReg()); 00827 OutStreamer.AddComment(PPCInstPrinter:: 00828 getRegisterName(MI->getOperand(0).getReg())); 00829 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 00830 .addImm(Mask) 00831 .addReg(MI->getOperand(1).getReg())); 00832 return; 00833 } 00834 break; 00835 case PPC::LD: 00836 case PPC::STD: 00837 case PPC::LWA_32: 00838 case PPC::LWA: { 00839 // Verify alignment is legal, so we don't create relocations 00840 // that can't be supported. 00841 // FIXME: This test is currently disabled for Darwin. The test 00842 // suite shows a handful of test cases that fail this check for 00843 // Darwin. Those need to be investigated before this sanity test 00844 // can be enabled for those subtargets. 00845 if (!Subtarget.isDarwin()) { 00846 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 00847 const MachineOperand &MO = MI->getOperand(OpNum); 00848 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 00849 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 00850 } 00851 // Now process the instruction normally. 00852 break; 00853 } 00854 } 00855 00856 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 00857 EmitToStreamer(OutStreamer, TmpInst); 00858 } 00859 00860 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { 00861 if (Subtarget.isELFv2ABI()) { 00862 PPCTargetStreamer *TS = 00863 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 00864 00865 if (TS) 00866 TS->emitAbiVersion(2); 00867 } 00868 00869 if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_) 00870 return AsmPrinter::EmitStartOfAsmFile(M); 00871 00872 // FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not 00873 // optimal for some cases. We should consider supporting small model (-fpic) 00874 // as well in the future. 00875 assert(TM.getCodeModel() != CodeModel::Small && 00876 "Small code model PIC is currently unsupported."); 00877 OutStreamer.SwitchSection(OutContext.getELFSection(".got2", 00878 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 00879 SectionKind::getReadOnly())); 00880 00881 MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC.")); 00882 MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); 00883 00884 OutStreamer.EmitLabel(CurrentPos); 00885 00886 // The GOT pointer points to the middle of the GOT, in order to reference the 00887 // entire 64kB range. 0x8000 is the midpoint. 00888 const MCExpr *tocExpr = 00889 MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext), 00890 MCConstantExpr::Create(0x8000, OutContext), 00891 OutContext); 00892 00893 OutStreamer.EmitAssignment(TOCSym, tocExpr); 00894 00895 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 00896 } 00897 00898 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 00899 // linux/ppc32 - Normal entry label. 00900 if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_) 00901 return AsmPrinter::EmitFunctionEntryLabel(); 00902 00903 if (!Subtarget.isPPC64()) { 00904 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 00905 if (PPCFI->usesPICBase()) { 00906 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); 00907 MCSymbol *PICBase = MF->getPICBaseSymbol(); 00908 OutStreamer.EmitLabel(RelocSymbol); 00909 00910 const MCExpr *OffsExpr = 00911 MCBinaryExpr::CreateSub( 00912 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")), 00913 OutContext), 00914 MCSymbolRefExpr::Create(PICBase, OutContext), 00915 OutContext); 00916 OutStreamer.EmitValue(OffsExpr, 4); 00917 OutStreamer.EmitLabel(CurrentFnSym); 00918 return; 00919 } else 00920 return AsmPrinter::EmitFunctionEntryLabel(); 00921 } 00922 00923 // ELFv2 ABI - Normal entry label. 00924 if (Subtarget.isELFv2ABI()) 00925 return AsmPrinter::EmitFunctionEntryLabel(); 00926 00927 // Emit an official procedure descriptor. 00928 MCSectionSubPair Current = OutStreamer.getCurrentSection(); 00929 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 00930 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 00931 SectionKind::getReadOnly()); 00932 OutStreamer.SwitchSection(Section); 00933 OutStreamer.EmitLabel(CurrentFnSym); 00934 OutStreamer.EmitValueToAlignment(8); 00935 MCSymbol *Symbol1 = 00936 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 00937 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 00938 // entry point. 00939 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 00940 8 /*size*/); 00941 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 00942 // Generates a R_PPC64_TOC relocation for TOC base insertion. 00943 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 00944 MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 00945 8/*size*/); 00946 // Emit a null environment pointer. 00947 OutStreamer.EmitIntValue(0, 8 /* size */); 00948 OutStreamer.SwitchSection(Current.first, Current.second); 00949 00950 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 00951 ".L." + Twine(CurrentFnSym->getName())); 00952 OutStreamer.EmitLabel(RealFnSym); 00953 CurrentFnSymForSize = RealFnSym; 00954 } 00955 00956 00957 bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 00958 const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout(); 00959 00960 bool isPPC64 = TD->getPointerSizeInBits() == 64; 00961 00962 PPCTargetStreamer &TS = 00963 static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); 00964 00965 if (!TOC.empty()) { 00966 const MCSectionELF *Section; 00967 00968 if (isPPC64) 00969 Section = OutStreamer.getContext().getELFSection(".toc", 00970 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 00971 SectionKind::getReadOnly()); 00972 else 00973 Section = OutStreamer.getContext().getELFSection(".got2", 00974 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 00975 SectionKind::getReadOnly()); 00976 OutStreamer.SwitchSection(Section); 00977 00978 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 00979 E = TOC.end(); I != E; ++I) { 00980 OutStreamer.EmitLabel(I->second); 00981 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 00982 if (isPPC64) 00983 TS.emitTCEntry(*S); 00984 else 00985 OutStreamer.EmitSymbolValue(S, 4); 00986 } 00987 } 00988 00989 MachineModuleInfoELF &MMIELF = 00990 MMI->getObjFileInfo<MachineModuleInfoELF>(); 00991 00992 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 00993 if (!Stubs.empty()) { 00994 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 00995 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 00996 // L_foo$stub: 00997 OutStreamer.EmitLabel(Stubs[i].first); 00998 // .long _foo 00999 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 01000 OutContext), 01001 isPPC64 ? 8 : 4/*size*/); 01002 } 01003 01004 Stubs.clear(); 01005 OutStreamer.AddBlankLine(); 01006 } 01007 01008 return AsmPrinter::doFinalization(M); 01009 } 01010 01011 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 01012 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { 01013 // In the ELFv2 ABI, in functions that use the TOC register, we need to 01014 // provide two entry points. The ABI guarantees that when calling the 01015 // local entry point, r2 is set up by the caller to contain the TOC base 01016 // for this function, and when calling the global entry point, r12 is set 01017 // up by the caller to hold the address of the global entry point. We 01018 // thus emit a prefix sequence along the following lines: 01019 // 01020 // func: 01021 // # global entry point 01022 // addis r2,r12,(.TOC.-func)@ha 01023 // addi r2,r2,(.TOC.-func)@l 01024 // .localentry func, .-func 01025 // # local entry point, followed by function body 01026 // 01027 // This ensures we have r2 set up correctly while executing the function 01028 // body, no matter which entry point is called. 01029 if (Subtarget.isELFv2ABI() 01030 // Only do all that if the function uses r2 in the first place. 01031 && !MF->getRegInfo().use_empty(PPC::X2)) { 01032 01033 MCSymbol *GlobalEntryLabel = OutContext.CreateTempSymbol(); 01034 OutStreamer.EmitLabel(GlobalEntryLabel); 01035 const MCSymbolRefExpr *GlobalEntryLabelExp = 01036 MCSymbolRefExpr::Create(GlobalEntryLabel, OutContext); 01037 01038 MCSymbol *TOCSymbol = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 01039 const MCExpr *TOCDeltaExpr = 01040 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(TOCSymbol, OutContext), 01041 GlobalEntryLabelExp, OutContext); 01042 01043 const MCExpr *TOCDeltaHi = 01044 PPCMCExpr::CreateHa(TOCDeltaExpr, false, OutContext); 01045 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 01046 .addReg(PPC::X2) 01047 .addReg(PPC::X12) 01048 .addExpr(TOCDeltaHi)); 01049 01050 const MCExpr *TOCDeltaLo = 01051 PPCMCExpr::CreateLo(TOCDeltaExpr, false, OutContext); 01052 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI) 01053 .addReg(PPC::X2) 01054 .addReg(PPC::X2) 01055 .addExpr(TOCDeltaLo)); 01056 01057 MCSymbol *LocalEntryLabel = OutContext.CreateTempSymbol(); 01058 OutStreamer.EmitLabel(LocalEntryLabel); 01059 const MCSymbolRefExpr *LocalEntryLabelExp = 01060 MCSymbolRefExpr::Create(LocalEntryLabel, OutContext); 01061 const MCExpr *LocalOffsetExp = 01062 MCBinaryExpr::CreateSub(LocalEntryLabelExp, 01063 GlobalEntryLabelExp, OutContext); 01064 01065 PPCTargetStreamer *TS = 01066 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 01067 01068 if (TS) 01069 TS->emitLocalEntry(CurrentFnSym, LocalOffsetExp); 01070 } 01071 } 01072 01073 /// EmitFunctionBodyEnd - Print the traceback table before the .size 01074 /// directive. 01075 /// 01076 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 01077 // Only the 64-bit target requires a traceback table. For now, 01078 // we only emit the word of zeroes that GDB requires to find 01079 // the end of the function, and zeroes for the eight-byte 01080 // mandatory fields. 01081 // FIXME: We should fill in the eight-byte mandatory fields as described in 01082 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 01083 // currently make use of these fields). 01084 if (Subtarget.isPPC64()) { 01085 OutStreamer.EmitIntValue(0, 4/*size*/); 01086 OutStreamer.EmitIntValue(0, 8/*size*/); 01087 } 01088 } 01089 01090 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 01091 static const char *const CPUDirectives[] = { 01092 "", 01093 "ppc", 01094 "ppc440", 01095 "ppc601", 01096 "ppc602", 01097 "ppc603", 01098 "ppc7400", 01099 "ppc750", 01100 "ppc970", 01101 "ppcA2", 01102 "ppce500mc", 01103 "ppce5500", 01104 "power3", 01105 "power4", 01106 "power5", 01107 "power5x", 01108 "power6", 01109 "power6x", 01110 "power7", 01111 "ppc64", 01112 "ppc64le" 01113 }; 01114 01115 unsigned Directive = Subtarget.getDarwinDirective(); 01116 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 01117 Directive = PPC::DIR_970; 01118 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 01119 Directive = PPC::DIR_7400; 01120 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 01121 Directive = PPC::DIR_64; 01122 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 01123 01124 assert(Directive < array_lengthof(CPUDirectives) && 01125 "CPUDirectives[] might not be up-to-date!"); 01126 PPCTargetStreamer &TStreamer = 01127 *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 01128 TStreamer.emitMachine(CPUDirectives[Directive]); 01129 01130 // Prime text sections so they are adjacent. This reduces the likelihood a 01131 // large data or debug section causes a branch to exceed 16M limit. 01132 const TargetLoweringObjectFileMachO &TLOFMacho = 01133 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 01134 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 01135 if (TM.getRelocationModel() == Reloc::PIC_) { 01136 OutStreamer.SwitchSection( 01137 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 01138 MachO::S_SYMBOL_STUBS | 01139 MachO::S_ATTR_PURE_INSTRUCTIONS, 01140 32, SectionKind::getText())); 01141 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 01142 OutStreamer.SwitchSection( 01143 OutContext.getMachOSection("__TEXT","__symbol_stub1", 01144 MachO::S_SYMBOL_STUBS | 01145 MachO::S_ATTR_PURE_INSTRUCTIONS, 01146 16, SectionKind::getText())); 01147 } 01148 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 01149 } 01150 01151 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 01152 // Remove $stub suffix, add $lazy_ptr. 01153 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 01154 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 01155 } 01156 01157 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 01158 // Add $tmp suffix to $stub, yielding $stub$tmp. 01159 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 01160 } 01161 01162 void PPCDarwinAsmPrinter:: 01163 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 01164 bool isPPC64 = 01165 TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64; 01166 bool isDarwin = Subtarget.isDarwin(); 01167 01168 const TargetLoweringObjectFileMachO &TLOFMacho = 01169 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 01170 01171 // .lazy_symbol_pointer 01172 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 01173 01174 // Output stubs for dynamically-linked functions 01175 if (TM.getRelocationModel() == Reloc::PIC_) { 01176 const MCSection *StubSection = 01177 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 01178 MachO::S_SYMBOL_STUBS | 01179 MachO::S_ATTR_PURE_INSTRUCTIONS, 01180 32, SectionKind::getText()); 01181 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 01182 OutStreamer.SwitchSection(StubSection); 01183 EmitAlignment(4); 01184 01185 MCSymbol *Stub = Stubs[i].first; 01186 MCSymbol *RawSym = Stubs[i].second.getPointer(); 01187 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 01188 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 01189 01190 OutStreamer.EmitLabel(Stub); 01191 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 01192 01193 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 01194 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 01195 const MCExpr *Sub = 01196 MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); 01197 01198 // mflr r0 01199 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 01200 // bcl 20, 31, AnonSymbol 01201 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 01202 OutStreamer.EmitLabel(AnonSymbol); 01203 // mflr r11 01204 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 01205 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 01206 const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext); 01207 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 01208 .addReg(PPC::R11) 01209 .addReg(PPC::R11) 01210 .addExpr(SubHa16)); 01211 // mtlr r0 01212 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 01213 01214 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 01215 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 01216 const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext); 01217 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 01218 .addReg(PPC::R12) 01219 .addExpr(SubLo16).addExpr(SubLo16) 01220 .addReg(PPC::R11)); 01221 // mtctr r12 01222 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 01223 // bctr 01224 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 01225 01226 OutStreamer.SwitchSection(LSPSection); 01227 OutStreamer.EmitLabel(LazyPtr); 01228 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 01229 01230 MCSymbol *DyldStubBindingHelper = 01231 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 01232 if (isPPC64) { 01233 // .quad dyld_stub_binding_helper 01234 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 01235 } else { 01236 // .long dyld_stub_binding_helper 01237 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 01238 } 01239 } 01240 OutStreamer.AddBlankLine(); 01241 return; 01242 } 01243 01244 const MCSection *StubSection = 01245 OutContext.getMachOSection("__TEXT","__symbol_stub1", 01246 MachO::S_SYMBOL_STUBS | 01247 MachO::S_ATTR_PURE_INSTRUCTIONS, 01248 16, SectionKind::getText()); 01249 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 01250 MCSymbol *Stub = Stubs[i].first; 01251 MCSymbol *RawSym = Stubs[i].second.getPointer(); 01252 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 01253 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 01254 01255 OutStreamer.SwitchSection(StubSection); 01256 EmitAlignment(4); 01257 OutStreamer.EmitLabel(Stub); 01258 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 01259 01260 // lis r11, ha16(LazyPtr) 01261 const MCExpr *LazyPtrHa16 = 01262 PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext); 01263 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS) 01264 .addReg(PPC::R11) 01265 .addExpr(LazyPtrHa16)); 01266 01267 // ldu r12, lo16(LazyPtr)(r11) 01268 // lwzu r12, lo16(LazyPtr)(r11) 01269 const MCExpr *LazyPtrLo16 = 01270 PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext); 01271 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 01272 .addReg(PPC::R12) 01273 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 01274 .addReg(PPC::R11)); 01275 01276 // mtctr r12 01277 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 01278 // bctr 01279 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 01280 01281 OutStreamer.SwitchSection(LSPSection); 01282 OutStreamer.EmitLabel(LazyPtr); 01283 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 01284 01285 MCSymbol *DyldStubBindingHelper = 01286 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 01287 if (isPPC64) { 01288 // .quad dyld_stub_binding_helper 01289 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 01290 } else { 01291 // .long dyld_stub_binding_helper 01292 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 01293 } 01294 } 01295 01296 OutStreamer.AddBlankLine(); 01297 } 01298 01299 01300 bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 01301 bool isPPC64 = 01302 TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64; 01303 01304 // Darwin/PPC always uses mach-o. 01305 const TargetLoweringObjectFileMachO &TLOFMacho = 01306 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 01307 MachineModuleInfoMachO &MMIMacho = 01308 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 01309 01310 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 01311 if (!Stubs.empty()) 01312 EmitFunctionStubs(Stubs); 01313 01314 if (MAI->doesSupportExceptionHandling() && MMI) { 01315 // Add the (possibly multiple) personalities to the set of global values. 01316 // Only referenced functions get into the Personalities list. 01317 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 01318 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 01319 E = Personalities.end(); I != E; ++I) { 01320 if (*I) { 01321 MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 01322 MachineModuleInfoImpl::StubValueTy &StubSym = 01323 MMIMacho.getGVStubEntry(NLPSym); 01324 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true); 01325 } 01326 } 01327 } 01328 01329 // Output stubs for dynamically-linked functions. 01330 Stubs = MMIMacho.GetGVStubList(); 01331 01332 // Output macho stubs for external and common global variables. 01333 if (!Stubs.empty()) { 01334 // Switch with ".non_lazy_symbol_pointer" directive. 01335 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 01336 EmitAlignment(isPPC64 ? 3 : 2); 01337 01338 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 01339 // L_foo$stub: 01340 OutStreamer.EmitLabel(Stubs[i].first); 01341 // .indirect_symbol _foo 01342 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 01343 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 01344 01345 if (MCSym.getInt()) 01346 // External to current translation unit. 01347 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 01348 else 01349 // Internal to current translation unit. 01350 // 01351 // When we place the LSDA into the TEXT section, the type info pointers 01352 // need to be indirect and pc-rel. We accomplish this by using NLPs. 01353 // However, sometimes the types are local to the file. So we need to 01354 // fill in the value for the NLP in those cases. 01355 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 01356 OutContext), 01357 isPPC64 ? 8 : 4/*size*/); 01358 } 01359 01360 Stubs.clear(); 01361 OutStreamer.AddBlankLine(); 01362 } 01363 01364 Stubs = MMIMacho.GetHiddenGVStubList(); 01365 if (!Stubs.empty()) { 01366 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 01367 EmitAlignment(isPPC64 ? 3 : 2); 01368 01369 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 01370 // L_foo$stub: 01371 OutStreamer.EmitLabel(Stubs[i].first); 01372 // .long _foo 01373 OutStreamer.EmitValue(MCSymbolRefExpr:: 01374 Create(Stubs[i].second.getPointer(), 01375 OutContext), 01376 isPPC64 ? 8 : 4/*size*/); 01377 } 01378 01379 Stubs.clear(); 01380 OutStreamer.AddBlankLine(); 01381 } 01382 01383 // Funny Darwin hack: This flag tells the linker that no global symbols 01384 // contain code that falls through to other global symbols (e.g. the obvious 01385 // implementation of multiple entry points). If this doesn't occur, the 01386 // linker can safely perform dead code stripping. Since LLVM never generates 01387 // code that does this, it is always safe to set. 01388 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 01389 01390 return AsmPrinter::doFinalization(M); 01391 } 01392 01393 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 01394 /// for a MachineFunction to the given output stream, in a format that the 01395 /// Darwin assembler can deal with. 01396 /// 01397 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 01398 MCStreamer &Streamer) { 01399 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 01400 01401 if (Subtarget->isDarwin()) 01402 return new PPCDarwinAsmPrinter(tm, Streamer); 01403 return new PPCLinuxAsmPrinter(tm, Streamer); 01404 } 01405 01406 // Force static initialization. 01407 extern "C" void LLVMInitializePowerPCAsmPrinter() { 01408 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 01409 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 01410 TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass); 01411 }