LLVM API Documentation
00001 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source 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 #define DEBUG_TYPE "asmprinter" 00020 #include "PPC.h" 00021 #include "PPCTargetMachine.h" 00022 #include "PPCSubtarget.h" 00023 #include "llvm/Constants.h" 00024 #include "llvm/DerivedTypes.h" 00025 #include "llvm/Module.h" 00026 #include "llvm/Assembly/Writer.h" 00027 #include "llvm/CodeGen/AsmPrinter.h" 00028 #include "llvm/CodeGen/DwarfWriter.h" 00029 #include "llvm/CodeGen/MachineDebugInfo.h" 00030 #include "llvm/CodeGen/MachineFunctionPass.h" 00031 #include "llvm/CodeGen/MachineInstr.h" 00032 #include "llvm/Support/Mangler.h" 00033 #include "llvm/Support/MathExtras.h" 00034 #include "llvm/Support/CommandLine.h" 00035 #include "llvm/Support/Debug.h" 00036 #include "llvm/Support/Visibility.h" 00037 #include "llvm/Target/MRegisterInfo.h" 00038 #include "llvm/Target/TargetInstrInfo.h" 00039 #include "llvm/Target/TargetOptions.h" 00040 #include "llvm/ADT/Statistic.h" 00041 #include "llvm/ADT/StringExtras.h" 00042 #include <iostream> 00043 #include <set> 00044 using namespace llvm; 00045 00046 namespace { 00047 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 00048 00049 class VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter { 00050 public: 00051 std::set<std::string> FnStubs, GVStubs; 00052 00053 PPCAsmPrinter(std::ostream &O, TargetMachine &TM) 00054 : AsmPrinter(O, TM) {} 00055 00056 virtual const char *getPassName() const { 00057 return "PowerPC Assembly Printer"; 00058 } 00059 00060 PPCTargetMachine &getTM() { 00061 return static_cast<PPCTargetMachine&>(TM); 00062 } 00063 00064 unsigned enumRegToMachineReg(unsigned enumReg) { 00065 switch (enumReg) { 00066 default: assert(0 && "Unhandled register!"); break; 00067 case PPC::CR0: return 0; 00068 case PPC::CR1: return 1; 00069 case PPC::CR2: return 2; 00070 case PPC::CR3: return 3; 00071 case PPC::CR4: return 4; 00072 case PPC::CR5: return 5; 00073 case PPC::CR6: return 6; 00074 case PPC::CR7: return 7; 00075 } 00076 abort(); 00077 } 00078 00079 /// printInstruction - This method is automatically generated by tablegen 00080 /// from the instruction set description. This method returns true if the 00081 /// machine instruction was sufficiently described to print it, otherwise it 00082 /// returns false. 00083 bool printInstruction(const MachineInstr *MI); 00084 00085 void printMachineInstruction(const MachineInstr *MI); 00086 void printOp(const MachineOperand &MO); 00087 00088 void printOperand(const MachineInstr *MI, unsigned OpNo) { 00089 const MachineOperand &MO = MI->getOperand(OpNo); 00090 if (MO.isRegister()) { 00091 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); 00092 O << TM.getRegisterInfo()->get(MO.getReg()).Name; 00093 } else if (MO.isImmediate()) { 00094 O << MO.getImmedValue(); 00095 } else { 00096 printOp(MO); 00097 } 00098 } 00099 00100 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00101 unsigned AsmVariant, const char *ExtraCode); 00102 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00103 unsigned AsmVariant, const char *ExtraCode); 00104 00105 00106 void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00107 char value = MI->getOperand(OpNo).getImmedValue(); 00108 value = (value << (32-5)) >> (32-5); 00109 O << (int)value; 00110 } 00111 void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00112 unsigned char value = MI->getOperand(OpNo).getImmedValue(); 00113 assert(value <= 31 && "Invalid u5imm argument!"); 00114 O << (unsigned int)value; 00115 } 00116 void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00117 unsigned char value = MI->getOperand(OpNo).getImmedValue(); 00118 assert(value <= 63 && "Invalid u6imm argument!"); 00119 O << (unsigned int)value; 00120 } 00121 void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00122 O << (short)MI->getOperand(OpNo).getImmedValue(); 00123 } 00124 void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00125 O << (unsigned short)MI->getOperand(OpNo).getImmedValue(); 00126 } 00127 void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) { 00128 O << (short)(MI->getOperand(OpNo).getImmedValue()*4); 00129 } 00130 void printBranchOperand(const MachineInstr *MI, unsigned OpNo) { 00131 // Branches can take an immediate operand. This is used by the branch 00132 // selection pass to print $+8, an eight byte displacement from the PC. 00133 if (MI->getOperand(OpNo).isImmediate()) { 00134 O << "$+" << MI->getOperand(OpNo).getImmedValue(); 00135 } else { 00136 printOp(MI->getOperand(OpNo)); 00137 } 00138 } 00139 void printCallOperand(const MachineInstr *MI, unsigned OpNo) { 00140 const MachineOperand &MO = MI->getOperand(OpNo); 00141 if (TM.getRelocationModel() != Reloc::Static) { 00142 if (MO.getType() == MachineOperand::MO_GlobalAddress) { 00143 GlobalValue *GV = MO.getGlobal(); 00144 if (((GV->isExternal() || GV->hasWeakLinkage() || 00145 GV->hasLinkOnceLinkage()))) { 00146 // Dynamically-resolved functions need a stub for the function. 00147 std::string Name = Mang->getValueName(GV); 00148 FnStubs.insert(Name); 00149 O << "L" << Name << "$stub"; 00150 return; 00151 } 00152 } 00153 if (MO.getType() == MachineOperand::MO_ExternalSymbol) { 00154 std::string Name(GlobalPrefix); Name += MO.getSymbolName(); 00155 FnStubs.insert(Name); 00156 O << "L" << Name << "$stub"; 00157 return; 00158 } 00159 } 00160 00161 printOp(MI->getOperand(OpNo)); 00162 } 00163 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) { 00164 O << (int)MI->getOperand(OpNo).getImmedValue()*4; 00165 } 00166 void printPICLabel(const MachineInstr *MI, unsigned OpNo) { 00167 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 00168 O << "\"L" << getFunctionNumber() << "$pb\":"; 00169 } 00170 void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { 00171 if (MI->getOperand(OpNo).isImmediate()) { 00172 printS16ImmOperand(MI, OpNo); 00173 } else { 00174 O << "ha16("; 00175 printOp(MI->getOperand(OpNo)); 00176 if (TM.getRelocationModel() == Reloc::PIC_) 00177 O << "-\"L" << getFunctionNumber() << "$pb\")"; 00178 else 00179 O << ')'; 00180 } 00181 } 00182 void printSymbolLo(const MachineInstr *MI, unsigned OpNo) { 00183 if (MI->getOperand(OpNo).isImmediate()) { 00184 printS16ImmOperand(MI, OpNo); 00185 } else { 00186 O << "lo16("; 00187 printOp(MI->getOperand(OpNo)); 00188 if (TM.getRelocationModel() == Reloc::PIC_) 00189 O << "-\"L" << getFunctionNumber() << "$pb\")"; 00190 else 00191 O << ')'; 00192 } 00193 } 00194 void printcrbitm(const MachineInstr *MI, unsigned OpNo) { 00195 unsigned CCReg = MI->getOperand(OpNo).getReg(); 00196 unsigned RegNo = enumRegToMachineReg(CCReg); 00197 O << (0x80 >> RegNo); 00198 } 00199 // The new addressing mode printers. 00200 void printMemRegImm(const MachineInstr *MI, unsigned OpNo) { 00201 printSymbolLo(MI, OpNo); 00202 O << '('; 00203 if (MI->getOperand(OpNo+1).isRegister() && 00204 MI->getOperand(OpNo+1).getReg() == PPC::R0) 00205 O << "0"; 00206 else 00207 printOperand(MI, OpNo+1); 00208 O << ')'; 00209 } 00210 void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) { 00211 if (MI->getOperand(OpNo).isImmediate()) 00212 printS16X4ImmOperand(MI, OpNo); 00213 else 00214 printSymbolLo(MI, OpNo); 00215 O << '('; 00216 if (MI->getOperand(OpNo+1).isRegister() && 00217 MI->getOperand(OpNo+1).getReg() == PPC::R0) 00218 O << "0"; 00219 else 00220 printOperand(MI, OpNo+1); 00221 O << ')'; 00222 } 00223 00224 void printMemRegReg(const MachineInstr *MI, unsigned OpNo) { 00225 // When used as the base register, r0 reads constant zero rather than 00226 // the value contained in the register. For this reason, the darwin 00227 // assembler requires that we print r0 as 0 (no r) when used as the base. 00228 const MachineOperand &MO = MI->getOperand(OpNo); 00229 if (MO.getReg() == PPC::R0) 00230 O << '0'; 00231 else 00232 O << TM.getRegisterInfo()->get(MO.getReg()).Name; 00233 O << ", "; 00234 printOperand(MI, OpNo+1); 00235 } 00236 00237 virtual bool runOnMachineFunction(MachineFunction &F) = 0; 00238 virtual bool doFinalization(Module &M) = 0; 00239 00240 }; 00241 00242 /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X 00243 /// 00244 struct VISIBILITY_HIDDEN DarwinDwarfWriter : public DwarfWriter { 00245 // Ctor. 00246 DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap) 00247 : DwarfWriter(o, ap) 00248 { 00249 needsSet = true; 00250 DwarfAbbrevSection = ".section __DWARF,__debug_abbrev"; 00251 DwarfInfoSection = ".section __DWARF,__debug_info"; 00252 DwarfLineSection = ".section __DWARF,__debug_line"; 00253 DwarfFrameSection = ".section __DWARF,__debug_frame"; 00254 DwarfPubNamesSection = ".section __DWARF,__debug_pubnames"; 00255 DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes"; 00256 DwarfStrSection = ".section __DWARF,__debug_str"; 00257 DwarfLocSection = ".section __DWARF,__debug_loc"; 00258 DwarfARangesSection = ".section __DWARF,__debug_aranges"; 00259 DwarfRangesSection = ".section __DWARF,__debug_ranges"; 00260 DwarfMacInfoSection = ".section __DWARF,__debug_macinfo"; 00261 TextSection = ".text"; 00262 DataSection = ".data"; 00263 } 00264 }; 00265 00266 /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS 00267 /// X 00268 struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter { 00269 00270 DarwinDwarfWriter DW; 00271 00272 DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM) 00273 : PPCAsmPrinter(O, TM), DW(O, this) { 00274 bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); 00275 CommentString = ";"; 00276 GlobalPrefix = "_"; 00277 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs 00278 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 00279 if (isPPC64) 00280 Data64bitsDirective = ".quad\t"; // we can't emit a 64-bit unit 00281 else 00282 Data64bitsDirective = 0; // we can't emit a 64-bit unit 00283 AlignmentIsInBytes = false; // Alignment is by power of 2. 00284 ConstantPoolSection = "\t.const\t"; 00285 JumpTableDataSection = ".const"; 00286 JumpTableTextSection = "\t.text"; 00287 LCOMMDirective = "\t.lcomm\t"; 00288 StaticCtorsSection = ".mod_init_func"; 00289 StaticDtorsSection = ".mod_term_func"; 00290 InlineAsmStart = "# InlineAsm Start"; 00291 InlineAsmEnd = "# InlineAsm End"; 00292 } 00293 00294 virtual const char *getPassName() const { 00295 return "Darwin PPC Assembly Printer"; 00296 } 00297 00298 bool runOnMachineFunction(MachineFunction &F); 00299 bool doInitialization(Module &M); 00300 bool doFinalization(Module &M); 00301 00302 void getAnalysisUsage(AnalysisUsage &AU) const { 00303 AU.setPreservesAll(); 00304 AU.addRequired<MachineDebugInfo>(); 00305 PPCAsmPrinter::getAnalysisUsage(AU); 00306 } 00307 00308 }; 00309 } // end of anonymous namespace 00310 00311 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly 00312 /// code for a MachineFunction to the given output stream, in a format that the 00313 /// Darwin assembler can deal with. 00314 /// 00315 FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, 00316 PPCTargetMachine &tm) { 00317 return new DarwinAsmPrinter(o, tm); 00318 } 00319 00320 // Include the auto-generated portion of the assembly writer 00321 #include "PPCGenAsmWriter.inc" 00322 00323 void PPCAsmPrinter::printOp(const MachineOperand &MO) { 00324 switch (MO.getType()) { 00325 case MachineOperand::MO_Immediate: 00326 std::cerr << "printOp() does not handle immediate values\n"; 00327 abort(); 00328 return; 00329 00330 case MachineOperand::MO_MachineBasicBlock: 00331 printBasicBlockLabel(MO.getMachineBasicBlock()); 00332 return; 00333 case MachineOperand::MO_JumpTableIndex: 00334 O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() 00335 << '_' << MO.getJumpTableIndex(); 00336 // FIXME: PIC relocation model 00337 return; 00338 case MachineOperand::MO_ConstantPoolIndex: 00339 O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() 00340 << '_' << MO.getConstantPoolIndex(); 00341 return; 00342 case MachineOperand::MO_ExternalSymbol: 00343 // Computing the address of an external symbol, not calling it. 00344 if (TM.getRelocationModel() != Reloc::Static) { 00345 std::string Name(GlobalPrefix); Name += MO.getSymbolName(); 00346 GVStubs.insert(Name); 00347 O << "L" << Name << "$non_lazy_ptr"; 00348 return; 00349 } 00350 O << GlobalPrefix << MO.getSymbolName(); 00351 return; 00352 case MachineOperand::MO_GlobalAddress: { 00353 // Computing the address of a global symbol, not calling it. 00354 GlobalValue *GV = MO.getGlobal(); 00355 std::string Name = Mang->getValueName(GV); 00356 int offset = MO.getOffset(); 00357 00358 // External or weakly linked global variables need non-lazily-resolved stubs 00359 if (TM.getRelocationModel() != Reloc::Static) { 00360 if (((GV->isExternal() || GV->hasWeakLinkage() || 00361 GV->hasLinkOnceLinkage()))) { 00362 GVStubs.insert(Name); 00363 O << "L" << Name << "$non_lazy_ptr"; 00364 return; 00365 } 00366 } 00367 00368 O << Name; 00369 return; 00370 } 00371 00372 default: 00373 O << "<unknown operand type: " << MO.getType() << ">"; 00374 return; 00375 } 00376 } 00377 00378 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00379 /// 00380 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00381 unsigned AsmVariant, 00382 const char *ExtraCode) { 00383 // Does this asm operand have a single letter operand modifier? 00384 if (ExtraCode && ExtraCode[0]) { 00385 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00386 00387 switch (ExtraCode[0]) { 00388 default: return true; // Unknown modifier. 00389 case 'L': // Write second word of DImode reference. 00390 // Verify that this operand has two consecutive registers. 00391 if (!MI->getOperand(OpNo).isRegister() || 00392 OpNo+1 == MI->getNumOperands() || 00393 !MI->getOperand(OpNo+1).isRegister()) 00394 return true; 00395 ++OpNo; // Return the high-part. 00396 break; 00397 } 00398 } 00399 00400 printOperand(MI, OpNo); 00401 return false; 00402 } 00403 00404 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00405 unsigned AsmVariant, 00406 const char *ExtraCode) { 00407 if (ExtraCode && ExtraCode[0]) 00408 return true; // Unknown modifier. 00409 printMemRegReg(MI, OpNo); 00410 return false; 00411 } 00412 00413 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to 00414 /// the current output stream. 00415 /// 00416 void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 00417 ++EmittedInsts; 00418 00419 // Check for slwi/srwi mnemonics. 00420 if (MI->getOpcode() == PPC::RLWINM) { 00421 bool FoundMnemonic = false; 00422 unsigned char SH = MI->getOperand(2).getImmedValue(); 00423 unsigned char MB = MI->getOperand(3).getImmedValue(); 00424 unsigned char ME = MI->getOperand(4).getImmedValue(); 00425 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 00426 O << "slwi "; FoundMnemonic = true; 00427 } 00428 if (SH <= 31 && MB == (32-SH) && ME == 31) { 00429 O << "srwi "; FoundMnemonic = true; 00430 SH = 32-SH; 00431 } 00432 if (FoundMnemonic) { 00433 printOperand(MI, 0); 00434 O << ", "; 00435 printOperand(MI, 1); 00436 O << ", " << (unsigned int)SH << "\n"; 00437 return; 00438 } 00439 } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) { 00440 if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 00441 O << "mr "; 00442 printOperand(MI, 0); 00443 O << ", "; 00444 printOperand(MI, 1); 00445 O << "\n"; 00446 return; 00447 } 00448 } 00449 00450 if (printInstruction(MI)) 00451 return; // Printer was automatically generated 00452 00453 assert(0 && "Unhandled instruction in asm writer!"); 00454 abort(); 00455 return; 00456 } 00457 00458 /// runOnMachineFunction - This uses the printMachineInstruction() 00459 /// method to print assembly for each instruction. 00460 /// 00461 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00462 DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>()); 00463 00464 SetupMachineFunction(MF); 00465 O << "\n\n"; 00466 00467 // Print out constants referenced by the function 00468 EmitConstantPool(MF.getConstantPool()); 00469 00470 // Print out jump tables referenced by the function 00471 EmitJumpTableInfo(MF.getJumpTableInfo()); 00472 00473 // Print out labels for the function. 00474 const Function *F = MF.getFunction(); 00475 switch (F->getLinkage()) { 00476 default: assert(0 && "Unknown linkage type!"); 00477 case Function::InternalLinkage: // Symbols default to internal. 00478 SwitchToTextSection("\t.text", F); 00479 break; 00480 case Function::ExternalLinkage: 00481 SwitchToTextSection("\t.text", F); 00482 O << "\t.globl\t" << CurrentFnName << "\n"; 00483 break; 00484 case Function::WeakLinkage: 00485 case Function::LinkOnceLinkage: 00486 SwitchToTextSection( 00487 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F); 00488 O << "\t.globl\t" << CurrentFnName << "\n"; 00489 O << "\t.weak_definition\t" << CurrentFnName << "\n"; 00490 break; 00491 } 00492 EmitAlignment(4, F); 00493 O << CurrentFnName << ":\n"; 00494 00495 // Emit pre-function debug information. 00496 DW.BeginFunction(&MF); 00497 00498 // Print out code for the function. 00499 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00500 I != E; ++I) { 00501 // Print a label for the basic block. 00502 if (I != MF.begin()) { 00503 printBasicBlockLabel(I, true); 00504 O << '\n'; 00505 } 00506 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00507 II != E; ++II) { 00508 // Print the assembly for the instruction. 00509 O << "\t"; 00510 printMachineInstruction(II); 00511 } 00512 } 00513 00514 // Emit post-function debug information. 00515 DW.EndFunction(); 00516 00517 // We didn't modify anything. 00518 return false; 00519 } 00520 00521 00522 bool DarwinAsmPrinter::doInitialization(Module &M) { 00523 if (TM.getSubtarget<PPCSubtarget>().isGigaProcessor()) 00524 O << "\t.machine ppc970\n"; 00525 AsmPrinter::doInitialization(M); 00526 00527 // Darwin wants symbols to be quoted if they have complex names. 00528 Mang->setUseQuotes(true); 00529 00530 // Emit initial debug information. 00531 DW.BeginModule(&M); 00532 return false; 00533 } 00534 00535 bool DarwinAsmPrinter::doFinalization(Module &M) { 00536 const TargetData *TD = TM.getTargetData(); 00537 00538 // Print out module-level global variables here. 00539 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00540 I != E; ++I) { 00541 if (!I->hasInitializer()) continue; // External global require no code 00542 00543 // Check to see if this is a special global used by LLVM, if so, emit it. 00544 if (EmitSpecialLLVMGlobal(I)) 00545 continue; 00546 00547 std::string name = Mang->getValueName(I); 00548 Constant *C = I->getInitializer(); 00549 unsigned Size = TD->getTypeSize(C->getType()); 00550 unsigned Align = getPreferredAlignmentLog(I); 00551 00552 if (C->isNullValue() && /* FIXME: Verify correct */ 00553 (I->hasInternalLinkage() || I->hasWeakLinkage() || 00554 I->hasLinkOnceLinkage() || 00555 (I->hasExternalLinkage() && !I->hasSection()))) { 00556 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 00557 if (I->hasExternalLinkage()) { 00558 O << "\t.globl " << name << '\n'; 00559 O << "\t.zerofill __DATA, __common, " << name << ", " 00560 << Size << ", " << Align; 00561 } else if (I->hasInternalLinkage()) { 00562 SwitchToDataSection("\t.data", I); 00563 O << LCOMMDirective << name << "," << Size << "," << Align; 00564 } else { 00565 SwitchToDataSection("\t.data", I); 00566 O << ".comm " << name << "," << Size; 00567 } 00568 O << "\t\t; '" << I->getName() << "'\n"; 00569 } else { 00570 switch (I->getLinkage()) { 00571 case GlobalValue::LinkOnceLinkage: 00572 case GlobalValue::WeakLinkage: 00573 O << "\t.globl " << name << '\n' 00574 << "\t.weak_definition " << name << '\n'; 00575 SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I); 00576 break; 00577 case GlobalValue::AppendingLinkage: 00578 // FIXME: appending linkage variables should go into a section of 00579 // their name or something. For now, just emit them as external. 00580 case GlobalValue::ExternalLinkage: 00581 // If external or appending, declare as a global symbol 00582 O << "\t.globl " << name << "\n"; 00583 // FALL THROUGH 00584 case GlobalValue::InternalLinkage: 00585 SwitchToDataSection("\t.data", I); 00586 break; 00587 default: 00588 std::cerr << "Unknown linkage type!"; 00589 abort(); 00590 } 00591 00592 EmitAlignment(Align, I); 00593 O << name << ":\t\t\t\t; '" << I->getName() << "'\n"; 00594 EmitGlobalConstant(C); 00595 O << '\n'; 00596 } 00597 } 00598 00599 bool isPPC64 = TD->getPointerSizeInBits() == 64; 00600 00601 // Output stubs for dynamically-linked functions 00602 if (TM.getRelocationModel() == Reloc::PIC_) { 00603 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 00604 i != e; ++i) { 00605 SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs," 00606 "pure_instructions,32", 0); 00607 EmitAlignment(4); 00608 O << "L" << *i << "$stub:\n"; 00609 O << "\t.indirect_symbol " << *i << "\n"; 00610 O << "\tmflr r0\n"; 00611 O << "\tbcl 20,31,L0$" << *i << "\n"; 00612 O << "L0$" << *i << ":\n"; 00613 O << "\tmflr r11\n"; 00614 O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n"; 00615 O << "\tmtlr r0\n"; 00616 if (isPPC64) 00617 O << "\tldu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 00618 else 00619 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 00620 O << "\tmtctr r12\n"; 00621 O << "\tbctr\n"; 00622 SwitchToDataSection(".lazy_symbol_pointer", 0); 00623 O << "L" << *i << "$lazy_ptr:\n"; 00624 O << "\t.indirect_symbol " << *i << "\n"; 00625 if (isPPC64) 00626 O << "\t.quad dyld_stub_binding_helper\n"; 00627 else 00628 O << "\t.long dyld_stub_binding_helper\n"; 00629 } 00630 } else { 00631 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 00632 i != e; ++i) { 00633 SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs," 00634 "pure_instructions,16", 0); 00635 EmitAlignment(4); 00636 O << "L" << *i << "$stub:\n"; 00637 O << "\t.indirect_symbol " << *i << "\n"; 00638 O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n"; 00639 if (isPPC64) 00640 O << "\tldu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; 00641 else 00642 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; 00643 O << "\tmtctr r12\n"; 00644 O << "\tbctr\n"; 00645 SwitchToDataSection(".lazy_symbol_pointer", 0); 00646 O << "L" << *i << "$lazy_ptr:\n"; 00647 O << "\t.indirect_symbol " << *i << "\n"; 00648 if (isPPC64) 00649 O << "\t.quad dyld_stub_binding_helper\n"; 00650 else 00651 O << "\t.long dyld_stub_binding_helper\n"; 00652 } 00653 } 00654 00655 O << "\n"; 00656 00657 // Output stubs for external and common global variables. 00658 if (GVStubs.begin() != GVStubs.end()) { 00659 SwitchToDataSection(".non_lazy_symbol_pointer", 0); 00660 for (std::set<std::string>::iterator I = GVStubs.begin(), 00661 E = GVStubs.end(); I != E; ++I) { 00662 O << "L" << *I << "$non_lazy_ptr:\n"; 00663 O << "\t.indirect_symbol " << *I << "\n"; 00664 if (isPPC64) 00665 O << "\t.quad\t0\n"; 00666 else 00667 O << "\t.long\t0\n"; 00668 00669 } 00670 } 00671 00672 // Emit initial debug information. 00673 DW.EndModule(); 00674 00675 // Funny Darwin hack: This flag tells the linker that no global symbols 00676 // contain code that falls through to other global symbols (e.g. the obvious 00677 // implementation of multiple entry points). If this doesn't occur, the 00678 // linker can safely perform dead code stripping. Since LLVM never generates 00679 // code that does this, it is always safe to set. 00680 O << "\t.subsections_via_symbols\n"; 00681 00682 AsmPrinter::doFinalization(M); 00683 return false; // success 00684 } 00685