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 /// runOnMachineFunction - Emit the function body.
53 bool X86AsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
54 SetupMachineFunction(MF
);
56 if (Subtarget
->isTargetCOFF() && !Subtarget
->isTargetEnvMacho()) {
57 bool Intrn
= MF
.getFunction()->hasInternalLinkage();
58 OutStreamer
.BeginCOFFSymbolDef(CurrentFnSym
);
59 OutStreamer
.EmitCOFFSymbolStorageClass(Intrn
? COFF::IMAGE_SYM_CLASS_STATIC
60 : COFF::IMAGE_SYM_CLASS_EXTERNAL
);
61 OutStreamer
.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
62 << COFF::SCT_COMPLEX_TYPE_SHIFT
);
63 OutStreamer
.EndCOFFSymbolDef();
66 // Have common code print out the function header with linkage info etc.
69 // Emit the rest of the function body.
72 // We didn't modify anything.
76 /// printSymbolOperand - Print a raw symbol reference operand. This handles
77 /// jump tables, constant pools, global address and external symbols, all of
78 /// which print to a label with various suffixes for relocation types etc.
79 void X86AsmPrinter::printSymbolOperand(const MachineOperand
&MO
,
81 switch (MO
.getType()) {
82 default: llvm_unreachable("unknown symbol type!");
83 case MachineOperand::MO_JumpTableIndex
:
84 O
<< *GetJTISymbol(MO
.getIndex());
86 case MachineOperand::MO_ConstantPoolIndex
:
87 O
<< *GetCPISymbol(MO
.getIndex());
88 printOffset(MO
.getOffset(), O
);
90 case MachineOperand::MO_GlobalAddress
: {
91 const GlobalValue
*GV
= MO
.getGlobal();
94 if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
)
95 GVSym
= GetSymbolWithGlobalValueBase(GV
, "$stub");
96 else if (MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY
||
97 MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE
||
98 MO
.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
)
99 GVSym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
101 GVSym
= Mang
->getSymbol(GV
);
103 // Handle dllimport linkage.
104 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
105 GVSym
= OutContext
.GetOrCreateSymbol(Twine("__imp_") + GVSym
->getName());
107 if (MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY
||
108 MO
.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE
) {
109 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
110 MachineModuleInfoImpl::StubValueTy
&StubSym
=
111 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getGVStubEntry(Sym
);
112 if (StubSym
.getPointer() == 0)
113 StubSym
= MachineModuleInfoImpl::
114 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
115 } else if (MO
.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
){
116 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$non_lazy_ptr");
117 MachineModuleInfoImpl::StubValueTy
&StubSym
=
118 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getHiddenGVStubEntry(Sym
);
119 if (StubSym
.getPointer() == 0)
120 StubSym
= MachineModuleInfoImpl::
121 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
122 } else if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
) {
123 MCSymbol
*Sym
= GetSymbolWithGlobalValueBase(GV
, "$stub");
124 MachineModuleInfoImpl::StubValueTy
&StubSym
=
125 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getFnStubEntry(Sym
);
126 if (StubSym
.getPointer() == 0)
127 StubSym
= MachineModuleInfoImpl::
128 StubValueTy(Mang
->getSymbol(GV
), !GV
->hasInternalLinkage());
131 // If the name begins with a dollar-sign, enclose it in parens. We do this
132 // to avoid having it look like an integer immediate to the assembler.
133 if (GVSym
->getName()[0] != '$')
136 O
<< '(' << *GVSym
<< ')';
137 printOffset(MO
.getOffset(), O
);
140 case MachineOperand::MO_ExternalSymbol
: {
141 const MCSymbol
*SymToPrint
;
142 if (MO
.getTargetFlags() == X86II::MO_DARWIN_STUB
) {
143 SmallString
<128> TempNameStr
;
144 TempNameStr
+= StringRef(MO
.getSymbolName());
145 TempNameStr
+= StringRef("$stub");
147 MCSymbol
*Sym
= GetExternalSymbolSymbol(TempNameStr
.str());
148 MachineModuleInfoImpl::StubValueTy
&StubSym
=
149 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>().getFnStubEntry(Sym
);
150 if (StubSym
.getPointer() == 0) {
151 TempNameStr
.erase(TempNameStr
.end()-5, TempNameStr
.end());
152 StubSym
= MachineModuleInfoImpl::
153 StubValueTy(OutContext
.GetOrCreateSymbol(TempNameStr
.str()),
156 SymToPrint
= StubSym
.getPointer();
158 SymToPrint
= GetExternalSymbolSymbol(MO
.getSymbolName());
161 // If the name begins with a dollar-sign, enclose it in parens. We do this
162 // to avoid having it look like an integer immediate to the assembler.
163 if (SymToPrint
->getName()[0] != '$')
166 O
<< '(' << *SymToPrint
<< '(';
171 switch (MO
.getTargetFlags()) {
173 llvm_unreachable("Unknown target flag on GV operand");
174 case X86II::MO_NO_FLAG
: // No flag.
176 case X86II::MO_DARWIN_NONLAZY
:
177 case X86II::MO_DLLIMPORT
:
178 case X86II::MO_DARWIN_STUB
:
179 // These affect the name of the symbol, not any suffix.
181 case X86II::MO_GOT_ABSOLUTE_ADDRESS
:
182 O
<< " + [.-" << *MF
->getPICBaseSymbol() << ']';
184 case X86II::MO_PIC_BASE_OFFSET
:
185 case X86II::MO_DARWIN_NONLAZY_PIC_BASE
:
186 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE
:
187 O
<< '-' << *MF
->getPICBaseSymbol();
189 case X86II::MO_TLSGD
: O
<< "@TLSGD"; break;
190 case X86II::MO_GOTTPOFF
: O
<< "@GOTTPOFF"; break;
191 case X86II::MO_INDNTPOFF
: O
<< "@INDNTPOFF"; break;
192 case X86II::MO_TPOFF
: O
<< "@TPOFF"; break;
193 case X86II::MO_NTPOFF
: O
<< "@NTPOFF"; break;
194 case X86II::MO_GOTPCREL
: O
<< "@GOTPCREL"; break;
195 case X86II::MO_GOT
: O
<< "@GOT"; break;
196 case X86II::MO_GOTOFF
: O
<< "@GOTOFF"; break;
197 case X86II::MO_PLT
: O
<< "@PLT"; break;
198 case X86II::MO_TLVP
: O
<< "@TLVP"; break;
199 case X86II::MO_TLVP_PIC_BASE
:
200 O
<< "@TLVP" << '-' << *MF
->getPICBaseSymbol();
205 /// print_pcrel_imm - This is used to print an immediate value that ends up
206 /// being encoded as a pc-relative value. These print slightly differently, for
207 /// example, a $ is not emitted.
208 void X86AsmPrinter::print_pcrel_imm(const MachineInstr
*MI
, unsigned OpNo
,
210 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
211 switch (MO
.getType()) {
212 default: llvm_unreachable("Unknown pcrel immediate operand");
213 case MachineOperand::MO_Register
:
214 // pc-relativeness was handled when computing the value in the reg.
215 printOperand(MI
, OpNo
, O
);
217 case MachineOperand::MO_Immediate
:
220 case MachineOperand::MO_MachineBasicBlock
:
221 O
<< *MO
.getMBB()->getSymbol();
223 case MachineOperand::MO_GlobalAddress
:
224 case MachineOperand::MO_ExternalSymbol
:
225 printSymbolOperand(MO
, O
);
231 void X86AsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
232 raw_ostream
&O
, const char *Modifier
) {
233 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
234 switch (MO
.getType()) {
235 default: llvm_unreachable("unknown operand type!");
236 case MachineOperand::MO_Register
: {
238 unsigned Reg
= MO
.getReg();
239 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
240 EVT VT
= (strcmp(Modifier
+6,"64") == 0) ?
241 MVT::i64
: ((strcmp(Modifier
+6, "32") == 0) ? MVT::i32
:
242 ((strcmp(Modifier
+6,"16") == 0) ? MVT::i16
: MVT::i8
));
243 Reg
= getX86SubSuperRegister(Reg
, VT
);
245 O
<< X86ATTInstPrinter::getRegisterName(Reg
);
249 case MachineOperand::MO_Immediate
:
250 O
<< '$' << MO
.getImm();
253 case MachineOperand::MO_JumpTableIndex
:
254 case MachineOperand::MO_ConstantPoolIndex
:
255 case MachineOperand::MO_GlobalAddress
:
256 case MachineOperand::MO_ExternalSymbol
: {
258 printSymbolOperand(MO
, O
);
264 void X86AsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
,
266 unsigned char value
= MI
->getOperand(Op
).getImm();
267 assert(value
<= 7 && "Invalid ssecc argument!");
269 case 0: O
<< "eq"; break;
270 case 1: O
<< "lt"; break;
271 case 2: O
<< "le"; break;
272 case 3: O
<< "unord"; break;
273 case 4: O
<< "neq"; break;
274 case 5: O
<< "nlt"; break;
275 case 6: O
<< "nle"; break;
276 case 7: O
<< "ord"; break;
280 void X86AsmPrinter::printLeaMemReference(const MachineInstr
*MI
, unsigned Op
,
281 raw_ostream
&O
, const char *Modifier
) {
282 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
283 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
284 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
286 // If we really don't want to print out (rip), don't.
287 bool HasBaseReg
= BaseReg
.getReg() != 0;
288 if (HasBaseReg
&& Modifier
&& !strcmp(Modifier
, "no-rip") &&
289 BaseReg
.getReg() == X86::RIP
)
292 // HasParenPart - True if we will print out the () part of the mem ref.
293 bool HasParenPart
= IndexReg
.getReg() || HasBaseReg
;
295 if (DispSpec
.isImm()) {
296 int DispVal
= DispSpec
.getImm();
297 if (DispVal
|| !HasParenPart
)
300 assert(DispSpec
.isGlobal() || DispSpec
.isCPI() ||
301 DispSpec
.isJTI() || DispSpec
.isSymbol());
302 printSymbolOperand(MI
->getOperand(Op
+3), O
);
305 if (Modifier
&& strcmp(Modifier
, "H") == 0)
309 assert(IndexReg
.getReg() != X86::ESP
&&
310 "X86 doesn't allow scaling by ESP");
314 printOperand(MI
, Op
, O
, Modifier
);
316 if (IndexReg
.getReg()) {
318 printOperand(MI
, Op
+2, O
, Modifier
);
319 unsigned ScaleVal
= MI
->getOperand(Op
+1).getImm();
321 O
<< ',' << ScaleVal
;
327 void X86AsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
328 raw_ostream
&O
, const char *Modifier
) {
329 assert(isMem(MI
, Op
) && "Invalid memory reference!");
330 const MachineOperand
&Segment
= MI
->getOperand(Op
+4);
331 if (Segment
.getReg()) {
332 printOperand(MI
, Op
+4, O
, Modifier
);
335 printLeaMemReference(MI
, Op
, O
, Modifier
);
338 void X86AsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
,
340 O
<< *MF
->getPICBaseSymbol() << '\n';
341 O
<< *MF
->getPICBaseSymbol() << ':';
344 bool X86AsmPrinter::printAsmMRegister(const MachineOperand
&MO
, char Mode
,
346 unsigned Reg
= MO
.getReg();
348 default: return true; // Unknown mode.
349 case 'b': // Print QImode register
350 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
352 case 'h': // Print QImode high register
353 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
355 case 'w': // Print HImode register
356 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
358 case 'k': // Print SImode register
359 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
361 case 'q': // Print DImode register
362 Reg
= getX86SubSuperRegister(Reg
, MVT::i64
);
366 O
<< '%' << X86ATTInstPrinter::getRegisterName(Reg
);
370 /// PrintAsmOperand - Print out an operand for an inline asm expression.
372 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
374 const char *ExtraCode
, raw_ostream
&O
) {
375 // Does this asm operand have a single letter operand modifier?
376 if (ExtraCode
&& ExtraCode
[0]) {
377 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
379 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
381 switch (ExtraCode
[0]) {
382 default: return true; // Unknown modifier.
383 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
388 if (MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isSymbol()) {
389 printSymbolOperand(MO
, O
);
390 if (Subtarget
->isPICStyleRIPRel())
396 printOperand(MI
, OpNo
, O
);
402 case 'c': // Don't print "$" before a global var name or constant.
405 else if (MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isSymbol())
406 printSymbolOperand(MO
, O
);
408 printOperand(MI
, OpNo
, O
);
411 case 'A': // Print '*' before a register (it must be a register)
414 printOperand(MI
, OpNo
, O
);
419 case 'b': // Print QImode register
420 case 'h': // Print QImode high register
421 case 'w': // Print HImode register
422 case 'k': // Print SImode register
423 case 'q': // Print DImode register
425 return printAsmMRegister(MO
, ExtraCode
[0], O
);
426 printOperand(MI
, OpNo
, O
);
429 case 'P': // This is the operand of a call, treat specially.
430 print_pcrel_imm(MI
, OpNo
, O
);
433 case 'n': // Negate the immediate or print a '-' before the operand.
434 // Note: this is a temporary solution. It should be handled target
435 // independently as part of the 'MC' work.
444 printOperand(MI
, OpNo
, O
);
448 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
449 unsigned OpNo
, unsigned AsmVariant
,
450 const char *ExtraCode
,
452 if (ExtraCode
&& ExtraCode
[0]) {
453 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
455 switch (ExtraCode
[0]) {
456 default: return true; // Unknown modifier.
457 case 'b': // Print QImode register
458 case 'h': // Print QImode high register
459 case 'w': // Print HImode register
460 case 'k': // Print SImode register
461 case 'q': // Print SImode register
462 // These only apply to registers, ignore on mem.
465 printMemReference(MI
, OpNo
, O
, "H");
467 case 'P': // Don't print @PLT, but do print as memory.
468 printMemReference(MI
, OpNo
, O
, "no-rip");
472 printMemReference(MI
, OpNo
, O
);
476 void X86AsmPrinter::EmitStartOfAsmFile(Module
&M
) {
477 if (Subtarget
->isTargetEnvMacho())
478 OutStreamer
.SwitchSection(getObjFileLowering().getTextSection());
482 void X86AsmPrinter::EmitEndOfAsmFile(Module
&M
) {
483 if (Subtarget
->isTargetEnvMacho()) {
484 // All darwin targets use mach-o.
485 MachineModuleInfoMachO
&MMIMacho
=
486 MMI
->getObjFileInfo
<MachineModuleInfoMachO
>();
488 // Output stubs for dynamically-linked functions.
489 MachineModuleInfoMachO::SymbolListTy Stubs
;
491 Stubs
= MMIMacho
.GetFnStubList();
492 if (!Stubs
.empty()) {
493 const MCSection
*TheSection
=
494 OutContext
.getMachOSection("__IMPORT", "__jump_table",
495 MCSectionMachO::S_SYMBOL_STUBS
|
496 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE
|
497 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
498 5, SectionKind::getMetadata());
499 OutStreamer
.SwitchSection(TheSection
);
501 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
503 OutStreamer
.EmitLabel(Stubs
[i
].first
);
504 // .indirect_symbol _foo
505 OutStreamer
.EmitSymbolAttribute(Stubs
[i
].second
.getPointer(),
506 MCSA_IndirectSymbol
);
507 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
508 const char HltInsts
[] = { -12, -12, -12, -12, -12 };
509 OutStreamer
.EmitBytes(StringRef(HltInsts
, 5), 0/*addrspace*/);
513 OutStreamer
.AddBlankLine();
516 // Output stubs for external and common global variables.
517 Stubs
= MMIMacho
.GetGVStubList();
518 if (!Stubs
.empty()) {
519 const MCSection
*TheSection
=
520 OutContext
.getMachOSection("__IMPORT", "__pointers",
521 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
,
522 SectionKind::getMetadata());
523 OutStreamer
.SwitchSection(TheSection
);
525 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
526 // L_foo$non_lazy_ptr:
527 OutStreamer
.EmitLabel(Stubs
[i
].first
);
528 // .indirect_symbol _foo
529 MachineModuleInfoImpl::StubValueTy
&MCSym
= Stubs
[i
].second
;
530 OutStreamer
.EmitSymbolAttribute(MCSym
.getPointer(),
531 MCSA_IndirectSymbol
);
534 // External to current translation unit.
535 OutStreamer
.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
537 // Internal to current translation unit.
539 // When we place the LSDA into the TEXT section, the type info
540 // pointers need to be indirect and pc-rel. We accomplish this by
541 // using NLPs. However, sometimes the types are local to the file. So
542 // we need to fill in the value for the NLP in those cases.
543 OutStreamer
.EmitValue(MCSymbolRefExpr::Create(MCSym
.getPointer(),
545 4/*size*/, 0/*addrspace*/);
548 OutStreamer
.AddBlankLine();
551 Stubs
= MMIMacho
.GetHiddenGVStubList();
552 if (!Stubs
.empty()) {
553 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
556 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
557 // L_foo$non_lazy_ptr:
558 OutStreamer
.EmitLabel(Stubs
[i
].first
);
560 OutStreamer
.EmitValue(MCSymbolRefExpr::
561 Create(Stubs
[i
].second
.getPointer(),
563 4/*size*/, 0/*addrspace*/);
566 OutStreamer
.AddBlankLine();
569 // Funny Darwin hack: This flag tells the linker that no global symbols
570 // contain code that falls through to other global symbols (e.g. the obvious
571 // implementation of multiple entry points). If this doesn't occur, the
572 // linker can safely perform dead code stripping. Since LLVM never
573 // generates code that does this, it is always safe to set.
574 OutStreamer
.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
577 if (Subtarget
->isTargetWindows() && !Subtarget
->isTargetCygMing() &&
578 MMI
->callsExternalVAFunctionWithFloatingPointArguments()) {
579 StringRef SymbolName
= Subtarget
->is64Bit() ? "_fltused" : "__fltused";
580 MCSymbol
*S
= MMI
->getContext().GetOrCreateSymbol(SymbolName
);
581 OutStreamer
.EmitSymbolAttribute(S
, MCSA_Global
);
584 if (Subtarget
->isTargetCOFF() && !Subtarget
->isTargetEnvMacho()) {
585 X86COFFMachineModuleInfo
&COFFMMI
=
586 MMI
->getObjFileInfo
<X86COFFMachineModuleInfo
>();
588 // Emit type information for external functions
589 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator
;
590 for (externals_iterator I
= COFFMMI
.externals_begin(),
591 E
= COFFMMI
.externals_end();
593 OutStreamer
.BeginCOFFSymbolDef(CurrentFnSym
);
594 OutStreamer
.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL
);
595 OutStreamer
.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
596 << COFF::SCT_COMPLEX_TYPE_SHIFT
);
597 OutStreamer
.EndCOFFSymbolDef();
600 // Necessary for dllexport support
601 std::vector
<const MCSymbol
*> DLLExportedFns
, DLLExportedGlobals
;
603 const TargetLoweringObjectFileCOFF
&TLOFCOFF
=
604 static_cast<const TargetLoweringObjectFileCOFF
&>(getObjFileLowering());
606 for (Module::const_iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
607 if (I
->hasDLLExportLinkage())
608 DLLExportedFns
.push_back(Mang
->getSymbol(I
));
610 for (Module::const_global_iterator I
= M
.global_begin(),
611 E
= M
.global_end(); I
!= E
; ++I
)
612 if (I
->hasDLLExportLinkage())
613 DLLExportedGlobals
.push_back(Mang
->getSymbol(I
));
615 // Output linker support code for dllexported globals on windows.
616 if (!DLLExportedGlobals
.empty() || !DLLExportedFns
.empty()) {
617 OutStreamer
.SwitchSection(TLOFCOFF
.getDrectveSection());
618 SmallString
<128> name
;
619 for (unsigned i
= 0, e
= DLLExportedGlobals
.size(); i
!= e
; ++i
) {
620 if (Subtarget
->isTargetWindows())
624 name
+= DLLExportedGlobals
[i
]->getName();
625 if (Subtarget
->isTargetWindows())
629 OutStreamer
.EmitBytes(name
, 0);
632 for (unsigned i
= 0, e
= DLLExportedFns
.size(); i
!= e
; ++i
) {
633 if (Subtarget
->isTargetWindows())
637 name
+= DLLExportedFns
[i
]->getName();
638 OutStreamer
.EmitBytes(name
, 0);
643 if (Subtarget
->isTargetELF()) {
644 const TargetLoweringObjectFileELF
&TLOFELF
=
645 static_cast<const TargetLoweringObjectFileELF
&>(getObjFileLowering());
647 MachineModuleInfoELF
&MMIELF
= MMI
->getObjFileInfo
<MachineModuleInfoELF
>();
649 // Output stubs for external and common global variables.
650 MachineModuleInfoELF::SymbolListTy Stubs
= MMIELF
.GetGVStubList();
651 if (!Stubs
.empty()) {
652 OutStreamer
.SwitchSection(TLOFELF
.getDataRelSection());
653 const TargetData
*TD
= TM
.getTargetData();
655 for (unsigned i
= 0, e
= Stubs
.size(); i
!= e
; ++i
) {
656 OutStreamer
.EmitLabel(Stubs
[i
].first
);
657 OutStreamer
.EmitSymbolValue(Stubs
[i
].second
.getPointer(),
658 TD
->getPointerSize(), 0);
666 X86AsmPrinter::getDebugValueLocation(const MachineInstr
*MI
) const {
667 MachineLocation Location
;
668 assert (MI
->getNumOperands() == 7 && "Invalid no. of machine operands!");
669 // Frame address. Currently handles register +- offset only.
671 if (MI
->getOperand(0).isReg() && MI
->getOperand(3).isImm())
672 Location
.set(MI
->getOperand(0).getReg(), MI
->getOperand(3).getImm());
674 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI
<< "\n");
679 void X86AsmPrinter::PrintDebugValueComment(const MachineInstr
*MI
,
681 // Only the target-dependent form of DBG_VALUE should get here.
682 // Referencing the offset and metadata as NOps-2 and NOps-1 is
683 // probably portable to other targets; frame pointer location is not.
684 unsigned NOps
= MI
->getNumOperands();
686 O
<< '\t' << MAI
->getCommentString() << "DEBUG_VALUE: ";
687 // cast away const; DIetc do not take const operands for some reason.
688 DIVariable
V(const_cast<MDNode
*>(MI
->getOperand(NOps
-1).getMetadata()));
689 if (V
.getContext().isSubprogram())
690 O
<< DISubprogram(V
.getContext()).getDisplayName() << ":";
693 // Frame address. Currently handles register +- offset only.
695 if (MI
->getOperand(0).isReg() && MI
->getOperand(0).getReg())
696 printOperand(MI
, 0, O
);
699 O
<< '+'; printOperand(MI
, 3, O
);
702 printOperand(MI
, NOps
-2, O
);
707 //===----------------------------------------------------------------------===//
708 // Target Registry Stuff
709 //===----------------------------------------------------------------------===//
711 static MCInstPrinter
*createX86MCInstPrinter(const Target
&T
,
713 unsigned SyntaxVariant
,
714 const MCAsmInfo
&MAI
) {
715 if (SyntaxVariant
== 0)
716 return new X86ATTInstPrinter(TM
, MAI
);
717 if (SyntaxVariant
== 1)
718 return new X86IntelInstPrinter(TM
, MAI
);
722 // Force static initialization.
723 extern "C" void LLVMInitializeX86AsmPrinter() {
724 RegisterAsmPrinter
<X86AsmPrinter
> X(TheX86_32Target
);
725 RegisterAsmPrinter
<X86AsmPrinter
> Y(TheX86_64Target
);
727 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target
,createX86MCInstPrinter
);
728 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target
,createX86MCInstPrinter
);