X86: further range-loopify AsmPrinter
[oota-llvm.git] / lib / Target / X86 / X86AsmPrinter.cpp
1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T 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 contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to X86 machine code.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "X86AsmPrinter.h"
16 #include "InstPrinter/X86ATTInstPrinter.h"
17 #include "MCTargetDesc/X86BaseInfo.h"
18 #include "X86InstrInfo.h"
19 #include "X86MachineFunctionInfo.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
22 #include "llvm/CodeGen/MachineValueType.h"
23 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
24 #include "llvm/IR/DebugInfo.h"
25 #include "llvm/IR/DerivedTypes.h"
26 #include "llvm/IR/Mangler.h"
27 #include "llvm/IR/Module.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/MC/MCAsmInfo.h"
30 #include "llvm/MC/MCContext.h"
31 #include "llvm/MC/MCExpr.h"
32 #include "llvm/MC/MCSectionMachO.h"
33 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/MC/MCSymbol.h"
35 #include "llvm/Support/COFF.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Support/TargetRegistry.h"
39 using namespace llvm;
40
41 //===----------------------------------------------------------------------===//
42 // Primitive Helper Functions.
43 //===----------------------------------------------------------------------===//
44
45 /// runOnMachineFunction - Emit the function body.
46 ///
47 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
48   SetupMachineFunction(MF);
49
50   if (Subtarget->isTargetCOFF()) {
51     bool Intrn = MF.getFunction()->hasInternalLinkage();
52     OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
53     OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC
54                                               : COFF::IMAGE_SYM_CLASS_EXTERNAL);
55     OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
56                                                << COFF::SCT_COMPLEX_TYPE_SHIFT);
57     OutStreamer.EndCOFFSymbolDef();
58   }
59
60   // Have common code print out the function header with linkage info etc.
61   EmitFunctionHeader();
62
63   // Emit the rest of the function body.
64   EmitFunctionBody();
65
66   // We didn't modify anything.
67   return false;
68 }
69
70 /// printSymbolOperand - Print a raw symbol reference operand.  This handles
71 /// jump tables, constant pools, global address and external symbols, all of
72 /// which print to a label with various suffixes for relocation types etc.
73 static void printSymbolOperand(X86AsmPrinter &P, const MachineOperand &MO,
74                                raw_ostream &O) {
75   switch (MO.getType()) {
76   default: llvm_unreachable("unknown symbol type!");
77   case MachineOperand::MO_ConstantPoolIndex:
78     O << *P.GetCPISymbol(MO.getIndex());
79     P.printOffset(MO.getOffset(), O);
80     break;
81   case MachineOperand::MO_GlobalAddress: {
82     const GlobalValue *GV = MO.getGlobal();
83
84     MCSymbol *GVSym;
85     if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
86       GVSym = P.getSymbolWithGlobalValueBase(GV, "$stub");
87     else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
88              MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
89              MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
90       GVSym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
91     else
92       GVSym = P.getSymbol(GV);
93
94     // Handle dllimport linkage.
95     if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
96       GVSym =
97           P.OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
98
99     if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
100         MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
101       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
102       MachineModuleInfoImpl::StubValueTy &StubSym =
103           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
104       if (!StubSym.getPointer())
105         StubSym = MachineModuleInfoImpl::
106           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
107     } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
108       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
109       MachineModuleInfoImpl::StubValueTy &StubSym =
110           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(
111               Sym);
112       if (!StubSym.getPointer())
113         StubSym = MachineModuleInfoImpl::
114           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
115     } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
116       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$stub");
117       MachineModuleInfoImpl::StubValueTy &StubSym =
118           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
119       if (!StubSym.getPointer())
120         StubSym = MachineModuleInfoImpl::
121           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
122     }
123
124     // If the name begins with a dollar-sign, enclose it in parens.  We do this
125     // to avoid having it look like an integer immediate to the assembler.
126     if (GVSym->getName()[0] != '$')
127       O << *GVSym;
128     else
129       O << '(' << *GVSym << ')';
130     P.printOffset(MO.getOffset(), O);
131     break;
132   }
133   }
134
135   switch (MO.getTargetFlags()) {
136   default:
137     llvm_unreachable("Unknown target flag on GV operand");
138   case X86II::MO_NO_FLAG:    // No flag.
139     break;
140   case X86II::MO_DARWIN_NONLAZY:
141   case X86II::MO_DLLIMPORT:
142   case X86II::MO_DARWIN_STUB:
143     // These affect the name of the symbol, not any suffix.
144     break;
145   case X86II::MO_GOT_ABSOLUTE_ADDRESS:
146     O << " + [.-" << *P.MF->getPICBaseSymbol() << ']';
147     break;
148   case X86II::MO_PIC_BASE_OFFSET:
149   case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
150   case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
151     O << '-' << *P.MF->getPICBaseSymbol();
152     break;
153   case X86II::MO_TLSGD:     O << "@TLSGD";     break;
154   case X86II::MO_TLSLD:     O << "@TLSLD";     break;
155   case X86II::MO_TLSLDM:    O << "@TLSLDM";    break;
156   case X86II::MO_GOTTPOFF:  O << "@GOTTPOFF";  break;
157   case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
158   case X86II::MO_TPOFF:     O << "@TPOFF";     break;
159   case X86II::MO_DTPOFF:    O << "@DTPOFF";    break;
160   case X86II::MO_NTPOFF:    O << "@NTPOFF";    break;
161   case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
162   case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
163   case X86II::MO_GOT:       O << "@GOT";       break;
164   case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
165   case X86II::MO_PLT:       O << "@PLT";       break;
166   case X86II::MO_TLVP:      O << "@TLVP";      break;
167   case X86II::MO_TLVP_PIC_BASE:
168     O << "@TLVP" << '-' << *P.MF->getPICBaseSymbol();
169     break;
170   case X86II::MO_SECREL:    O << "@SECREL32";  break;
171   }
172 }
173
174 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI,
175                          unsigned OpNo, raw_ostream &O,
176                          const char *Modifier = nullptr, unsigned AsmVariant = 0);
177
178 /// printPCRelImm - This is used to print an immediate value that ends up
179 /// being encoded as a pc-relative value.  These print slightly differently, for
180 /// example, a $ is not emitted.
181 static void printPCRelImm(X86AsmPrinter &P, const MachineInstr *MI,
182                           unsigned OpNo, raw_ostream &O) {
183   const MachineOperand &MO = MI->getOperand(OpNo);
184   switch (MO.getType()) {
185   default: llvm_unreachable("Unknown pcrel immediate operand");
186   case MachineOperand::MO_Register:
187     // pc-relativeness was handled when computing the value in the reg.
188     printOperand(P, MI, OpNo, O);
189     return;
190   case MachineOperand::MO_Immediate:
191     O << MO.getImm();
192     return;
193   case MachineOperand::MO_GlobalAddress:
194     printSymbolOperand(P, MO, O);
195     return;
196   }
197 }
198
199 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI,
200                          unsigned OpNo, raw_ostream &O, const char *Modifier,
201                          unsigned AsmVariant) {
202   const MachineOperand &MO = MI->getOperand(OpNo);
203   switch (MO.getType()) {
204   default: llvm_unreachable("unknown operand type!");
205   case MachineOperand::MO_Register: {
206     // FIXME: Enumerating AsmVariant, so we can remove magic number.
207     if (AsmVariant == 0) O << '%';
208     unsigned Reg = MO.getReg();
209     if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
210       MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ?
211         MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
212                     ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
213       Reg = getX86SubSuperRegister(Reg, VT);
214     }
215     O << X86ATTInstPrinter::getRegisterName(Reg);
216     return;
217   }
218
219   case MachineOperand::MO_Immediate:
220     if (AsmVariant == 0) O << '$';
221     O << MO.getImm();
222     return;
223
224   case MachineOperand::MO_GlobalAddress: {
225     if (AsmVariant == 0) O << '$';
226     printSymbolOperand(P, MO, O);
227     break;
228   }
229   }
230 }
231
232 static void printLeaMemReference(X86AsmPrinter &P, const MachineInstr *MI,
233                                  unsigned Op, raw_ostream &O,
234                                  const char *Modifier = nullptr) {
235   const MachineOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
236   const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
237   const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
238
239   // If we really don't want to print out (rip), don't.
240   bool HasBaseReg = BaseReg.getReg() != 0;
241   if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
242       BaseReg.getReg() == X86::RIP)
243     HasBaseReg = false;
244
245   // HasParenPart - True if we will print out the () part of the mem ref.
246   bool HasParenPart = IndexReg.getReg() || HasBaseReg;
247
248   switch (DispSpec.getType()) {
249   default:
250     llvm_unreachable("unknown operand type!");
251   case MachineOperand::MO_Immediate: {
252     int DispVal = DispSpec.getImm();
253     if (DispVal || !HasParenPart)
254       O << DispVal;
255     break;
256   }
257   case MachineOperand::MO_GlobalAddress:
258   case MachineOperand::MO_ConstantPoolIndex:
259     printSymbolOperand(P, DispSpec, O);
260   }
261
262   if (Modifier && strcmp(Modifier, "H") == 0)
263     O << "+8";
264
265   if (HasParenPart) {
266     assert(IndexReg.getReg() != X86::ESP &&
267            "X86 doesn't allow scaling by ESP");
268
269     O << '(';
270     if (HasBaseReg)
271       printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier);
272
273     if (IndexReg.getReg()) {
274       O << ',';
275       printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier);
276       unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
277       if (ScaleVal != 1)
278         O << ',' << ScaleVal;
279     }
280     O << ')';
281   }
282 }
283
284 static void printMemReference(X86AsmPrinter &P, const MachineInstr *MI,
285                               unsigned Op, raw_ostream &O,
286                               const char *Modifier = nullptr) {
287   assert(isMem(MI, Op) && "Invalid memory reference!");
288   const MachineOperand &Segment = MI->getOperand(Op+X86::AddrSegmentReg);
289   if (Segment.getReg()) {
290     printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier);
291     O << ':';
292   }
293   printLeaMemReference(P, MI, Op, O, Modifier);
294 }
295
296 static void printIntelMemReference(X86AsmPrinter &P, const MachineInstr *MI,
297                                    unsigned Op, raw_ostream &O,
298                                    const char *Modifier = nullptr,
299                                    unsigned AsmVariant = 1) {
300   const MachineOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
301   unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
302   const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
303   const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
304   const MachineOperand &SegReg   = MI->getOperand(Op+X86::AddrSegmentReg);
305
306   // If this has a segment register, print it.
307   if (SegReg.getReg()) {
308     printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier, AsmVariant);
309     O << ':';
310   }
311
312   O << '[';
313
314   bool NeedPlus = false;
315   if (BaseReg.getReg()) {
316     printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier, AsmVariant);
317     NeedPlus = true;
318   }
319
320   if (IndexReg.getReg()) {
321     if (NeedPlus) O << " + ";
322     if (ScaleVal != 1)
323       O << ScaleVal << '*';
324     printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier, AsmVariant);
325     NeedPlus = true;
326   }
327
328   if (!DispSpec.isImm()) {
329     if (NeedPlus) O << " + ";
330     printOperand(P, MI, Op+X86::AddrDisp, O, Modifier, AsmVariant);
331   } else {
332     int64_t DispVal = DispSpec.getImm();
333     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
334       if (NeedPlus) {
335         if (DispVal > 0)
336           O << " + ";
337         else {
338           O << " - ";
339           DispVal = -DispVal;
340         }
341       }
342       O << DispVal;
343     }
344   }
345   O << ']';
346 }
347
348 static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
349                               char Mode, raw_ostream &O) {
350   unsigned Reg = MO.getReg();
351   switch (Mode) {
352   default: return true;  // Unknown mode.
353   case 'b': // Print QImode register
354     Reg = getX86SubSuperRegister(Reg, MVT::i8);
355     break;
356   case 'h': // Print QImode high register
357     Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
358     break;
359   case 'w': // Print HImode register
360     Reg = getX86SubSuperRegister(Reg, MVT::i16);
361     break;
362   case 'k': // Print SImode register
363     Reg = getX86SubSuperRegister(Reg, MVT::i32);
364     break;
365   case 'q':
366     // Print 64-bit register names if 64-bit integer registers are available.
367     // Otherwise, print 32-bit register names.
368     MVT::SimpleValueType Ty = P.getSubtarget().is64Bit() ? MVT::i64 : MVT::i32;
369     Reg = getX86SubSuperRegister(Reg, Ty);
370     break;
371   }
372
373   O << '%' << X86ATTInstPrinter::getRegisterName(Reg);
374   return false;
375 }
376
377 /// PrintAsmOperand - Print out an operand for an inline asm expression.
378 ///
379 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
380                                     unsigned AsmVariant,
381                                     const char *ExtraCode, raw_ostream &O) {
382   // Does this asm operand have a single letter operand modifier?
383   if (ExtraCode && ExtraCode[0]) {
384     if (ExtraCode[1] != 0) return true; // Unknown modifier.
385
386     const MachineOperand &MO = MI->getOperand(OpNo);
387
388     switch (ExtraCode[0]) {
389     default:
390       // See if this is a generic print operand
391       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
392     case 'a': // This is an address.  Currently only 'i' and 'r' are expected.
393       switch (MO.getType()) {
394       default:
395         return true;
396       case MachineOperand::MO_Immediate:
397         O << MO.getImm();
398         return false;
399       case MachineOperand::MO_ConstantPoolIndex:
400       case MachineOperand::MO_JumpTableIndex:
401       case MachineOperand::MO_ExternalSymbol:
402         llvm_unreachable("unexpected operand type!");
403       case MachineOperand::MO_GlobalAddress:
404         printSymbolOperand(*this, MO, O);
405         if (Subtarget->isPICStyleRIPRel())
406           O << "(%rip)";
407         return false;
408       case MachineOperand::MO_Register:
409         O << '(';
410         printOperand(*this, MI, OpNo, O);
411         O << ')';
412         return false;
413       }
414
415     case 'c': // Don't print "$" before a global var name or constant.
416       switch (MO.getType()) {
417       default:
418         printOperand(*this, MI, OpNo, O);
419         break;
420       case MachineOperand::MO_Immediate:
421         O << MO.getImm();
422         break;
423       case MachineOperand::MO_ConstantPoolIndex:
424       case MachineOperand::MO_JumpTableIndex:
425       case MachineOperand::MO_ExternalSymbol:
426         llvm_unreachable("unexpected operand type!");
427       case MachineOperand::MO_GlobalAddress:
428         printSymbolOperand(*this, MO, O);
429         break;
430       }
431       return false;
432
433     case 'A': // Print '*' before a register (it must be a register)
434       if (MO.isReg()) {
435         O << '*';
436         printOperand(*this, MI, OpNo, O);
437         return false;
438       }
439       return true;
440
441     case 'b': // Print QImode register
442     case 'h': // Print QImode high register
443     case 'w': // Print HImode register
444     case 'k': // Print SImode register
445     case 'q': // Print DImode register
446       if (MO.isReg())
447         return printAsmMRegister(*this, MO, ExtraCode[0], O);
448       printOperand(*this, MI, OpNo, O);
449       return false;
450
451     case 'P': // This is the operand of a call, treat specially.
452       printPCRelImm(*this, MI, OpNo, O);
453       return false;
454
455     case 'n':  // Negate the immediate or print a '-' before the operand.
456       // Note: this is a temporary solution. It should be handled target
457       // independently as part of the 'MC' work.
458       if (MO.isImm()) {
459         O << -MO.getImm();
460         return false;
461       }
462       O << '-';
463     }
464   }
465
466   printOperand(*this, MI, OpNo, O, /*Modifier*/ nullptr, AsmVariant);
467   return false;
468 }
469
470 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
471                                           unsigned OpNo, unsigned AsmVariant,
472                                           const char *ExtraCode,
473                                           raw_ostream &O) {
474   if (AsmVariant) {
475     printIntelMemReference(*this, MI, OpNo, O);
476     return false;
477   }
478
479   if (ExtraCode && ExtraCode[0]) {
480     if (ExtraCode[1] != 0) return true; // Unknown modifier.
481
482     switch (ExtraCode[0]) {
483     default: return true;  // Unknown modifier.
484     case 'b': // Print QImode register
485     case 'h': // Print QImode high register
486     case 'w': // Print HImode register
487     case 'k': // Print SImode register
488     case 'q': // Print SImode register
489       // These only apply to registers, ignore on mem.
490       break;
491     case 'H':
492       printMemReference(*this, MI, OpNo, O, "H");
493       return false;
494     case 'P': // Don't print @PLT, but do print as memory.
495       printMemReference(*this, MI, OpNo, O, "no-rip");
496       return false;
497     }
498   }
499   printMemReference(*this, MI, OpNo, O);
500   return false;
501 }
502
503 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
504   if (Subtarget->isTargetMacho())
505     OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
506
507   if (Subtarget->isTargetCOFF()) {
508     // Emit an absolute @feat.00 symbol.  This appears to be some kind of
509     // compiler features bitfield read by link.exe.
510     if (!Subtarget->is64Bit()) {
511       MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00"));
512       OutStreamer.BeginCOFFSymbolDef(S);
513       OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
514       OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
515       OutStreamer.EndCOFFSymbolDef();
516       // According to the PE-COFF spec, the LSB of this value marks the object
517       // for "registered SEH".  This means that all SEH handler entry points
518       // must be registered in .sxdata.  Use of any unregistered handlers will
519       // cause the process to terminate immediately.  LLVM does not know how to
520       // register any SEH handlers, so its object files should be safe.
521       S->setAbsolute();
522       OutStreamer.EmitSymbolAttribute(S, MCSA_Global);
523       OutStreamer.EmitAssignment(
524           S, MCConstantExpr::Create(int64_t(1), MMI->getContext()));
525     }
526   }
527 }
528
529 static void
530 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
531                          MachineModuleInfoImpl::StubValueTy &MCSym) {
532   // L_foo$stub:
533   OutStreamer.EmitLabel(StubLabel);
534   //   .indirect_symbol _foo
535   OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
536
537   if (MCSym.getInt())
538     // External to current translation unit.
539     OutStreamer.EmitIntValue(0, 4/*size*/);
540   else
541     // Internal to current translation unit.
542     //
543     // When we place the LSDA into the TEXT section, the type info
544     // pointers need to be indirect and pc-rel. We accomplish this by
545     // using NLPs; however, sometimes the types are local to the file.
546     // We need to fill in the value for the NLP in those cases.
547     OutStreamer.EmitValue(
548         MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()),
549         4 /*size*/);
550 }
551
552 void X86AsmPrinter::GenerateExportDirective(const MCSymbol *Sym, bool IsData) {
553   SmallString<128> Directive;
554   raw_svector_ostream OS(Directive);
555   StringRef Name = Sym->getName();
556
557   if (Subtarget->isTargetKnownWindowsMSVC())
558     OS << " /EXPORT:";
559   else
560     OS << " -export:";
561
562   if ((Subtarget->isTargetWindowsGNU() || Subtarget->isTargetWindowsCygwin()) &&
563       (Name[0] == getDataLayout().getGlobalPrefix()))
564     Name = Name.drop_front();
565
566   OS << Name;
567
568   if (IsData) {
569     if (Subtarget->isTargetKnownWindowsMSVC())
570       OS << ",DATA";
571     else
572       OS << ",data";
573   }
574
575   OS.flush();
576   OutStreamer.EmitBytes(Directive);
577 }
578
579 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
580   if (Subtarget->isTargetMacho()) {
581     // All darwin targets use mach-o.
582     MachineModuleInfoMachO &MMIMacho =
583       MMI->getObjFileInfo<MachineModuleInfoMachO>();
584
585     // Output stubs for dynamically-linked functions.
586     MachineModuleInfoMachO::SymbolListTy Stubs;
587
588     Stubs = MMIMacho.GetFnStubList();
589     if (!Stubs.empty()) {
590       const MCSection *TheSection =
591         OutContext.getMachOSection("__IMPORT", "__jump_table",
592                                    MachO::S_SYMBOL_STUBS |
593                                    MachO::S_ATTR_SELF_MODIFYING_CODE |
594                                    MachO::S_ATTR_PURE_INSTRUCTIONS,
595                                    5, SectionKind::getMetadata());
596       OutStreamer.SwitchSection(TheSection);
597
598       for (const auto &Stub : Stubs) {
599         // L_foo$stub:
600         OutStreamer.EmitLabel(Stub.first);
601         //   .indirect_symbol _foo
602         OutStreamer.EmitSymbolAttribute(Stub.second.getPointer(),
603                                         MCSA_IndirectSymbol);
604         // hlt; hlt; hlt; hlt; hlt     hlt = 0xf4.
605         const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4";
606         OutStreamer.EmitBytes(StringRef(HltInsts, 5));
607       }
608
609       Stubs.clear();
610       OutStreamer.AddBlankLine();
611     }
612
613     // Output stubs for external and common global variables.
614     Stubs = MMIMacho.GetGVStubList();
615     if (!Stubs.empty()) {
616       const MCSection *TheSection =
617         OutContext.getMachOSection("__IMPORT", "__pointers",
618                                    MachO::S_NON_LAZY_SYMBOL_POINTERS,
619                                    SectionKind::getMetadata());
620       OutStreamer.SwitchSection(TheSection);
621
622       for (auto &Stub : Stubs)
623         emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
624
625       Stubs.clear();
626       OutStreamer.AddBlankLine();
627     }
628
629     Stubs = MMIMacho.GetHiddenGVStubList();
630     if (!Stubs.empty()) {
631       const MCSection *TheSection =
632         OutContext.getMachOSection("__IMPORT", "__pointers",
633                                    MachO::S_NON_LAZY_SYMBOL_POINTERS,
634                                    SectionKind::getMetadata());
635       OutStreamer.SwitchSection(TheSection);
636
637       for (auto &Stub : Stubs)
638         emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
639
640       Stubs.clear();
641       OutStreamer.AddBlankLine();
642     }
643
644     SM.serializeToStackMapSection();
645
646     // Funny Darwin hack: This flag tells the linker that no global symbols
647     // contain code that falls through to other global symbols (e.g. the obvious
648     // implementation of multiple entry points).  If this doesn't occur, the
649     // linker can safely perform dead code stripping.  Since LLVM never
650     // generates code that does this, it is always safe to set.
651     OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
652   }
653
654   if (Subtarget->isTargetKnownWindowsMSVC() && MMI->usesVAFloatArgument()) {
655     StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused";
656     MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName);
657     OutStreamer.EmitSymbolAttribute(S, MCSA_Global);
658   }
659
660   if (Subtarget->isTargetCOFF()) {
661     // Necessary for dllexport support
662     std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;
663
664     for (const auto &Function : M)
665       if (Function.hasDLLExportStorageClass())
666         DLLExportedFns.push_back(getSymbol(&Function));
667
668     for (const auto &Global : M.globals())
669       if (Global.hasDLLExportStorageClass())
670         DLLExportedGlobals.push_back(getSymbol(&Global));
671
672     for (const auto &Alias : M.aliases()) {
673       const GlobalValue *GV = &Alias;
674       if (!GV->hasDLLExportStorageClass())
675         continue;
676
677       while (const GlobalAlias *A = dyn_cast<GlobalAlias>(GV))
678         GV = A->getAliasedGlobal();
679
680       if (isa<Function>(GV))
681         DLLExportedFns.push_back(getSymbol(&Alias));
682       else if (isa<GlobalVariable>(GV))
683         DLLExportedGlobals.push_back(getSymbol(&Alias));
684     }
685
686     // Output linker support code for dllexported globals on windows.
687     if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
688       const TargetLoweringObjectFileCOFF &TLOFCOFF =
689         static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
690
691       OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
692
693       for (auto & Symbol : DLLExportedGlobals)
694         GenerateExportDirective(Symbol, /*IsData=*/true);
695       for (auto & Symbol : DLLExportedFns)
696         GenerateExportDirective(Symbol, /*IsData=*/false);
697     }
698   }
699
700   if (Subtarget->isTargetELF()) {
701     const TargetLoweringObjectFileELF &TLOFELF =
702       static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
703
704     MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
705
706     // Output stubs for external and common global variables.
707     MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
708     if (!Stubs.empty()) {
709       OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
710       const DataLayout *TD = TM.getDataLayout();
711
712       for (const auto &Stub : Stubs) {
713         OutStreamer.EmitLabel(Stub.first);
714         OutStreamer.EmitSymbolValue(Stub.second.getPointer(),
715                                     TD->getPointerSize());
716       }
717       Stubs.clear();
718     }
719   }
720 }
721
722 //===----------------------------------------------------------------------===//
723 // Target Registry Stuff
724 //===----------------------------------------------------------------------===//
725
726 // Force static initialization.
727 extern "C" void LLVMInitializeX86AsmPrinter() {
728   RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target);
729   RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target);
730 }