LLVM API Documentation
00001 //===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 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 the shared super class printer that converts from our internal 00011 // representation of machine-dependent LLVM code to Intel and AT&T format 00012 // assembly language. 00013 // This printer is the output mechanism used by `llc'. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "X86AsmPrinter.h" 00018 #include "X86ATTAsmPrinter.h" 00019 #include "X86IntelAsmPrinter.h" 00020 #include "X86Subtarget.h" 00021 #include "llvm/Constants.h" 00022 #include "llvm/Module.h" 00023 #include "llvm/Type.h" 00024 #include "llvm/Assembly/Writer.h" 00025 #include "llvm/Support/Mangler.h" 00026 #include "llvm/Support/CommandLine.h" 00027 using namespace llvm; 00028 00029 Statistic<> llvm::EmittedInsts("asm-printer", 00030 "Number of machine instrs printed"); 00031 00032 enum AsmWriterFlavorTy { att, intel }; 00033 cl::opt<AsmWriterFlavorTy> 00034 AsmWriterFlavor("x86-asm-syntax", 00035 cl::desc("Choose style of code to emit from X86 backend:"), 00036 cl::values( 00037 clEnumVal(att, " Emit AT&T-style assembly"), 00038 clEnumVal(intel, " Emit Intel-style assembly"), 00039 clEnumValEnd), 00040 cl::init(att)); 00041 00042 /// doInitialization 00043 bool X86SharedAsmPrinter::doInitialization(Module &M) { 00044 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); 00045 00046 forDarwin = false; 00047 PrivateGlobalPrefix = ".L"; 00048 00049 switch (Subtarget->TargetType) { 00050 case X86Subtarget::isDarwin: 00051 AlignmentIsInBytes = false; 00052 GlobalPrefix = "_"; 00053 Data64bitsDirective = 0; // we can't emit a 64-bit unit 00054 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 00055 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs 00056 ConstantPoolSection = "\t.const\n"; 00057 LCOMMDirective = "\t.lcomm\t"; 00058 COMMDirectiveTakesAlignment = false; 00059 HasDotTypeDotSizeDirective = false; 00060 forDarwin = true; 00061 StaticCtorsSection = ".mod_init_func"; 00062 StaticDtorsSection = ".mod_term_func"; 00063 InlineAsmStart = InlineAsmEnd = ""; // Don't use #APP/#NO_APP 00064 break; 00065 case X86Subtarget::isCygwin: 00066 GlobalPrefix = "_"; 00067 COMMDirectiveTakesAlignment = false; 00068 HasDotTypeDotSizeDirective = false; 00069 break; 00070 case X86Subtarget::isWindows: 00071 GlobalPrefix = "_"; 00072 HasDotTypeDotSizeDirective = false; 00073 break; 00074 default: break; 00075 } 00076 00077 if (forDarwin) { 00078 // Emit initial debug information. 00079 DW.BeginModule(&M); 00080 } 00081 00082 return AsmPrinter::doInitialization(M); 00083 } 00084 00085 bool X86SharedAsmPrinter::doFinalization(Module &M) { 00086 const TargetData &TD = TM.getTargetData(); 00087 00088 // Print out module-level global variables here. 00089 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00090 I != E; ++I) { 00091 if (!I->hasInitializer()) continue; // External global require no code 00092 00093 // Check to see if this is a special global used by LLVM, if so, emit it. 00094 if (EmitSpecialLLVMGlobal(I)) 00095 continue; 00096 00097 std::string name = Mang->getValueName(I); 00098 Constant *C = I->getInitializer(); 00099 unsigned Size = TD.getTypeSize(C->getType()); 00100 unsigned Align = getPreferredAlignmentLog(I); 00101 00102 if (C->isNullValue() && /* FIXME: Verify correct */ 00103 (I->hasInternalLinkage() || I->hasWeakLinkage() || 00104 I->hasLinkOnceLinkage() || 00105 (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) { 00106 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 00107 if (I->hasExternalLinkage()) { 00108 O << "\t.globl\t" << name << "\n"; 00109 O << "\t.zerofill __DATA__, __common, " << name << ", " 00110 << Size << ", " << Align; 00111 } else { 00112 SwitchSection(".data", I); 00113 if (LCOMMDirective != NULL) { 00114 if (I->hasInternalLinkage()) { 00115 O << LCOMMDirective << name << "," << Size; 00116 if (forDarwin) 00117 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 00118 } else 00119 O << COMMDirective << name << "," << Size; 00120 } else { 00121 if (I->hasInternalLinkage()) 00122 O << "\t.local\t" << name << "\n"; 00123 O << COMMDirective << name << "," << Size; 00124 if (COMMDirectiveTakesAlignment) 00125 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 00126 } 00127 } 00128 O << "\t\t" << CommentString << " " << I->getName() << "\n"; 00129 } else { 00130 switch (I->getLinkage()) { 00131 case GlobalValue::LinkOnceLinkage: 00132 case GlobalValue::WeakLinkage: 00133 if (forDarwin) { 00134 O << "\t.globl " << name << "\n" 00135 << "\t.weak_definition " << name << "\n"; 00136 SwitchSection(".section __DATA,__datacoal_nt,coalesced", I); 00137 } else { 00138 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 00139 O << "\t.weak " << name << "\n"; 00140 } 00141 break; 00142 case GlobalValue::AppendingLinkage: 00143 // FIXME: appending linkage variables should go into a section of 00144 // their name or something. For now, just emit them as external. 00145 case GlobalValue::ExternalLinkage: 00146 // If external or appending, declare as a global symbol 00147 O << "\t.globl " << name << "\n"; 00148 // FALL THROUGH 00149 case GlobalValue::InternalLinkage: 00150 SwitchSection(".data", I); 00151 break; 00152 default: 00153 assert(0 && "Unknown linkage type!"); 00154 } 00155 00156 EmitAlignment(Align, I); 00157 O << name << ":\t\t\t\t" << CommentString << " " << I->getName() 00158 << "\n"; 00159 if (HasDotTypeDotSizeDirective) 00160 O << "\t.size " << name << ", " << Size << "\n"; 00161 00162 EmitGlobalConstant(C); 00163 O << '\n'; 00164 } 00165 } 00166 00167 if (forDarwin) { 00168 SwitchSection("", 0); 00169 00170 // Output stubs for dynamically-linked functions 00171 unsigned j = 1; 00172 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 00173 i != e; ++i, ++j) { 00174 SwitchSection(".section __IMPORT,__jump_table,symbol_stubs," 00175 "self_modifying_code+pure_instructions,5", 0); 00176 O << "L" << *i << "$stub:\n"; 00177 O << "\t.indirect_symbol " << *i << "\n"; 00178 O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; 00179 } 00180 00181 O << "\n"; 00182 00183 // Output stubs for external and common global variables. 00184 if (GVStubs.begin() != GVStubs.end()) 00185 SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); 00186 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); 00187 i != e; ++i) { 00188 O << "L" << *i << "$non_lazy_ptr:\n"; 00189 O << "\t.indirect_symbol " << *i << "\n"; 00190 O << "\t.long\t0\n"; 00191 } 00192 00193 // Emit initial debug information. 00194 DW.EndModule(); 00195 00196 // Funny Darwin hack: This flag tells the linker that no global symbols 00197 // contain code that falls through to other global symbols (e.g. the obvious 00198 // implementation of multiple entry points). If this doesn't occur, the 00199 // linker can safely perform dead code stripping. Since LLVM never 00200 // generates code that does this, it is always safe to set. 00201 O << "\t.subsections_via_symbols\n"; 00202 } 00203 00204 AsmPrinter::doFinalization(M); 00205 return false; // success 00206 } 00207 00208 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 00209 /// for a MachineFunction to the given output stream, using the given target 00210 /// machine description. 00211 /// 00212 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o, 00213 X86TargetMachine &tm){ 00214 switch (AsmWriterFlavor) { 00215 default: 00216 assert(0 && "Unknown asm flavor!"); 00217 case intel: 00218 return new X86IntelAsmPrinter(o, tm); 00219 case att: 00220 return new X86ATTAsmPrinter(o, tm); 00221 } 00222 }