X86AsmPrinter.cpp revision a6e24d8caf526b2778293d8a9b469505e4634ab8
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/// doInitialization
48bool X86SharedAsmPrinter::doInitialization(Module &M) {
49  const X86Subtarget *Subtarget = &TM.getSubtarget<X86Subtarget>();
50
51  forDarwin = false;
52  PrivateGlobalPrefix = ".L";
53
54  switch (Subtarget->TargetType) {
55  case X86Subtarget::isDarwin:
56    AlignmentIsInBytes = false;
57    GlobalPrefix = "_";
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;
66    forDarwin = true;
67    StaticCtorsSection = ".mod_init_func";
68    StaticDtorsSection = ".mod_term_func";
69    InlineAsmStart = InlineAsmEnd = "";  // Don't use #APP/#NO_APP
70    break;
71  case X86Subtarget::isCygwin:
72    GlobalPrefix = "_";
73    COMMDirectiveTakesAlignment = false;
74    HasDotTypeDotSizeDirective = false;
75    break;
76  case X86Subtarget::isWindows:
77    GlobalPrefix = "_";
78    HasDotTypeDotSizeDirective = false;
79    break;
80  default: break;
81  }
82
83  if (forDarwin) {
84    // Emit initial debug information.
85    DW.BeginModule(&M);
86  }
87
88  return AsmPrinter::doInitialization(M);
89}
90
91bool X86SharedAsmPrinter::doFinalization(Module &M) {
92  const TargetData *TD = TM.getTargetData();
93
94  // Print out module-level global variables here.
95  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
96       I != E; ++I) {
97    if (!I->hasInitializer()) continue;   // External global require no code
98
99    // Check to see if this is a special global used by LLVM, if so, emit it.
100    if (EmitSpecialLLVMGlobal(I))
101      continue;
102
103    std::string name = Mang->getValueName(I);
104    Constant *C = I->getInitializer();
105    unsigned Size = TD->getTypeSize(C->getType());
106    unsigned Align = getPreferredAlignmentLog(I);
107
108    if (C->isNullValue() && /* FIXME: Verify correct */
109        (I->hasInternalLinkage() || I->hasWeakLinkage() ||
110         I->hasLinkOnceLinkage() ||
111         (forDarwin && I->hasExternalLinkage() && !I->hasSection()))) {
112      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
113      if (I->hasExternalLinkage()) {
114          O << "\t.globl\t" << name << "\n";
115          O << "\t.zerofill __DATA__, __common, " << name << ", "
116            << Size << ", " << Align;
117      } else {
118        SwitchSection(".data", I);
119        if (LCOMMDirective != NULL) {
120          if (I->hasInternalLinkage()) {
121            O << LCOMMDirective << name << "," << Size;
122            if (forDarwin)
123              O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
124          } else
125            O << COMMDirective  << name << "," << Size;
126        } else {
127          if (I->hasInternalLinkage())
128            O << "\t.local\t" << name << "\n";
129          O << COMMDirective  << name << "," << Size;
130          if (COMMDirectiveTakesAlignment)
131            O << "," << (AlignmentIsInBytes ? (1 << Align) : Align);
132        }
133      }
134      O << "\t\t" << CommentString << " " << I->getName() << "\n";
135    } else {
136      switch (I->getLinkage()) {
137      case GlobalValue::LinkOnceLinkage:
138      case GlobalValue::WeakLinkage:
139        if (forDarwin) {
140          O << "\t.globl " << name << "\n"
141            << "\t.weak_definition " << name << "\n";
142          SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
143        } else {
144          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
145          O << "\t.weak " << name << "\n";
146        }
147        break;
148      case GlobalValue::AppendingLinkage:
149        // FIXME: appending linkage variables should go into a section of
150        // their name or something.  For now, just emit them as external.
151      case GlobalValue::ExternalLinkage:
152        // If external or appending, declare as a global symbol
153        O << "\t.globl " << name << "\n";
154        // FALL THROUGH
155      case GlobalValue::InternalLinkage:
156        SwitchSection(".data", I);
157        break;
158      default:
159        assert(0 && "Unknown linkage type!");
160      }
161
162      EmitAlignment(Align, I);
163      O << name << ":\t\t\t\t" << CommentString << " " << I->getName()
164        << "\n";
165      if (HasDotTypeDotSizeDirective)
166        O << "\t.size " << name << ", " << Size << "\n";
167
168      EmitGlobalConstant(C);
169      O << '\n';
170    }
171  }
172
173  if (forDarwin) {
174    SwitchSection("", 0);
175
176    // Output stubs for dynamically-linked functions
177    unsigned j = 1;
178    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
179         i != e; ++i, ++j) {
180      SwitchSection(".section __IMPORT,__jump_table,symbol_stubs,"
181                    "self_modifying_code+pure_instructions,5", 0);
182      O << "L" << *i << "$stub:\n";
183      O << "\t.indirect_symbol " << *i << "\n";
184      O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
185    }
186
187    O << "\n";
188
189    // Output stubs for external and common global variables.
190    if (GVStubs.begin() != GVStubs.end())
191      SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
192    for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
193         i != e; ++i) {
194      O << "L" << *i << "$non_lazy_ptr:\n";
195      O << "\t.indirect_symbol " << *i << "\n";
196      O << "\t.long\t0\n";
197    }
198
199    // Emit initial debug information.
200    DW.EndModule();
201
202    // Funny Darwin hack: This flag tells the linker that no global symbols
203    // contain code that falls through to other global symbols (e.g. the obvious
204    // implementation of multiple entry points).  If this doesn't occur, the
205    // linker can safely perform dead code stripping.  Since LLVM never
206    // generates code that does this, it is always safe to set.
207    O << "\t.subsections_via_symbols\n";
208  }
209
210  AsmPrinter::doFinalization(M);
211  return false; // success
212}
213
214/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
215/// for a MachineFunction to the given output stream, using the given target
216/// machine description.
217///
218FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
219                                             X86TargetMachine &tm){
220  switch (AsmWriterFlavor) {
221  default:
222    assert(0 && "Unknown asm flavor!");
223  case intel:
224    return new X86IntelAsmPrinter(o, tm);
225  case att:
226    return new X86ATTAsmPrinter(o, tm);
227  }
228}
229