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