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 #ifdef _MSC_VER 00041 cl::init(intel) 00042 #else 00043 cl::init(att) 00044 #endif 00045 ); 00046 00047 // Out of line virtual function to home classes. 00048 void X86DwarfWriter::virtfn() {} 00049 00050 00051 /// doInitialization 00052 bool X86SharedAsmPrinter::doInitialization(Module &M) { 00053 PrivateGlobalPrefix = ".L"; 00054 DefaultTextSection = ".text"; 00055 DefaultDataSection = ".data"; 00056 00057 switch (Subtarget->TargetType) { 00058 case X86Subtarget::isDarwin: 00059 AlignmentIsInBytes = false; 00060 GlobalPrefix = "_"; 00061 Data64bitsDirective = 0; // we can't emit a 64-bit unit 00062 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 00063 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs 00064 ConstantPoolSection = "\t.const\n"; 00065 JumpTableDataSection = "\t.const\n"; // FIXME: depends on PIC mode 00066 FourByteConstantSection = "\t.literal4\n"; 00067 EightByteConstantSection = "\t.literal8\n"; 00068 LCOMMDirective = "\t.lcomm\t"; 00069 COMMDirectiveTakesAlignment = false; 00070 HasDotTypeDotSizeDirective = false; 00071 StaticCtorsSection = ".mod_init_func"; 00072 StaticDtorsSection = ".mod_term_func"; 00073 InlineAsmStart = "# InlineAsm Start"; 00074 InlineAsmEnd = "# InlineAsm End"; 00075 break; 00076 case X86Subtarget::isCygwin: 00077 GlobalPrefix = "_"; 00078 COMMDirectiveTakesAlignment = false; 00079 HasDotTypeDotSizeDirective = false; 00080 StaticCtorsSection = "\t.section .ctors,\"aw\""; 00081 StaticDtorsSection = "\t.section .dtors,\"aw\""; 00082 break; 00083 case X86Subtarget::isWindows: 00084 GlobalPrefix = "_"; 00085 HasDotTypeDotSizeDirective = false; 00086 break; 00087 default: break; 00088 } 00089 00090 if (Subtarget->isTargetDarwin()) { 00091 // Emit initial debug information. 00092 DW.BeginModule(&M); 00093 } 00094 00095 return AsmPrinter::doInitialization(M); 00096 } 00097 00098 bool X86SharedAsmPrinter::doFinalization(Module &M) { 00099 // Note: this code is not shared by the Intel printer as it is too different 00100 // from how MASM does things. When making changes here don't forget to look 00101 // at X86IntelAsmPrinter::doFinalization(). 00102 const TargetData *TD = TM.getTargetData(); 00103 00104 // Print out module-level global variables here. 00105 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 00106 I != E; ++I) { 00107 if (!I->hasInitializer()) continue; // External global require no code 00108 00109 // Check to see if this is a special global used by LLVM, if so, emit it. 00110 if (EmitSpecialLLVMGlobal(I)) 00111 continue; 00112 00113 std::string name = Mang->getValueName(I); 00114 Constant *C = I->getInitializer(); 00115 unsigned Size = TD->getTypeSize(C->getType()); 00116 unsigned Align = getPreferredAlignmentLog(I); 00117 00118 if (C->isNullValue() && /* FIXME: Verify correct */ 00119 (I->hasInternalLinkage() || I->hasWeakLinkage() || 00120 I->hasLinkOnceLinkage() || 00121 (Subtarget->isTargetDarwin() && 00122 I->hasExternalLinkage() && !I->hasSection()))) { 00123 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 00124 if (I->hasExternalLinkage()) { 00125 O << "\t.globl\t" << name << "\n"; 00126 O << "\t.zerofill __DATA__, __common, " << name << ", " 00127 << Size << ", " << Align; 00128 } else { 00129 SwitchToDataSection(DefaultDataSection, I); 00130 if (LCOMMDirective != NULL) { 00131 if (I->hasInternalLinkage()) { 00132 O << LCOMMDirective << name << "," << Size; 00133 if (Subtarget->isTargetDarwin()) 00134 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 00135 } else 00136 O << COMMDirective << name << "," << Size; 00137 } else { 00138 if (Subtarget->TargetType != X86Subtarget::isCygwin) { 00139 if (I->hasInternalLinkage()) 00140 O << "\t.local\t" << name << "\n"; 00141 } 00142 O << COMMDirective << name << "," << Size; 00143 if (COMMDirectiveTakesAlignment) 00144 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 00145 } 00146 } 00147 O << "\t\t" << CommentString << " " << I->getName() << "\n"; 00148 } else { 00149 switch (I->getLinkage()) { 00150 case GlobalValue::LinkOnceLinkage: 00151 case GlobalValue::WeakLinkage: 00152 if (Subtarget->isTargetDarwin()) { 00153 O << "\t.globl " << name << "\n" 00154 << "\t.weak_definition " << name << "\n"; 00155 SwitchToDataSection(".section __DATA,__const_coal,coalesced", I); 00156 } else if (Subtarget->TargetType == X86Subtarget::isCygwin) { 00157 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\"\n" 00158 << "\t.weak " << name << "\n"; 00159 } else { 00160 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n" 00161 << "\t.weak " << name << "\n"; 00162 } 00163 break; 00164 case GlobalValue::AppendingLinkage: 00165 // FIXME: appending linkage variables should go into a section of 00166 // their name or something. For now, just emit them as external. 00167 case GlobalValue::ExternalLinkage: 00168 // If external or appending, declare as a global symbol 00169 O << "\t.globl " << name << "\n"; 00170 // FALL THROUGH 00171 case GlobalValue::InternalLinkage: 00172 SwitchToDataSection(DefaultDataSection, I); 00173 break; 00174 default: 00175 assert(0 && "Unknown linkage type!"); 00176 } 00177 00178 EmitAlignment(Align, I); 00179 O << name << ":\t\t\t\t" << CommentString << " " << I->getName() 00180 << "\n"; 00181 if (HasDotTypeDotSizeDirective) 00182 O << "\t.size " << name << ", " << Size << "\n"; 00183 00184 EmitGlobalConstant(C); 00185 O << '\n'; 00186 } 00187 } 00188 00189 if (Subtarget->isTargetDarwin()) { 00190 SwitchToDataSection("", 0); 00191 00192 // Output stubs for dynamically-linked functions 00193 unsigned j = 1; 00194 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 00195 i != e; ++i, ++j) { 00196 SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs," 00197 "self_modifying_code+pure_instructions,5", 0); 00198 O << "L" << *i << "$stub:\n"; 00199 O << "\t.indirect_symbol " << *i << "\n"; 00200 O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; 00201 } 00202 00203 O << "\n"; 00204 00205 // Output stubs for external and common global variables. 00206 if (GVStubs.begin() != GVStubs.end()) 00207 SwitchToDataSection( 00208 ".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); 00209 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); 00210 i != e; ++i) { 00211 O << "L" << *i << "$non_lazy_ptr:\n"; 00212 O << "\t.indirect_symbol " << *i << "\n"; 00213 O << "\t.long\t0\n"; 00214 } 00215 00216 // Emit initial debug information. 00217 DW.EndModule(); 00218 00219 // Funny Darwin hack: This flag tells the linker that no global symbols 00220 // contain code that falls through to other global symbols (e.g. the obvious 00221 // implementation of multiple entry points). If this doesn't occur, the 00222 // linker can safely perform dead code stripping. Since LLVM never 00223 // generates code that does this, it is always safe to set. 00224 O << "\t.subsections_via_symbols\n"; 00225 } 00226 00227 AsmPrinter::doFinalization(M); 00228 return false; // success 00229 } 00230 00231 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 00232 /// for a MachineFunction to the given output stream, using the given target 00233 /// machine description. 00234 /// 00235 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o, 00236 X86TargetMachine &tm){ 00237 switch (AsmWriterFlavor) { 00238 default: 00239 assert(0 && "Unknown asm flavor!"); 00240 case intel: 00241 return new X86IntelAsmPrinter(o, tm); 00242 case att: 00243 return new X86ATTAsmPrinter(o, tm); 00244 } 00245 }