X86AsmPrinter.cpp revision 7f70559bc47877bafc6dfa92b7df6b64650445fb
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 "X86MachineFunctionInfo.h"
21#include "X86Subtarget.h"
22#include "llvm/ADT/StringExtras.h"
23#include "llvm/CallingConv.h"
24#include "llvm/Constants.h"
25#include "llvm/Module.h"
26#include "llvm/Type.h"
27#include "llvm/Assembly/Writer.h"
28#include "llvm/Support/Mangler.h"
29#include "llvm/Target/TargetAsmInfo.h"
30using namespace llvm;
31
32static X86FunctionInfo calculateFunctionInfo(const Function *F,
33                                             const TargetData *TD) {
34  X86FunctionInfo Info;
35  uint64_t Size = 0;
36
37  switch (F->getCallingConv()) {
38  case CallingConv::X86_StdCall:
39    Info.setDecorationStyle(StdCall);
40    break;
41  case CallingConv::X86_FastCall:
42    Info.setDecorationStyle(FastCall);
43    break;
44  default:
45    return Info;
46  }
47
48  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
49       AI != AE; ++AI)
50    Size += TD->getTypeSize(AI->getType());
51
52  // Size should be aligned to DWORD boundary
53  Size = ((Size + 3)/4)*4;
54
55  // We're not supporting tooooo huge arguments :)
56  Info.setBytesToPopOnReturn((unsigned int)Size);
57  return Info;
58}
59
60
61/// decorateName - Query FunctionInfoMap and use this information for various
62/// name decoration.
63void X86SharedAsmPrinter::decorateName(std::string &Name,
64                                       const GlobalValue *GV) {
65  const Function *F = dyn_cast<Function>(GV);
66  if (!F) return;
67
68  // We don't want to decorate non-stdcall or non-fastcall functions right now
69  unsigned CC = F->getCallingConv();
70  if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
71    return;
72
73  FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
74
75  const X86FunctionInfo *Info;
76  if (info_item == FunctionInfoMap.end()) {
77    // Calculate apropriate function info and populate map
78    FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData());
79    Info = &FunctionInfoMap[F];
80  } else {
81    Info = &info_item->second;
82  }
83
84  switch (Info->getDecorationStyle()) {
85  case None:
86    break;
87  case StdCall:
88    if (!F->isVarArg()) // Variadic functions do not receive @0 suffix.
89      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
90    break;
91  case FastCall:
92    if (!F->isVarArg()) // Variadic functions do not receive @0 suffix.
93      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
94
95    if (Name[0] == '_') {
96      Name[0] = '@';
97    } else {
98      Name = '@' + Name;
99    }
100    break;
101  default:
102    assert(0 && "Unsupported DecorationStyle");
103  }
104}
105
106/// doInitialization
107bool X86SharedAsmPrinter::doInitialization(Module &M) {
108  if (Subtarget->isTargetELF() ||
109      Subtarget->isTargetCygMing() ||
110      Subtarget->isTargetDarwin()) {
111    // Emit initial debug information.
112    DW.BeginModule(&M);
113  }
114
115  return AsmPrinter::doInitialization(M);
116}
117
118bool X86SharedAsmPrinter::doFinalization(Module &M) {
119  // Note: this code is not shared by the Intel printer as it is too different
120  // from how MASM does things.  When making changes here don't forget to look
121  // at X86IntelAsmPrinter::doFinalization().
122  const TargetData *TD = TM.getTargetData();
123
124  // Print out module-level global variables here.
125  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
126       I != E; ++I) {
127    if (!I->hasInitializer())
128      continue;   // External global require no code
129
130    // Check to see if this is a special global used by LLVM, if so, emit it.
131    if (EmitSpecialLLVMGlobal(I))
132      continue;
133
134    std::string name = Mang->getValueName(I);
135    Constant *C = I->getInitializer();
136    unsigned Size = TD->getTypeSize(C->getType());
137    unsigned Align = TD->getPreferredAlignmentLog(I);
138
139    if (C->isNullValue() && /* FIXME: Verify correct */
140        !I->hasSection() &&
141        (I->hasInternalLinkage() || I->hasWeakLinkage() ||
142         I->hasLinkOnceLinkage() ||
143         (Subtarget->isTargetDarwin() &&
144          I->hasExternalLinkage()))) {
145      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
146      if (I->hasExternalLinkage()) {
147          O << "\t.globl\t" << name << "\n";
148          O << "\t.zerofill __DATA__, __common, " << name << ", "
149            << Size << ", " << Align;
150      } else {
151        SwitchToDataSection(TAI->getDataSection(), I);
152        if (TAI->getLCOMMDirective() != NULL) {
153          if (I->hasInternalLinkage()) {
154            O << TAI->getLCOMMDirective() << name << "," << Size;
155            if (Subtarget->isTargetDarwin())
156              O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
157          } else
158            O << TAI->getCOMMDirective()  << name << "," << Size;
159        } else {
160          if (!Subtarget->isTargetCygMing()) {
161            if (I->hasInternalLinkage())
162              O << "\t.local\t" << name << "\n";
163          }
164          O << TAI->getCOMMDirective()  << name << "," << Size;
165          if (TAI->getCOMMDirectiveTakesAlignment())
166            O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
167        }
168      }
169      O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
170    } else {
171      switch (I->getLinkage()) {
172      case GlobalValue::LinkOnceLinkage:
173      case GlobalValue::WeakLinkage:
174        if (Subtarget->isTargetDarwin()) {
175          O << "\t.globl " << name << "\n"
176            << "\t.weak_definition " << name << "\n";
177          SwitchToDataSection(".section __DATA,__const_coal,coalesced", I);
178        } else if (Subtarget->isTargetCygMing()) {
179          std::string SectionName(".section\t.data$linkonce." +
180                                  name +
181                                  ",\"aw\"");
182          SwitchToDataSection(SectionName.c_str(), I);
183          O << "\t.globl " << name << "\n"
184            << "\t.linkonce same_size\n";
185        } else {
186          std::string SectionName("\t.section\t.llvm.linkonce.d." +
187                                  name +
188                                  ",\"aw\",@progbits");
189          SwitchToDataSection(SectionName.c_str(), I);
190          O << "\t.weak " << name << "\n";
191        }
192        break;
193      case GlobalValue::AppendingLinkage:
194        // FIXME: appending linkage variables should go into a section of
195        // their name or something.  For now, just emit them as external.
196      case GlobalValue::DLLExportLinkage:
197        DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
198        // FALL THROUGH
199      case GlobalValue::ExternalLinkage:
200        // If external or appending, declare as a global symbol
201        O << "\t.globl " << name << "\n";
202        // FALL THROUGH
203      case GlobalValue::InternalLinkage: {
204        if (I->isConstant()) {
205          const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
206          if (TAI->getCStringSection() && CVA && CVA->isCString()) {
207            SwitchToDataSection(TAI->getCStringSection(), I);
208            break;
209          }
210        }
211        // FIXME: special handling for ".ctors" & ".dtors" sections
212        if (I->hasSection() &&
213            (I->getSection() == ".ctors" ||
214             I->getSection() == ".dtors")) {
215          std::string SectionName = ".section " + I->getSection();
216
217          if (Subtarget->isTargetCygMing()) {
218            SectionName += ",\"aw\"";
219          } else {
220            assert(!Subtarget->isTargetDarwin());
221            SectionName += ",\"aw\",@progbits";
222          }
223
224          SwitchToDataSection(SectionName.c_str());
225        } else {
226          SwitchToDataSection(TAI->getDataSection(), I);
227        }
228
229        break;
230      }
231      default:
232        assert(0 && "Unknown linkage type!");
233      }
234
235      EmitAlignment(Align, I);
236      O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
237        << "\n";
238      if (TAI->hasDotTypeDotSizeDirective())
239        O << "\t.size " << name << ", " << Size << "\n";
240      // If the initializer is a extern weak symbol, remember to emit the weak
241      // reference!
242      if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
243        if (GV->hasExternalWeakLinkage())
244          ExtWeakSymbols.insert(GV);
245
246      EmitGlobalConstant(C);
247      O << '\n';
248    }
249    if (I->hasHiddenVisibility())
250      O << "\t.hidden " << name << "\n";
251  }
252
253  // Output linker support code for dllexported globals
254  if (DLLExportedGVs.begin() != DLLExportedGVs.end()) {
255    SwitchToDataSection(".section .drectve");
256  }
257
258  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
259         e = DLLExportedGVs.end();
260         i != e; ++i) {
261    O << "\t.ascii \" -export:" << *i << ",data\"\n";
262  }
263
264  if (DLLExportedFns.begin() != DLLExportedFns.end()) {
265    SwitchToDataSection(".section .drectve");
266  }
267
268  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
269         e = DLLExportedFns.end();
270         i != e; ++i) {
271    O << "\t.ascii \" -export:" << *i << "\"\n";
272  }
273
274  if (Subtarget->isTargetDarwin()) {
275    SwitchToDataSection("");
276
277    // Output stubs for dynamically-linked functions
278    unsigned j = 1;
279    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
280         i != e; ++i, ++j) {
281      SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs,"
282                          "self_modifying_code+pure_instructions,5", 0);
283      O << "L" << *i << "$stub:\n";
284      O << "\t.indirect_symbol " << *i << "\n";
285      O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
286    }
287
288    O << "\n";
289
290    // Output stubs for external and common global variables.
291    if (GVStubs.begin() != GVStubs.end())
292      SwitchToDataSection(
293                    ".section __IMPORT,__pointers,non_lazy_symbol_pointers");
294    for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
295         i != e; ++i) {
296      O << "L" << *i << "$non_lazy_ptr:\n";
297      O << "\t.indirect_symbol " << *i << "\n";
298      O << "\t.long\t0\n";
299    }
300
301    // Emit final debug information.
302    DW.EndModule();
303
304    // Funny Darwin hack: This flag tells the linker that no global symbols
305    // contain code that falls through to other global symbols (e.g. the obvious
306    // implementation of multiple entry points).  If this doesn't occur, the
307    // linker can safely perform dead code stripping.  Since LLVM never
308    // generates code that does this, it is always safe to set.
309    O << "\t.subsections_via_symbols\n";
310  } else if (Subtarget->isTargetELF() || Subtarget->isTargetCygMing()) {
311    // Emit final debug information.
312    DW.EndModule();
313  }
314
315  AsmPrinter::doFinalization(M);
316  return false; // success
317}
318
319/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
320/// for a MachineFunction to the given output stream, using the given target
321/// machine description.
322///
323FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
324                                             X86TargetMachine &tm) {
325  const X86Subtarget *Subtarget = &tm.getSubtarget<X86Subtarget>();
326
327  if (Subtarget->isFlavorIntel()) {
328    return new X86IntelAsmPrinter(o, tm, tm.getTargetAsmInfo());
329  } else {
330    return new X86ATTAsmPrinter(o, tm, tm.getTargetAsmInfo());
331  }
332}
333