X86AsmPrinter.cpp revision 3c992d291bc67d9ce9d742d586d24ade9a577c99
1//===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file the shared super class printer that converts from our internal 11// representation of machine-dependent LLVM code to Intel and AT&T format 12// assembly language. 13// This printer is the output mechanism used by `llc'. 14// 15//===----------------------------------------------------------------------===// 16 17#include "X86ATTAsmPrinter.h" 18#include "X86IntelAsmPrinter.h" 19#include "X86Subtarget.h" 20#include "X86.h" 21#include "llvm/Constants.h" 22#include "llvm/Module.h" 23#include "llvm/Type.h" 24#include "llvm/Assembly/Writer.h" 25#include "llvm/Support/Mangler.h" 26#include "llvm/Support/CommandLine.h" 27using namespace llvm; 28using namespace x86; 29 30Statistic<> llvm::x86::EmittedInsts("asm-printer", 31 "Number of machine instrs printed"); 32 33enum AsmWriterFlavorTy { att, intel }; 34cl::opt<AsmWriterFlavorTy> 35AsmWriterFlavor("x86-asm-syntax", 36 cl::desc("Choose style of code to emit from X86 backend:"), 37 cl::values( 38 clEnumVal(att, " Emit AT&T-style assembly"), 39 clEnumVal(intel, " Emit Intel-style assembly"), 40 clEnumValEnd), 41 cl::init(att)); 42 43/// doInitialization 44bool X86SharedAsmPrinter::doInitialization(Module &M) { 45 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>(); 46 47 forDarwin = false; 48 PrivateGlobalPrefix = ".L"; 49 50 switch (Subtarget->TargetType) { 51 case X86Subtarget::isDarwin: 52 AlignmentIsInBytes = false; 53 GlobalPrefix = "_"; 54 Data64bitsDirective = 0; // we can't emit a 64-bit unit 55 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 56 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs 57 ConstantPoolSection = "\t.const\n"; 58 LCOMMDirective = "\t.lcomm\t"; 59 COMMDirectiveTakesAlignment = false; 60 HasDotTypeDotSizeDirective = false; 61 forDarwin = true; 62 StaticCtorsSection = ".mod_init_func"; 63 StaticDtorsSection = ".mod_term_func"; 64 InlineAsmStart = InlineAsmEnd = ""; // Don't use #APP/#NO_APP 65 break; 66 case X86Subtarget::isCygwin: 67 GlobalPrefix = "_"; 68 COMMDirectiveTakesAlignment = false; 69 HasDotTypeDotSizeDirective = false; 70 break; 71 case X86Subtarget::isWindows: 72 GlobalPrefix = "_"; 73 HasDotTypeDotSizeDirective = false; 74 break; 75 default: break; 76 } 77 78 // Emit initial debug information. 79 DW.BeginModule(M); 80 81 return AsmPrinter::doInitialization(M); 82} 83 84bool X86SharedAsmPrinter::doFinalization(Module &M) { 85 const TargetData &TD = TM.getTargetData(); 86 87 // Print out module-level global variables here. 88 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 89 I != E; ++I) { 90 if (!I->hasInitializer()) continue; // External global require no code 91 92 // Check to see if this is a special global used by LLVM, if so, emit it. 93 if (I->hasAppendingLinkage() && EmitSpecialLLVMGlobal(I)) 94 continue; 95 96 std::string name = Mang->getValueName(I); 97 Constant *C = I->getInitializer(); 98 unsigned Size = TD.getTypeSize(C->getType()); 99 unsigned Align = getPreferredAlignmentLog(I); 100 101 if (C->isNullValue() && /* FIXME: Verify correct */ 102 (I->hasInternalLinkage() || I->hasWeakLinkage() || 103 I->hasLinkOnceLinkage() || 104 (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) { 105 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 106 if (I->hasExternalLinkage()) { 107 O << "\t.globl\t" << name << "\n"; 108 O << "\t.zerofill __DATA__, __common, " << name << ", " 109 << Size << ", " << Align; 110 } else { 111 SwitchSection(".data", I); 112 if (LCOMMDirective != NULL) { 113 if (I->hasInternalLinkage()) { 114 O << LCOMMDirective << name << "," << Size; 115 if (forDarwin) 116 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 117 } else 118 O << COMMDirective << name << "," << Size; 119 } else { 120 if (I->hasInternalLinkage()) 121 O << "\t.local\t" << name << "\n"; 122 O << COMMDirective << name << "," << Size; 123 if (COMMDirectiveTakesAlignment) 124 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align); 125 } 126 } 127 O << "\t\t" << CommentString << " " << I->getName() << "\n"; 128 } else { 129 switch (I->getLinkage()) { 130 case GlobalValue::LinkOnceLinkage: 131 case GlobalValue::WeakLinkage: 132 if (forDarwin) { 133 O << "\t.globl " << name << "\n" 134 << "\t.weak_definition " << name << "\n"; 135 SwitchSection(".section __DATA,__datacoal_nt,coalesced", I); 136 } else { 137 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 138 O << "\t.weak " << name << "\n"; 139 } 140 break; 141 case GlobalValue::AppendingLinkage: 142 // FIXME: appending linkage variables should go into a section of 143 // their name or something. For now, just emit them as external. 144 case GlobalValue::ExternalLinkage: 145 // If external or appending, declare as a global symbol 146 O << "\t.globl " << name << "\n"; 147 // FALL THROUGH 148 case GlobalValue::InternalLinkage: 149 SwitchSection(".data", I); 150 break; 151 default: 152 assert(0 && "Unknown linkage type!"); 153 } 154 155 EmitAlignment(Align, I); 156 O << name << ":\t\t\t\t" << CommentString << " " << I->getName() 157 << "\n"; 158 if (HasDotTypeDotSizeDirective) 159 O << "\t.size " << name << ", " << Size << "\n"; 160 161 EmitGlobalConstant(C); 162 O << '\n'; 163 } 164 } 165 166 if (forDarwin) { 167 SwitchSection("", 0); 168 169 // Output stubs for dynamically-linked functions 170 unsigned j = 1; 171 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 172 i != e; ++i, ++j) { 173 SwitchSection(".section __IMPORT,__jump_table,symbol_stubs," 174 "self_modifying_code+pure_instructions,5", 0); 175 O << "L" << *i << "$stub:\n"; 176 O << "\t.indirect_symbol " << *i << "\n"; 177 O << "\thlt ; hlt ; hlt ; hlt ; hlt\n"; 178 } 179 180 O << "\n"; 181 182 // Output stubs for external and common global variables. 183 if (GVStubs.begin() != GVStubs.end()) 184 SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0); 185 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); 186 i != e; ++i) { 187 O << "L" << *i << "$non_lazy_ptr:\n"; 188 O << "\t.indirect_symbol " << *i << "\n"; 189 O << "\t.long\t0\n"; 190 } 191 } 192 193 // Emit initial debug information. 194 DW.EndModule(M); 195 196 AsmPrinter::doFinalization(M); 197 return false; // success 198} 199 200/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code 201/// for a MachineFunction to the given output stream, using the given target 202/// machine description. 203/// 204FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){ 205 switch (AsmWriterFlavor) { 206 default: 207 assert(0 && "Unknown asm flavor!"); 208 case intel: 209 return new X86IntelAsmPrinter(o, tm); 210 case att: 211 return new X86ATTAsmPrinter(o, tm); 212 } 213} 214