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";
54 switch (Subtarget->TargetType) {
55 case X86Subtarget::isDarwin:
56 AlignmentIsInBytes = false;
58 Data64bitsDirective = 0; // we can't emit a 64-bit unit
59 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
60 PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
61 ConstantPoolSection = "\t.const\n";
62 JumpTableSection = "\t.const\n"; // FIXME: depends on PIC mode
63 LCOMMDirective = "\t.lcomm\t";
64 COMMDirectiveTakesAlignment = false;
65 HasDotTypeDotSizeDirective = false;
67 StaticCtorsSection = ".mod_init_func";
68 StaticDtorsSection = ".mod_term_func";
69 InlineAsmStart = "# InlineAsm Start";
70 InlineAsmEnd = "# InlineAsm End";
72 case X86Subtarget::isCygwin:
74 COMMDirectiveTakesAlignment = false;
75 HasDotTypeDotSizeDirective = false;
77 case X86Subtarget::isWindows:
79 HasDotTypeDotSizeDirective = false;
85 // Emit initial debug information.
89 return AsmPrinter::doInitialization(M);
92 bool X86SharedAsmPrinter::doFinalization(Module &M) {
93 // Note: this code is not shared by the Intel printer as it is too different
94 // from how MASM does things. When making changes here don't forget to look
95 // at X86IntelAsmPrinter::doFinalization().
96 const TargetData *TD = TM.getTargetData();
98 // Print out module-level global variables here.
99 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
101 if (!I->hasInitializer()) continue; // External global require no code
103 // Check to see if this is a special global used by LLVM, if so, emit it.
104 if (EmitSpecialLLVMGlobal(I))
107 std::string name = Mang->getValueName(I);
108 Constant *C = I->getInitializer();
109 unsigned Size = TD->getTypeSize(C->getType());
110 unsigned Align = getPreferredAlignmentLog(I);
112 if (C->isNullValue() && /* FIXME: Verify correct */
113 (I->hasInternalLinkage() || I->hasWeakLinkage() ||
114 I->hasLinkOnceLinkage() ||
115 (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) {
116 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
117 if (I->hasExternalLinkage()) {
118 O << "\t.globl\t" << name << "\n";
119 O << "\t.zerofill __DATA__, __common, " << name << ", "
120 << Size << ", " << Align;
122 SwitchSection(".data", I);
123 if (LCOMMDirective != NULL) {
124 if (I->hasInternalLinkage()) {
125 O << LCOMMDirective << name << "," << Size;
127 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
129 O << COMMDirective << name << "," << Size;
131 if (I->hasInternalLinkage())
132 O << "\t.local\t" << name << "\n";
133 O << COMMDirective << name << "," << Size;
134 if (COMMDirectiveTakesAlignment)
135 O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
138 O << "\t\t" << CommentString << " " << I->getName() << "\n";
140 switch (I->getLinkage()) {
141 case GlobalValue::LinkOnceLinkage:
142 case GlobalValue::WeakLinkage:
144 O << "\t.globl " << name << "\n"
145 << "\t.weak_definition " << name << "\n";
146 SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
148 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
149 O << "\t.weak " << name << "\n";
152 case GlobalValue::AppendingLinkage:
153 // FIXME: appending linkage variables should go into a section of
154 // their name or something. For now, just emit them as external.
155 case GlobalValue::ExternalLinkage:
156 // If external or appending, declare as a global symbol
157 O << "\t.globl " << name << "\n";
159 case GlobalValue::InternalLinkage:
160 SwitchSection(".data", I);
163 assert(0 && "Unknown linkage type!");
166 EmitAlignment(Align, I);
167 O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
169 if (HasDotTypeDotSizeDirective)
170 O << "\t.size " << name << ", " << Size << "\n";
172 EmitGlobalConstant(C);
178 SwitchSection("", 0);
180 // Output stubs for dynamically-linked functions
182 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
184 SwitchSection(".section __IMPORT,__jump_table,symbol_stubs,"
185 "self_modifying_code+pure_instructions,5", 0);
186 O << "L" << *i << "$stub:\n";
187 O << "\t.indirect_symbol " << *i << "\n";
188 O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
193 // Output stubs for external and common global variables.
194 if (GVStubs.begin() != GVStubs.end())
195 SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
196 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
198 O << "L" << *i << "$non_lazy_ptr:\n";
199 O << "\t.indirect_symbol " << *i << "\n";
203 // Emit initial debug information.
206 // Funny Darwin hack: This flag tells the linker that no global symbols
207 // contain code that falls through to other global symbols (e.g. the obvious
208 // implementation of multiple entry points). If this doesn't occur, the
209 // linker can safely perform dead code stripping. Since LLVM never
210 // generates code that does this, it is always safe to set.
211 O << "\t.subsections_via_symbols\n";
214 AsmPrinter::doFinalization(M);
215 return false; // success
218 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
219 /// for a MachineFunction to the given output stream, using the given target
220 /// machine description.
222 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
223 X86TargetMachine &tm){
224 switch (AsmWriterFlavor) {
226 assert(0 && "Unknown asm flavor!");
228 return new X86IntelAsmPrinter(o, tm);
230 return new X86ATTAsmPrinter(o, tm);