X86AsmPrinter.cpp revision 52a51e38dc312aa262b0d771419afe1785f3cb22
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 "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"
27using namespace llvm;
28
29Statistic<> llvm::EmittedInsts("asm-printer",
30                               "Number of machine instrs printed");
31
32enum AsmWriterFlavorTy { att, intel };
33cl::opt<AsmWriterFlavorTy>
34AsmWriterFlavor("x86-asm-syntax",
35                cl::desc("Choose style of code to emit from X86 backend:"),
36                cl::values(
37                           clEnumVal(att,   "  Emit AT&T-style assembly"),
38                           clEnumVal(intel, "  Emit Intel-style assembly"),
39                           clEnumValEnd),
40#ifdef _MSC_VER
41                cl::init(intel)
42#else
43                cl::init(att)
44#endif
45                );
46
47// Out of line virtual function to home classes.
48void X86DwarfWriter::virtfn() {}
49
50
51/// doInitialization
52bool X86SharedAsmPrinter::doInitialization(Module &M) {
53  PrivateGlobalPrefix = ".L";
54  DefaultTextSection = ".text";
55  DefaultDataSection = ".data";
56
57  switch (Subtarget->TargetType) {
58  case X86Subtarget::isDarwin:
59    AlignmentIsInBytes = false;
60    GlobalPrefix = "_";
61    Data64bitsDirective = 0;       // we can't emit a 64-bit unit
62    ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
63    PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
64    ConstantPoolSection = "\t.const\n";
65    JumpTableDataSection = "\t.const\n"; // FIXME: depends on PIC mode
66    FourByteConstantSection = "\t.literal4\n";
67    EightByteConstantSection = "\t.literal8\n";
68    LCOMMDirective = "\t.lcomm\t";
69    COMMDirectiveTakesAlignment = false;
70    HasDotTypeDotSizeDirective = false;
71    StaticCtorsSection = ".mod_init_func";
72    StaticDtorsSection = ".mod_term_func";
73    InlineAsmStart = "# InlineAsm Start";
74    InlineAsmEnd = "# InlineAsm End";
75    SetDirective = "\t.set";
76    break;
77  case X86Subtarget::isCygwin:
78    GlobalPrefix = "_";
79    COMMDirectiveTakesAlignment = false;
80    HasDotTypeDotSizeDirective = false;
81    StaticCtorsSection = "\t.section .ctors,\"aw\"";
82    StaticDtorsSection = "\t.section .dtors,\"aw\"";
83    break;
84  case X86Subtarget::isWindows:
85    GlobalPrefix = "_";
86    HasDotTypeDotSizeDirective = false;
87    break;
88  default: break;
89  }
90
91  if (Subtarget->isTargetDarwin()) {
92    // Emit initial debug information.
93    DW.BeginModule(&M);
94  }
95
96  return AsmPrinter::doInitialization(M);
97}
98
99bool X86SharedAsmPrinter::doFinalization(Module &M) {
100  // Note: this code is not shared by the Intel printer as it is too different
101  // from how MASM does things.  When making changes here don't forget to look
102  // at X86IntelAsmPrinter::doFinalization().
103  const TargetData *TD = TM.getTargetData();
104
105  // Print out module-level global variables here.
106  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
107       I != E; ++I) {
108    if (!I->hasInitializer()) continue;   // External global require no code
109
110    // Check to see if this is a special global used by LLVM, if so, emit it.
111    if (EmitSpecialLLVMGlobal(I))
112      continue;
113
114    std::string name = Mang->getValueName(I);
115    Constant *C = I->getInitializer();
116    unsigned Size = TD->getTypeSize(C->getType());
117    unsigned Align = getPreferredAlignmentLog(I);
118
119    if (C->isNullValue() && /* FIXME: Verify correct */
120        (I->hasInternalLinkage() || I->hasWeakLinkage() ||
121         I->hasLinkOnceLinkage() ||
122         (Subtarget->isTargetDarwin() &&
123          I->hasExternalLinkage() && !I->hasSection()))) {
124      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
125      if (I->hasExternalLinkage()) {
126          O << "\t.globl\t" << name << "\n";
127          O << "\t.zerofill __DATA__, __common, " << name << ", "
128            << Size << ", " << Align;
129      } else {
130        SwitchToDataSection(DefaultDataSection, I);
131        if (LCOMMDirective != NULL) {
132          if (I->hasInternalLinkage()) {
133            O << LCOMMDirective << name << "," << Size;
134            if (Subtarget->isTargetDarwin())
135              O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
136          } else
137            O << COMMDirective  << name << "," << Size;
138        } else {
139          if (Subtarget->TargetType != X86Subtarget::isCygwin) {
140            if (I->hasInternalLinkage())
141              O << "\t.local\t" << name << "\n";
142          }
143          O << COMMDirective  << name << "," << Size;
144          if (COMMDirectiveTakesAlignment)
145            O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
146        }
147      }
148      O << "\t\t" << CommentString << " " << I->getName() << "\n";
149    } else {
150      switch (I->getLinkage()) {
151      case GlobalValue::LinkOnceLinkage:
152      case GlobalValue::WeakLinkage:
153        if (Subtarget->isTargetDarwin()) {
154          O << "\t.globl " << name << "\n"
155            << "\t.weak_definition " << name << "\n";
156          SwitchToDataSection(".section __DATA,__const_coal,coalesced", I);
157        } else if (Subtarget->TargetType == X86Subtarget::isCygwin) {
158          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\"\n"
159            << "\t.weak " << name << "\n";
160        } else {
161          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"
162            << "\t.weak " << name << "\n";
163        }
164        break;
165      case GlobalValue::AppendingLinkage:
166        // FIXME: appending linkage variables should go into a section of
167        // their name or something.  For now, just emit them as external.
168      case GlobalValue::ExternalLinkage:
169        // If external or appending, declare as a global symbol
170        O << "\t.globl " << name << "\n";
171        // FALL THROUGH
172      case GlobalValue::InternalLinkage:
173        SwitchToDataSection(DefaultDataSection, I);
174        break;
175      default:
176        assert(0 && "Unknown linkage type!");
177      }
178
179      EmitAlignment(Align, I);
180      O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
181        << "\n";
182      if (HasDotTypeDotSizeDirective)
183        O << "\t.size " << name << ", " << Size << "\n";
184
185      EmitGlobalConstant(C);
186      O << '\n';
187    }
188  }
189
190  if (Subtarget->isTargetDarwin()) {
191    SwitchToDataSection("", 0);
192
193    // Output stubs for dynamically-linked functions
194    unsigned j = 1;
195    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
196         i != e; ++i, ++j) {
197      SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs,"
198                          "self_modifying_code+pure_instructions,5", 0);
199      O << "L" << *i << "$stub:\n";
200      O << "\t.indirect_symbol " << *i << "\n";
201      O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
202    }
203
204    O << "\n";
205
206    // Output stubs for external and common global variables.
207    if (GVStubs.begin() != GVStubs.end())
208      SwitchToDataSection(
209                    ".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
210    for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
211         i != e; ++i) {
212      O << "L" << *i << "$non_lazy_ptr:\n";
213      O << "\t.indirect_symbol " << *i << "\n";
214      O << "\t.long\t0\n";
215    }
216
217    // Emit initial debug information.
218    DW.EndModule();
219
220    // Funny Darwin hack: This flag tells the linker that no global symbols
221    // contain code that falls through to other global symbols (e.g. the obvious
222    // implementation of multiple entry points).  If this doesn't occur, the
223    // linker can safely perform dead code stripping.  Since LLVM never
224    // generates code that does this, it is always safe to set.
225    O << "\t.subsections_via_symbols\n";
226  }
227
228  AsmPrinter::doFinalization(M);
229  return false; // success
230}
231
232/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
233/// for a MachineFunction to the given output stream, using the given target
234/// machine description.
235///
236FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
237                                             X86TargetMachine &tm){
238  switch (AsmWriterFlavor) {
239  default:
240    assert(0 && "Unknown asm flavor!");
241  case intel:
242    return new X86IntelAsmPrinter(o, tm);
243  case att:
244    return new X86ATTAsmPrinter(o, tm);
245  }
246}
247