1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to X86 machine code.
13 //===----------------------------------------------------------------------===//
15 #include "X86AsmPrinter.h"
16 #include "InstPrinter/X86ATTInstPrinter.h"
17 #include "InstPrinter/X86IntelInstPrinter.h"
18 #include "X86MCInstLower.h"
20 #include "X86COFFMachineModuleInfo.h"
21 #include "X86MachineFunctionInfo.h"
22 #include "X86TargetMachine.h"
23 #include "llvm/CallingConv.h"
24 #include "llvm/DerivedTypes.h"
25 #include "llvm/Module.h"
26 #include "llvm/Type.h"
27 #include "llvm/Analysis/DebugInfo.h"
28 #include "llvm/Assembly/Writer.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/CodeGen/MachineJumpTableInfo.h"
36 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
37 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
38 #include "llvm/Support/COFF.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Target/Mangler.h"
42 #include "llvm/Target/TargetOptions.h"
43 #include "llvm/Target/TargetRegistry.h"
44 #include "llvm/ADT/SmallString.h"
47 //===----------------------------------------------------------------------===//
48 // Primitive Helper Functions.
49 //===----------------------------------------------------------------------===//
51 void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream
&O
) const {
52 const TargetLowering
*TLI
= TM
.getTargetLowering();
53 O
<< *static_cast<const X86TargetLowering
*>(TLI
)->getPICBaseSymbol(MF
,
57 /// runOnMachineFunction - Emit the function body.
59 bool X86AsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
60 SetupMachineFunction(MF
);
62 if (Subtarget
->isTargetCOFF()) {
63 bool Intrn
= MF
.getFunction()->hasInternalLinkage();
64 OutStreamer
.BeginCOFFSymbolDef(CurrentFnSym
);
65 OutStreamer
.EmitCOFFSymbolStorageClass(Intrn
? COFF::IMAGE_SYM_CLASS_STATIC
66 : COFF::IMAGE_SYM_CLASS_EXTERNAL
);
67 OutStreamer
.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
68 << COFF::SCT_COMPLEX_TYPE_SHIFT
);
69 OutStreamer
.EndCOFFSymbolDef();
72 // Have common code print out the function header with linkage info etc.
75 // Emit the rest of the function body.
78 // We didn't modify anything.
82 /// printSymbolOperand - Print a raw symbol reference operand. This handles
83 /// jump tables, constant pools, global address and external symbols, all of
84 /// which print to a label with various suffixes for relocation types etc.
85 void X86AsmPrinter::printSymbolOperand(const MachineOperand
&MO
,
87 switch (MO
.getType()) {
88 default: llvm_unreachable("unknown symbol type!");
89 case MachineOperand::MO_JumpTableIndex
:
90 O
<< *GetJTISymbol(MO
.getIndex());
92 case MachineOperand::MO_ConstantPoolIndex
:
93 O
<< *GetCPISymbol(MO
.getIndex());
94 printOffset(MO
.getOffset(), O
);
96 case MachineOperand::MO_GlobalAddress
: {
97 const GlobalValue
*GV
= MO
.getGlobal();
100 if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
)
101 GVSym
= GetSymbolWithGlobalValueBase(GV
, "$stub");
102 else if (MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY
||
103 MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE
||
104 MO
.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
)
105 GVSym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
107 GVSym
= Mang
->getSymbol(GV
);
109 // Handle dllimport linkage.
110 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
111 GVSym
= OutContext
.GetOrCreateSymbol(Twine("__imp_") + GVSym
->getName());
113 if (MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY
||
114 MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE
) {
115 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
116 MachineModuleInfoImpl::StubValueTy
&StubSym
=
117 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getGVStubEntry(Sym
);
118 if (StubSym
.getPointer() == 0)
119 StubSym
= MachineModuleInfoImpl::
120 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
121 } else if (MO
.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
){
122 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
123 MachineModuleInfoImpl::StubValueTy
&StubSym
=
124 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getHiddenGVStubEntry(Sym
);
125 if (StubSym
.getPointer() == 0)
126 StubSym
= MachineModuleInfoImpl::
127 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
128 } else if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
) {
129 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$stub");
130 MachineModuleInfoImpl::StubValueTy
&StubSym
=
131 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getFnStubEntry(Sym
);
132 if (StubSym
.getPointer() == 0)
133 StubSym
= MachineModuleInfoImpl::
134 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
137 // If the name begins with a dollar-sign, enclose it in parens. We do this
138 // to avoid having it look like an integer immediate to the assembler.
139 if (GVSym
->getName()[0] != '$')
142 O
<< '(' << *GVSym
<< ')';
143 printOffset(MO
.getOffset(), O
);
146 case MachineOperand::MO_ExternalSymbol
: {
147 const MCSymbol
*SymToPrint
;
148 if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
) {
149 SmallString
<128> TempNameStr
;
150 TempNameStr
+= StringRef(MO
.getSymbolName());
151 TempNameStr
+= StringRef("$stub");
153 MCSymbol
*Sym
= GetExternalSymbolSymbol(TempNameStr
.str());
154 MachineModuleInfoImpl::StubValueTy
&StubSym
=
155 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getFnStubEntry(Sym
);
156 if (StubSym
.getPointer() == 0) {
157 TempNameStr
.erase(TempNameStr
.end()-5, TempNameStr
.end());
158 StubSym
= MachineModuleInfoImpl::
159 StubValueTy(OutContext
.GetOrCreateSymbol(TempNameStr
.str()),
162 SymToPrint
= StubSym
.getPointer();
164 SymToPrint
= GetExternalSymbolSymbol(MO
.getSymbolName());
167 // If the name begins with a dollar-sign, enclose it in parens. We do this
168 // to avoid having it look like an integer immediate to the assembler.
169 if (SymToPrint
->getName()[0] != '$')
172 O
<< '(' << *SymToPrint
<< '(';
177 switch (MO
.getTargetFlags()) {
179 llvm_unreachable("Unknown target flag on GV operand");
180 case X86II::MO_NO_FLAG
: // No flag.
182 case X86II::MO_DARWIN_NONLAZY
:
183 case X86II::MO_DLLIMPORT
:
184 case X86II::MO_DARWIN_STUB
:
185 // These affect the name of the symbol, not any suffix.
187 case X86II::MO_GOT_ABSOLUTE_ADDRESS
:
189 PrintPICBaseSymbol(O
);
192 case X86II::MO_PIC_BASE_OFFSET
:
193 case X86II::MO_DARWIN_NONLAZY_PIC_BASE
:
194 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
:
196 PrintPICBaseSymbol(O
);
198 case X86II::MO_TLSGD
: O
<< "@TLSGD"; break;
199 case X86II::MO_GOTTPOFF
: O
<< "@GOTTPOFF"; break;
200 case X86II::MO_INDNTPOFF
: O
<< "@INDNTPOFF"; break;
201 case X86II::MO_TPOFF
: O
<< "@TPOFF"; break;
202 case X86II::MO_NTPOFF
: O
<< "@NTPOFF"; break;
203 case X86II::MO_GOTPCREL
: O
<< "@GOTPCREL"; break;
204 case X86II::MO_GOT
: O
<< "@GOT"; break;
205 case X86II::MO_GOTOFF
: O
<< "@GOTOFF"; break;
206 case X86II::MO_PLT
: O
<< "@PLT"; break;
207 case X86II::MO_TLVP
: O
<< "@TLVP"; break;
208 case X86II::MO_TLVP_PIC_BASE
:
210 PrintPICBaseSymbol(O
);
215 /// print_pcrel_imm - This is used to print an immediate value that ends up
216 /// being encoded as a pc-relative value. These print slightly differently, for
217 /// example, a $ is not emitted.
218 void X86AsmPrinter::print_pcrel_imm(const MachineInstr
*MI
, unsigned OpNo
,
220 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
221 switch (MO
.getType()) {
222 default: llvm_unreachable("Unknown pcrel immediate operand");
223 case MachineOperand::MO_Register
:
224 // pc-relativeness was handled when computing the value in the reg.
225 printOperand(MI
, OpNo
, O
);
227 case MachineOperand::MO_Immediate
:
230 case MachineOperand::MO_MachineBasicBlock
:
231 O
<< *MO
.getMBB()->getSymbol();
233 case MachineOperand::MO_GlobalAddress
:
234 case MachineOperand::MO_ExternalSymbol
:
235 printSymbolOperand(MO
, O
);
241 void X86AsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
242 raw_ostream
&O
, const char *Modifier
) {
243 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
244 switch (MO
.getType()) {
245 default: llvm_unreachable("unknown operand type!");
246 case MachineOperand::MO_Register
: {
248 unsigned Reg
= MO
.getReg();
249 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
250 EVT VT
= (strcmp(Modifier
+6,"64") == 0) ?
251 MVT::i64
: ((strcmp(Modifier
+6, "32") == 0) ? MVT::i32
:
252 ((strcmp(Modifier
+6,"16") == 0) ? MVT::i16
: MVT::i8
));
253 Reg
= getX86SubSuperRegister(Reg
, VT
);
255 O
<< X86ATTInstPrinter::getRegisterName(Reg
);
259 case MachineOperand::MO_Immediate
:
260 O
<< '$' << MO
.getImm();
263 case MachineOperand::MO_JumpTableIndex
:
264 case MachineOperand::MO_ConstantPoolIndex
:
265 case MachineOperand::MO_GlobalAddress
:
266 case MachineOperand::MO_ExternalSymbol
: {
268 printSymbolOperand(MO
, O
);
274 void X86AsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
,
276 unsigned char value
= MI
->getOperand(Op
).getImm();
277 assert(value
<= 7 && "Invalid ssecc argument!");
279 case 0: O
<< "eq"; break;
280 case 1: O
<< "lt"; break;
281 case 2: O
<< "le"; break;
282 case 3: O
<< "unord"; break;
283 case 4: O
<< "neq"; break;
284 case 5: O
<< "nlt"; break;
285 case 6: O
<< "nle"; break;
286 case 7: O
<< "ord"; break;
290 void X86AsmPrinter::printLeaMemReference(const MachineInstr
*MI
, unsigned Op
,
291 raw_ostream
&O
, const char *Modifier
) {
292 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
293 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
294 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
296 // If we really don't want to print out (rip), don't.
297 bool HasBaseReg
= BaseReg
.getReg() != 0;
298 if (HasBaseReg
&& Modifier
&& !strcmp(Modifier
, "no-rip") &&
299 BaseReg
.getReg() == X86::RIP
)
302 // HasParenPart - True if we will print out the () part of the mem ref.
303 bool HasParenPart
= IndexReg
.getReg() || HasBaseReg
;
305 if (DispSpec
.isImm()) {
306 int DispVal
= DispSpec
.getImm();
307 if (DispVal
|| !HasParenPart
)
310 assert(DispSpec
.isGlobal() || DispSpec
.isCPI() ||
311 DispSpec
.isJTI() || DispSpec
.isSymbol());
312 printSymbolOperand(MI
->getOperand(Op
+3), O
);
316 assert(IndexReg
.getReg() != X86::ESP
&&
317 "X86 doesn't allow scaling by ESP");
321 printOperand(MI
, Op
, O
, Modifier
);
323 if (IndexReg
.getReg()) {
325 printOperand(MI
, Op
+2, O
, Modifier
);
326 unsigned ScaleVal
= MI
->getOperand(Op
+1).getImm();
328 O
<< ',' << ScaleVal
;
334 void X86AsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
335 raw_ostream
&O
, const char *Modifier
) {
336 assert(isMem(MI
, Op
) && "Invalid memory reference!");
337 const MachineOperand
&Segment
= MI
->getOperand(Op
+4);
338 if (Segment
.getReg()) {
339 printOperand(MI
, Op
+4, O
, Modifier
);
342 printLeaMemReference(MI
, Op
, O
, Modifier
);
345 void X86AsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
,
347 PrintPICBaseSymbol(O
);
349 PrintPICBaseSymbol(O
);
353 bool X86AsmPrinter::printAsmMRegister(const MachineOperand
&MO
, char Mode
,
355 unsigned Reg
= MO
.getReg();
357 default: return true; // Unknown mode.
358 case 'b': // Print QImode register
359 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
361 case 'h': // Print QImode high register
362 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
364 case 'w': // Print HImode register
365 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
367 case 'k': // Print SImode register
368 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
370 case 'q': // Print DImode register
371 Reg
= getX86SubSuperRegister(Reg
, MVT::i64
);
375 O
<< '%' << X86ATTInstPrinter::getRegisterName(Reg
);
379 /// PrintAsmOperand - Print out an operand for an inline asm expression.
381 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
383 const char *ExtraCode
, raw_ostream
&O
) {
384 // Does this asm operand have a single letter operand modifier?
385 if (ExtraCode
&& ExtraCode
[0]) {
386 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
388 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
390 switch (ExtraCode
[0]) {
391 default: return true; // Unknown modifier.
392 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
397 if (MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isSymbol()) {
398 printSymbolOperand(MO
, O
);
399 if (Subtarget
->isPICStyleRIPRel())
405 printOperand(MI
, OpNo
, O
);
411 case 'c': // Don't print "$" before a global var name or constant.
414 else if (MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isSymbol())
415 printSymbolOperand(MO
, O
);
417 printOperand(MI
, OpNo
, O
);
420 case 'A': // Print '*' before a register (it must be a register)
423 printOperand(MI
, OpNo
, O
);
428 case 'b': // Print QImode register
429 case 'h': // Print QImode high register
430 case 'w': // Print HImode register
431 case 'k': // Print SImode register
432 case 'q': // Print DImode register
434 return printAsmMRegister(MO
, ExtraCode
[0], O
);
435 printOperand(MI
, OpNo
, O
);
438 case 'P': // This is the operand of a call, treat specially.
439 print_pcrel_imm(MI
, OpNo
, O
);
442 case 'n': // Negate the immediate or print a '-' before the operand.
443 // Note: this is a temporary solution. It should be handled target
444 // independently as part of the 'MC' work.
453 printOperand(MI
, OpNo
, O
);
457 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
458 unsigned OpNo
, unsigned AsmVariant
,
459 const char *ExtraCode
,
461 if (ExtraCode
&& ExtraCode
[0]) {
462 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
464 switch (ExtraCode
[0]) {
465 default: return true; // Unknown modifier.
466 case 'b': // Print QImode register
467 case 'h': // Print QImode high register
468 case 'w': // Print HImode register
469 case 'k': // Print SImode register
470 case 'q': // Print SImode register
471 // These only apply to registers, ignore on mem.
473 case 'P': // Don't print @PLT, but do print as memory.
474 printMemReference(MI
, OpNo
, O
, "no-rip");
478 printMemReference(MI
, OpNo
, O
);
482 void X86AsmPrinter::EmitStartOfAsmFile(Module
&M
) {
483 if (Subtarget
->isTargetDarwin())
484 OutStreamer
.SwitchSection(getObjFileLowering().getTextSection());
488 void X86AsmPrinter::EmitEndOfAsmFile(Module
&M
) {
489 if (Subtarget
->isTargetDarwin()) {
490 // All darwin targets use mach-o.
491 MachineModuleInfoMachO
&MMIMacho
=
492 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
494 // Output stubs for dynamically-linked functions.
495 MachineModuleInfoMachO::SymbolListTy Stubs
;
497 Stubs
= MMIMacho
.GetFnStubList();
498 if (!Stubs
.empty()) {
499 const MCSection
*TheSection
=
500 OutContext
.getMachOSection("__IMPORT", "__jump_table",
501 MCSectionMachO::S_SYMBOL_STUBS
|
502 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE
|
503 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
504 5, SectionKind::getMetadata());
505 OutStreamer
.SwitchSection(TheSection
);
507 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
509 OutStreamer
.EmitLabel(Stubs
[i
].first
);
510 // .indirect_symbol _foo
511 OutStreamer
.EmitSymbolAttribute(Stubs
[i
].second
.getPointer(),
512 MCSA_IndirectSymbol
);
513 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
514 const char HltInsts
[] = { -12, -12, -12, -12, -12 };
515 OutStreamer
.EmitBytes(StringRef(HltInsts
, 5), 0/*addrspace*/);
519 OutStreamer
.AddBlankLine();
522 // Output stubs for external and common global variables.
523 Stubs
= MMIMacho
.GetGVStubList();
524 if (!Stubs
.empty()) {
525 const MCSection
*TheSection
=
526 OutContext
.getMachOSection("__IMPORT", "__pointers",
527 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
,
528 SectionKind::getMetadata());
529 OutStreamer
.SwitchSection(TheSection
);
531 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
532 // L_foo$non_lazy_ptr:
533 OutStreamer
.EmitLabel(Stubs
[i
].first
);
534 // .indirect_symbol _foo
535 MachineModuleInfoImpl::StubValueTy
&MCSym
= Stubs
[i
].second
;
536 OutStreamer
.EmitSymbolAttribute(MCSym
.getPointer(),
537 MCSA_IndirectSymbol
);
540 // External to current translation unit.
541 OutStreamer
.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
543 // Internal to current translation unit.
545 // When we place the LSDA into the TEXT section, the type info
546 // pointers need to be indirect and pc-rel. We accomplish this by
547 // using NLPs. However, sometimes the types are local to the file. So
548 // we need to fill in the value for the NLP in those cases.
549 OutStreamer
.EmitValue(MCSymbolRefExpr::Create(MCSym
.getPointer(),
551 4/*size*/, 0/*addrspace*/);
554 OutStreamer
.AddBlankLine();
557 Stubs
= MMIMacho
.GetHiddenGVStubList();
558 if (!Stubs
.empty()) {
559 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
562 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
563 // L_foo$non_lazy_ptr:
564 OutStreamer
.EmitLabel(Stubs
[i
].first
);
566 OutStreamer
.EmitValue(MCSymbolRefExpr::
567 Create(Stubs
[i
].second
.getPointer(),
569 4/*size*/, 0/*addrspace*/);
572 OutStreamer
.AddBlankLine();
575 // Funny Darwin hack: This flag tells the linker that no global symbols
576 // contain code that falls through to other global symbols (e.g. the obvious
577 // implementation of multiple entry points). If this doesn't occur, the
578 // linker can safely perform dead code stripping. Since LLVM never
579 // generates code that does this, it is always safe to set.
580 OutStreamer
.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
583 if (Subtarget
->isTargetWindows()
584 && !Subtarget
->isTargetCygMing()
585 && MMI
->callsExternalVAFunctionWithFloatingPointArguments()) {
586 StringRef SymbolName
= Subtarget
->is64Bit() ? "_fltused" : "__fltused";
587 MCSymbol
*S
= MMI
->getContext().GetOrCreateSymbol(SymbolName
);
588 OutStreamer
.EmitSymbolAttribute(S
, MCSA_Global
);
591 if (Subtarget
->isTargetCOFF()) {
592 X86COFFMachineModuleInfo
&COFFMMI
=
593 MMI
->getObjFileInfo
<X86COFFMachineModuleInfo
>();
595 // Emit type information for external functions
596 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator
;
597 for (externals_iterator I
= COFFMMI
.externals_begin(),
598 E
= COFFMMI
.externals_end();
600 OutStreamer
.BeginCOFFSymbolDef(CurrentFnSym
);
601 OutStreamer
.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL
);
602 OutStreamer
.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
603 << COFF::SCT_COMPLEX_TYPE_SHIFT
);
604 OutStreamer
.EndCOFFSymbolDef();
607 // Necessary for dllexport support
608 std::vector
<const MCSymbol
*> DLLExportedFns
, DLLExportedGlobals
;
610 const TargetLoweringObjectFileCOFF
&TLOFCOFF
=
611 static_cast<const TargetLoweringObjectFileCOFF
&>(getObjFileLowering());
613 for (Module::const_iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
614 if (I
->hasDLLExportLinkage())
615 DLLExportedFns
.push_back(Mang
->getSymbol(I
));
617 for (Module::const_global_iterator I
= M
.global_begin(),
618 E
= M
.global_end(); I
!= E
; ++I
)
619 if (I
->hasDLLExportLinkage())
620 DLLExportedGlobals
.push_back(Mang
->getSymbol(I
));
622 // Output linker support code for dllexported globals on windows.
623 if (!DLLExportedGlobals
.empty() || !DLLExportedFns
.empty()) {
624 OutStreamer
.SwitchSection(TLOFCOFF
.getDrectveSection());
625 SmallString
<128> name
;
626 for (unsigned i
= 0, e
= DLLExportedGlobals
.size(); i
!= e
; ++i
) {
627 if (Subtarget
->isTargetWindows())
631 name
+= DLLExportedGlobals
[i
]->getName();
632 if (Subtarget
->isTargetWindows())
636 OutStreamer
.EmitBytes(name
, 0);
639 for (unsigned i
= 0, e
= DLLExportedFns
.size(); i
!= e
; ++i
) {
640 if (Subtarget
->isTargetWindows())
644 name
+= DLLExportedFns
[i
]->getName();
645 OutStreamer
.EmitBytes(name
, 0);
650 if (Subtarget
->isTargetELF()) {
651 const TargetLoweringObjectFileELF
&TLOFELF
=
652 static_cast<const TargetLoweringObjectFileELF
&>(getObjFileLowering());
654 MachineModuleInfoELF
&MMIELF
= MMI
->getObjFileInfo
<MachineModuleInfoELF
>();
656 // Output stubs for external and common global variables.
657 MachineModuleInfoELF::SymbolListTy Stubs
= MMIELF
.GetGVStubList();
658 if (!Stubs
.empty()) {
659 OutStreamer
.SwitchSection(TLOFELF
.getDataRelSection());
660 const TargetData
*TD
= TM
.getTargetData();
662 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
663 OutStreamer
.EmitLabel(Stubs
[i
].first
);
664 OutStreamer
.EmitSymbolValue(Stubs
[i
].second
.getPointer(),
665 TD
->getPointerSize(), 0);
673 X86AsmPrinter::getDebugValueLocation(const MachineInstr
*MI
) const {
674 MachineLocation Location
;
675 assert (MI
->getNumOperands() == 7 && "Invalid no. of machine operands!");
676 // Frame address. Currently handles register +- offset only.
678 if (MI
->getOperand(0).isReg() && MI
->getOperand(3).isImm())
679 Location
.set(MI
->getOperand(0).getReg(), MI
->getOperand(3).getImm());
681 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI
<< "\n");
686 void X86AsmPrinter::PrintDebugValueComment(const MachineInstr
*MI
,
688 // Only the target-dependent form of DBG_VALUE should get here.
689 // Referencing the offset and metadata as NOps-2 and NOps-1 is
690 // probably portable to other targets; frame pointer location is not.
691 unsigned NOps
= MI
->getNumOperands();
693 O
<< '\t' << MAI
->getCommentString() << "DEBUG_VALUE: ";
694 // cast away const; DIetc do not take const operands for some reason.
695 DIVariable
V(const_cast<MDNode
*>(MI
->getOperand(NOps
-1).getMetadata()));
696 if (V
.getContext().isSubprogram())
697 O
<< DISubprogram(V
.getContext()).getDisplayName() << ":";
700 // Frame address. Currently handles register +- offset only.
702 if (MI
->getOperand(0).isReg() && MI
->getOperand(0).getReg())
703 printOperand(MI
, 0, O
);
706 O
<< '+'; printOperand(MI
, 3, O
);
709 printOperand(MI
, NOps
-2, O
);
714 //===----------------------------------------------------------------------===//
715 // Target Registry Stuff
716 //===----------------------------------------------------------------------===//
718 static MCInstPrinter
*createX86MCInstPrinter(const Target
&T
,
719 unsigned SyntaxVariant
,
720 const MCAsmInfo
&MAI
) {
721 if (SyntaxVariant
== 0)
722 return new X86ATTInstPrinter(MAI
);
723 if (SyntaxVariant
== 1)
724 return new X86IntelInstPrinter(MAI
);
728 // Force static initialization.
729 extern "C" void LLVMInitializeX86AsmPrinter() {
730 RegisterAsmPrinter
<X86AsmPrinter
> X(TheX86_32Target
);
731 RegisterAsmPrinter
<X86AsmPrinter
> Y(TheX86_64Target
);
733 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target
,createX86MCInstPrinter
);
734 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target
,createX86MCInstPrinter
);