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