1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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
13 // This printer is the output mechanism used by `llc'.
15 //===----------------------------------------------------------------------===//
17 #include "X86AsmPrinter.h"
18 #include "X86ATTAsmPrinter.h"
19 #include "X86IntelAsmPrinter.h"
20 #include "X86Subtarget.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"
29 Statistic<> llvm::EmittedInsts("asm-printer",
30 "Number of machine instrs printed");
32 enum AsmWriterFlavorTy { att, intel };
33 cl::opt<AsmWriterFlavorTy>
34 AsmWriterFlavor("x86-asm-syntax",
35 cl::desc("Choose style of code to emit from X86 backend:"),
37 clEnumVal(att, " Emit AT&T-style assembly"),
38 clEnumVal(intel, " Emit Intel-style assembly"),
48 bool X86SharedAsmPrinter::doInitialization(Module &M) {
49 const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
52 PrivateGlobalPrefix = ".L";
53 DefaultTextSection = ".text";
54 DefaultDataSection = ".data";
56 switch (Subtarget->TargetType) {
57 case X86Subtarget::isDarwin:
58 AlignmentIsInBytes = false;
60 Data64bitsDirective = 0; // we can't emit a 64-bit unit
61 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
62 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
63 ConstantPoolSection = "\t.const\n";
64 JumpTableSection = "\t.const\n"; // FIXME: depends on PIC mode
65 LCOMMDirective = "\t.lcomm\t";
66 COMMDirectiveTakesAlignment = false;
67 HasDotTypeDotSizeDirective = false;
69 StaticCtorsSection = ".mod_init_func";
70 StaticDtorsSection = ".mod_term_func";
71 InlineAsmStart = "# InlineAsm Start";
72 InlineAsmEnd = "# InlineAsm End";
74 case X86Subtarget::isCygwin:
76 COMMDirectiveTakesAlignment = false;
77 HasDotTypeDotSizeDirective = false;
79 case X86Subtarget::isWindows:
81 HasDotTypeDotSizeDirective = false;
87 // Emit initial debug information.
91 return AsmPrinter::doInitialization(M);
94 bool X86SharedAsmPrinter::doFinalization(Module &M) {
95 // Note: this code is not shared by the Intel printer as it is too different
96 // from how MASM does things. When making changes here don't forget to look
97 // at X86IntelAsmPrinter::doFinalization().
98 const TargetData *TD = TM.getTargetData();
100 // Print out module-level global variables here.
101 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
103 if (!I->hasInitializer()) continue; // External global require no code
105 // Check to see if this is a special global used by LLVM, if so, emit it.
106 if (EmitSpecialLLVMGlobal(I))
109 std::string name = Mang->getValueName(I);
110 Constant *C = I->getInitializer();
111 unsigned Size = TD->getTypeSize(C->getType());
112 unsigned Align = getPreferredAlignmentLog(I);
114 if (C->isNullValue() && /* FIXME: Verify correct */
115 (I->hasInternalLinkage() || I->hasWeakLinkage() ||
116 I->hasLinkOnceLinkage() ||
117 (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) {
118 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
119 if (I->hasExternalLinkage()) {
120 O << "\t.globl\t" << name << "\n";
121 O << "\t.zerofill __DATA__, __common, " << name << ", "
122 << Size << ", " << Align;
124 SwitchToDataSection(DefaultDataSection, I);
125 if (LCOMMDirective != NULL) {
126 if (I->hasInternalLinkage()) {
127 O << LCOMMDirective << name << "," << Size;
129 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
131 O << COMMDirective << name << "," << Size;
133 if (I->hasInternalLinkage())
134 O << "\t.local\t" << name << "\n";
135 O << COMMDirective << name << "," << Size;
136 if (COMMDirectiveTakesAlignment)
137 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
140 O << "\t\t" << CommentString << " " << I->getName() << "\n";
142 switch (I->getLinkage()) {
143 case GlobalValue::LinkOnceLinkage:
144 case GlobalValue::WeakLinkage:
146 O << "\t.globl " << name << "\n"
147 << "\t.weak_definition " << name << "\n";
148 SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
150 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
151 O << "\t.weak " << name << "\n";
154 case GlobalValue::AppendingLinkage:
155 // FIXME: appending linkage variables should go into a section of
156 // their name or something. For now, just emit them as external.
157 case GlobalValue::ExternalLinkage:
158 // If external or appending, declare as a global symbol
159 O << "\t.globl " << name << "\n";
161 case GlobalValue::InternalLinkage:
162 SwitchToDataSection(DefaultDataSection, I);
165 assert(0 && "Unknown linkage type!");
168 EmitAlignment(Align, I);
169 O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
171 if (HasDotTypeDotSizeDirective)
172 O << "\t.size " << name << ", " << Size << "\n";
174 EmitGlobalConstant(C);
180 SwitchToDataSection("", 0);
182 // Output stubs for dynamically-linked functions
184 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
186 SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs,"
187 "self_modifying_code+pure_instructions,5", 0);
188 O << "L" << *i << "$stub:\n";
189 O << "\t.indirect_symbol " << *i << "\n";
190 O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
195 // Output stubs for external and common global variables.
196 if (GVStubs.begin() != GVStubs.end())
198 ".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
199 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
201 O << "L" << *i << "$non_lazy_ptr:\n";
202 O << "\t.indirect_symbol " << *i << "\n";
206 // Emit initial debug information.
209 // Funny Darwin hack: This flag tells the linker that no global symbols
210 // contain code that falls through to other global symbols (e.g. the obvious
211 // implementation of multiple entry points). If this doesn't occur, the
212 // linker can safely perform dead code stripping. Since LLVM never
213 // generates code that does this, it is always safe to set.
214 O << "\t.subsections_via_symbols\n";
217 AsmPrinter::doFinalization(M);
218 return false; // success
221 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
222 /// for a MachineFunction to the given output stream, using the given target
223 /// machine description.
225 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
226 X86TargetMachine &tm){
227 switch (AsmWriterFlavor) {
229 assert(0 && "Unknown asm flavor!");
231 return new X86IntelAsmPrinter(o, tm);
233 return new X86ATTAsmPrinter(o, tm);