X86AsmPrinter.cpp revision d15d086956f0b9fabd95d729023468e068e930c9
1//===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// 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 "X86COFF.h"
20#include "X86IntelAsmPrinter.h"
21#include "X86MachineFunctionInfo.h"
22#include "X86Subtarget.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/CallingConv.h"
25#include "llvm/Constants.h"
26#include "llvm/Module.h"
27#include "llvm/DerivedTypes.h"
28#include "llvm/Type.h"
29#include "llvm/Assembly/Writer.h"
30#include "llvm/Support/Mangler.h"
31#include "llvm/Target/TargetAsmInfo.h"
32#include "llvm/Target/TargetOptions.h"
33using namespace llvm;
34
35static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
36                                                    const TargetData *TD) {
37  X86MachineFunctionInfo Info;
38  uint64_t Size = 0;
39
40  switch (F->getCallingConv()) {
41  case CallingConv::X86_StdCall:
42    Info.setDecorationStyle(StdCall);
43    break;
44  case CallingConv::X86_FastCall:
45    Info.setDecorationStyle(FastCall);
46    break;
47  default:
48    return Info;
49  }
50
51  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
52       AI != AE; ++AI)
53    // Size should be aligned to DWORD boundary
54    Size += ((TD->getABITypeSize(AI->getType()) + 3)/4)*4;
55
56  // We're not supporting tooooo huge arguments :)
57  Info.setBytesToPopOnReturn((unsigned int)Size);
58  return Info;
59}
60
61
62/// decorateName - Query FunctionInfoMap and use this information for various
63/// name decoration.
64void X86SharedAsmPrinter::decorateName(std::string &Name,
65                                       const GlobalValue *GV) {
66  const Function *F = dyn_cast<Function>(GV);
67  if (!F) return;
68
69  // We don't want to decorate non-stdcall or non-fastcall functions right now
70  unsigned CC = F->getCallingConv();
71  if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
72    return;
73
74  // Decorate names only when we're targeting Cygwin/Mingw32 targets
75  if (!Subtarget->isTargetCygMing())
76    return;
77
78  FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
79
80  const X86MachineFunctionInfo *Info;
81  if (info_item == FunctionInfoMap.end()) {
82    // Calculate apropriate function info and populate map
83    FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData());
84    Info = &FunctionInfoMap[F];
85  } else {
86    Info = &info_item->second;
87  }
88
89  const FunctionType *FT = F->getFunctionType();
90  switch (Info->getDecorationStyle()) {
91  case None:
92    break;
93  case StdCall:
94    // "Pure" variadic functions do not receive @0 suffix.
95    if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
96        (FT->getNumParams() == 1 && F->isStructReturn()))
97      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
98    break;
99  case FastCall:
100    // "Pure" variadic functions do not receive @0 suffix.
101    if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
102        (FT->getNumParams() == 1 && F->isStructReturn()))
103      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
104
105    if (Name[0] == '_') {
106      Name[0] = '@';
107    } else {
108      Name = '@' + Name;
109    }
110    break;
111  default:
112    assert(0 && "Unsupported DecorationStyle");
113  }
114}
115
116/// doInitialization
117bool X86SharedAsmPrinter::doInitialization(Module &M) {
118  if (TAI->doesSupportDebugInformation()) {
119    // Emit initial debug information.
120    DW.BeginModule(&M);
121  }
122
123  bool Result = AsmPrinter::doInitialization(M);
124
125  // Darwin wants symbols to be quoted if they have complex names.
126  if (Subtarget->isTargetDarwin())
127    Mang->setUseQuotes(true);
128
129  return Result;
130}
131
132bool X86SharedAsmPrinter::doFinalization(Module &M) {
133  // Note: this code is not shared by the Intel printer as it is too different
134  // from how MASM does things.  When making changes here don't forget to look
135  // at X86IntelAsmPrinter::doFinalization().
136  const TargetData *TD = TM.getTargetData();
137
138  // Print out module-level global variables here.
139  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
140       I != E; ++I) {
141    if (!I->hasInitializer())
142      continue;   // External global require no code
143
144    // Check to see if this is a special global used by LLVM, if so, emit it.
145    if (EmitSpecialLLVMGlobal(I)) {
146      if (Subtarget->isTargetDarwin() &&
147          TM.getRelocationModel() == Reloc::Static) {
148        if (I->getName() == "llvm.global_ctors")
149          O << ".reference .constructors_used\n";
150        else if (I->getName() == "llvm.global_dtors")
151          O << ".reference .destructors_used\n";
152      }
153      continue;
154    }
155
156    std::string name = Mang->getValueName(I);
157    Constant *C = I->getInitializer();
158    const Type *Type = C->getType();
159    unsigned Size = TD->getABITypeSize(Type);
160    unsigned Align = TD->getPreferredAlignmentLog(I);
161
162    if (I->hasHiddenVisibility()) {
163      if (const char *Directive = TAI->getHiddenDirective())
164        O << Directive << name << "\n";
165    } else if (I->hasProtectedVisibility()) {
166      if (const char *Directive = TAI->getProtectedDirective())
167        O << Directive << name << "\n";
168    }
169
170    if (Subtarget->isTargetELF())
171      O << "\t.type\t" << name << ",@object\n";
172
173    if (C->isNullValue() && !I->hasSection()) {
174      if (I->hasExternalLinkage()) {
175        if (const char *Directive = TAI->getZeroFillDirective()) {
176          O << "\t.globl " << name << "\n";
177          O << Directive << "__DATA__, __common, " << name << ", "
178            << Size << ", " << Align << "\n";
179          continue;
180        }
181      }
182
183      if (!I->isThreadLocal() &&
184          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
185           I->hasLinkOnceLinkage())) {
186        if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
187        if (!NoZerosInBSS && TAI->getBSSSection())
188          SwitchToDataSection(TAI->getBSSSection(), I);
189        else
190          SwitchToDataSection(TAI->getDataSection(), I);
191        if (TAI->getLCOMMDirective() != NULL) {
192          if (I->hasInternalLinkage()) {
193            O << TAI->getLCOMMDirective() << name << "," << Size;
194            if (Subtarget->isTargetDarwin())
195              O << "," << Align;
196          } else {
197            O << TAI->getCOMMDirective()  << name << "," << Size;
198
199            // Leopard and above support aligned common symbols.
200            if (Subtarget->getDarwinVers() >= 9)
201              O << "," << Align;
202          }
203        } else {
204          if (!Subtarget->isTargetCygMing()) {
205            if (I->hasInternalLinkage())
206              O << "\t.local\t" << name << "\n";
207          }
208          O << TAI->getCOMMDirective()  << name << "," << Size;
209          if (TAI->getCOMMDirectiveTakesAlignment())
210            O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
211        }
212        O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
213        continue;
214      }
215    }
216
217    switch (I->getLinkage()) {
218    case GlobalValue::LinkOnceLinkage:
219    case GlobalValue::WeakLinkage:
220      if (Subtarget->isTargetDarwin()) {
221        O << "\t.globl " << name << "\n"
222          << TAI->getWeakDefDirective() << name << "\n";
223        SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
224      } else if (Subtarget->isTargetCygMing()) {
225        std::string SectionName(".section\t.data$linkonce." +
226                                name +
227                                ",\"aw\"");
228        SwitchToDataSection(SectionName.c_str(), I);
229        O << "\t.globl\t" << name << "\n"
230          << "\t.linkonce same_size\n";
231      } else {
232        std::string SectionName("\t.section\t.llvm.linkonce.d." +
233                                name +
234                                ",\"aw\",@progbits");
235        SwitchToDataSection(SectionName.c_str(), I);
236        O << "\t.weak\t" << name << "\n";
237      }
238      break;
239    case GlobalValue::DLLExportLinkage:
240      DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
241      // FALL THROUGH
242    case GlobalValue::AppendingLinkage:
243      // FIXME: appending linkage variables should go into a section of
244      // their name or something.  For now, just emit them as external.
245    case GlobalValue::ExternalLinkage:
246      // If external or appending, declare as a global symbol
247      O << "\t.globl " << name << "\n";
248      // FALL THROUGH
249    case GlobalValue::InternalLinkage: {
250      if (I->isConstant()) {
251        const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
252        if (TAI->getCStringSection() && CVA && CVA->isCString()) {
253          SwitchToDataSection(TAI->getCStringSection(), I);
254          break;
255        }
256      }
257      // FIXME: special handling for ".ctors" & ".dtors" sections
258      if (I->hasSection() &&
259          (I->getSection() == ".ctors" ||
260           I->getSection() == ".dtors")) {
261        std::string SectionName = ".section " + I->getSection();
262
263        if (Subtarget->isTargetCygMing()) {
264          SectionName += ",\"aw\"";
265        } else {
266          assert(!Subtarget->isTargetDarwin());
267          SectionName += ",\"aw\",@progbits";
268        }
269
270        SwitchToDataSection(SectionName.c_str());
271      } else {
272        if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
273          SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
274                              TAI->getBSSSection(), I);
275        else if (!I->isConstant())
276          SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() :
277                              TAI->getDataSection(), I);
278        else if (I->isThreadLocal())
279          SwitchToDataSection(TAI->getTLSDataSection());
280        else {
281          // Read-only data.
282          bool HasReloc = C->ContainsRelocations();
283          if (HasReloc &&
284              Subtarget->isTargetDarwin() &&
285              TM.getRelocationModel() != Reloc::Static)
286            SwitchToDataSection("\t.const_data\n");
287          else if (!HasReloc && Size == 4 &&
288                   TAI->getFourByteConstantSection())
289            SwitchToDataSection(TAI->getFourByteConstantSection(), I);
290          else if (!HasReloc && Size == 8 &&
291                   TAI->getEightByteConstantSection())
292            SwitchToDataSection(TAI->getEightByteConstantSection(), I);
293          else if (!HasReloc && Size == 16 &&
294                   TAI->getSixteenByteConstantSection())
295            SwitchToDataSection(TAI->getSixteenByteConstantSection(), I);
296          else if (TAI->getReadOnlySection())
297            SwitchToDataSection(TAI->getReadOnlySection(), I);
298          else
299            SwitchToDataSection(TAI->getDataSection(), I);
300        }
301      }
302
303      break;
304    }
305    default:
306      assert(0 && "Unknown linkage type!");
307    }
308
309    EmitAlignment(Align, I);
310    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
311      << "\n";
312    if (TAI->hasDotTypeDotSizeDirective())
313      O << "\t.size\t" << name << ", " << Size << "\n";
314    // If the initializer is a extern weak symbol, remember to emit the weak
315    // reference!
316    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
317      if (GV->hasExternalWeakLinkage())
318        ExtWeakSymbols.insert(GV);
319
320    EmitGlobalConstant(C);
321  }
322
323  // Output linker support code for dllexported globals
324  if (!DLLExportedGVs.empty()) {
325    SwitchToDataSection(".section .drectve");
326  }
327
328  for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
329         e = DLLExportedGVs.end();
330         i != e; ++i) {
331    O << "\t.ascii \" -export:" << *i << ",data\"\n";
332  }
333
334  if (!DLLExportedFns.empty()) {
335    SwitchToDataSection(".section .drectve");
336  }
337
338  for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
339         e = DLLExportedFns.end();
340         i != e; ++i) {
341    O << "\t.ascii \" -export:" << *i << "\"\n";
342  }
343
344  if (Subtarget->isTargetDarwin()) {
345    SwitchToDataSection("");
346
347    // Output stubs for dynamically-linked functions
348    unsigned j = 1;
349    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
350         i != e; ++i, ++j) {
351      SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
352                          "self_modifying_code+pure_instructions,5", 0);
353      O << "L" << *i << "$stub:\n";
354      O << "\t.indirect_symbol " << *i << "\n";
355      O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
356    }
357
358    O << "\n";
359
360    if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI &&
361        !Subtarget->is64Bit()) {
362      // Add the (possibly multiple) personalities to the set of global values.
363      const std::vector<Function *>& Personalities = MMI->getPersonalities();
364
365      for (std::vector<Function *>::const_iterator I = Personalities.begin(),
366             E = Personalities.end(); I != E; ++I)
367        if (*I) GVStubs.insert("_" + (*I)->getName());
368    }
369
370    // Output stubs for external and common global variables.
371    if (!GVStubs.empty())
372      SwitchToDataSection(
373                    "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers");
374    for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
375         i != e; ++i) {
376      O << "L" << *i << "$non_lazy_ptr:\n";
377      O << "\t.indirect_symbol " << *i << "\n";
378      O << "\t.long\t0\n";
379    }
380
381    // Emit final debug information.
382    DW.EndModule();
383
384    // Funny Darwin hack: This flag tells the linker that no global symbols
385    // contain code that falls through to other global symbols (e.g. the obvious
386    // implementation of multiple entry points).  If this doesn't occur, the
387    // linker can safely perform dead code stripping.  Since LLVM never
388    // generates code that does this, it is always safe to set.
389    O << "\t.subsections_via_symbols\n";
390  } else if (Subtarget->isTargetCygMing()) {
391    // Emit type information for external functions
392    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
393         i != e; ++i) {
394      O << "\t.def\t " << *i
395        << ";\t.scl\t" << COFF::C_EXT
396        << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
397        << ";\t.endef\n";
398    }
399
400    // Emit final debug information.
401    DW.EndModule();
402  } else if (Subtarget->isTargetELF()) {
403    // Emit final debug information.
404    DW.EndModule();
405  }
406
407  return AsmPrinter::doFinalization(M);
408}
409
410/// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
411/// for a MachineFunction to the given output stream, using the given target
412/// machine description.
413///
414FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,
415                                             X86TargetMachine &tm) {
416  const X86Subtarget *Subtarget = &tm.getSubtarget<X86Subtarget>();
417
418  if (Subtarget->isFlavorIntel()) {
419    return new X86IntelAsmPrinter(o, tm, tm.getTargetAsmInfo());
420  } else {
421    return new X86ATTAsmPrinter(o, tm, tm.getTargetAsmInfo());
422  }
423}
424