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