1 //===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly -----===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to AT&T format assembly
12 // language. This printer is the output mechanism used by `llc'.
14 //===----------------------------------------------------------------------===//
16 #define DEBUG_TYPE "asm-printer"
17 #include "X86ATTAsmPrinter.h"
20 #include "X86MachineFunctionInfo.h"
21 #include "X86TargetMachine.h"
22 #include "X86TargetAsmInfo.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/CallingConv.h"
25 #include "llvm/Module.h"
26 #include "llvm/Support/Mangler.h"
27 #include "llvm/Target/TargetAsmInfo.h"
28 #include "llvm/Target/TargetOptions.h"
29 #include "llvm/ADT/Statistic.h"
32 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
34 static std::string
computePICLabel(unsigned FnNum
,
35 const TargetAsmInfo
*TAI
,
36 const X86Subtarget
* Subtarget
) {
38 if (Subtarget
->isTargetDarwin())
39 label
= "\"L" + utostr_32(FnNum
) + "$pb\"";
40 else if (Subtarget
->isTargetELF())
41 label
= ".Lllvm$" + utostr_32(FnNum
) + "$piclabel";
43 assert(0 && "Don't know how to print PIC label!\n");
48 /// getSectionForFunction - Return the section that we should emit the
49 /// specified function body into.
50 std::string
X86ATTAsmPrinter::getSectionForFunction(const Function
&F
) const {
51 switch (F
.getLinkage()) {
52 default: assert(0 && "Unknown linkage type!");
53 case Function::InternalLinkage
:
54 case Function::DLLExportLinkage
:
55 case Function::ExternalLinkage
:
56 return TAI
->getTextSection();
57 case Function::WeakLinkage
:
58 case Function::LinkOnceLinkage
:
59 if (Subtarget
->isTargetDarwin()) {
60 return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
61 } else if (Subtarget
->isTargetCygMing()) {
62 return "\t.section\t.text$linkonce." + CurrentFnName
+ ",\"ax\"";
64 return "\t.section\t.llvm.linkonce.t." + CurrentFnName
+
70 /// runOnMachineFunction - This uses the printMachineInstruction()
71 /// method to print assembly for each instruction.
73 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
74 if (TAI
->doesSupportDebugInformation()) {
75 // Let PassManager know we need debug information and relay
76 // the MachineModuleInfo address on to DwarfWriter.
77 MMI
= &getAnalysis
<MachineModuleInfo
>();
78 DW
.SetModuleInfo(MMI
);
81 SetupMachineFunction(MF
);
84 // Print out constants referenced by the function
85 EmitConstantPool(MF
.getConstantPool());
87 // Print out labels for the function.
88 const Function
*F
= MF
.getFunction();
89 unsigned CC
= F
->getCallingConv();
91 // Populate function information map. Actually, We don't want to populate
92 // non-stdcall or non-fastcall functions' information right now.
93 if (CC
== CallingConv::X86_StdCall
|| CC
== CallingConv::X86_FastCall
)
94 FunctionInfoMap
[F
] = *MF
.getInfo
<X86MachineFunctionInfo
>();
96 X86SharedAsmPrinter::decorateName(CurrentFnName
, F
);
98 SwitchToTextSection(getSectionForFunction(*F
).c_str(), F
);
100 switch (F
->getLinkage()) {
101 default: assert(0 && "Unknown linkage type!");
102 case Function::InternalLinkage
: // Symbols default to internal.
103 if (Subtarget
->isTargetDarwin())
104 // FIXME: This should be parameterized somewhere.
105 EmitAlignment(4, F
, 0, true, 0x90);
107 EmitAlignment(4, F
); // FIXME: This should be parameterized somewhere.
109 case Function::DLLExportLinkage
:
110 DLLExportedFns
.insert(Mang
->makeNameProper(F
->getName(), ""));
112 case Function::ExternalLinkage
:
113 if (Subtarget
->isTargetDarwin())
114 // FIXME: This should be parameterized somewhere.
115 EmitAlignment(4, F
, 0, true, 0x90);
117 EmitAlignment(4, F
); // FIXME: This should be parameterized somewhere.
118 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
120 case Function::LinkOnceLinkage
:
121 case Function::WeakLinkage
:
122 if (Subtarget
->isTargetDarwin()) {
123 // FIXME: This should be parameterized somewhere.
124 EmitAlignment(4, F
, 0, true, 0x90);
125 O
<< "\t.globl\t" << CurrentFnName
<< "\n";
126 O
<< "\t.weak_definition\t" << CurrentFnName
<< "\n";
127 } else if (Subtarget
->isTargetCygMing()) {
128 EmitAlignment(4, F
); // FIXME: This should be parameterized somewhere.
129 O
<< "\t.globl " << CurrentFnName
<< "\n";
130 O
<< "\t.linkonce discard\n";
132 EmitAlignment(4, F
); // FIXME: This should be parameterized somewhere.
133 O
<< "\t.weak\t" << CurrentFnName
<< "\n";
137 if (F
->hasHiddenVisibility()) {
138 if (const char *Directive
= TAI
->getHiddenDirective())
139 O
<< Directive
<< CurrentFnName
<< "\n";
140 } else if (F
->hasProtectedVisibility()) {
141 if (const char *Directive
= TAI
->getProtectedDirective())
142 O
<< Directive
<< CurrentFnName
<< "\n";
145 if (Subtarget
->isTargetELF())
146 O
<< "\t.type\t" << CurrentFnName
<< ",@function\n";
147 else if (Subtarget
->isTargetCygMing()) {
148 O
<< "\t.def\t " << CurrentFnName
150 (F
->getLinkage() == Function::InternalLinkage
? COFF::C_STAT
: COFF::C_EXT
)
151 << ";\t.type\t" << (COFF::DT_FCN
<< COFF::N_BTSHFT
)
155 O
<< CurrentFnName
<< ":\n";
156 // Add some workaround for linkonce linkage on Cygwin\MinGW
157 if (Subtarget
->isTargetCygMing() &&
158 (F
->getLinkage() == Function::LinkOnceLinkage
||
159 F
->getLinkage() == Function::WeakLinkage
))
160 O
<< "Lllvm$workaround$fake$stub$" << CurrentFnName
<< ":\n";
162 if (TAI
->doesSupportDebugInformation()) {
163 // Emit pre-function debug information.
164 DW
.BeginFunction(&MF
);
167 // Print out code for the function.
168 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
170 // Print a label for the basic block.
171 if (I
->pred_begin() != I
->pred_end()) {
172 printBasicBlockLabel(I
, true);
175 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
177 // Print the assembly for the instruction.
179 printMachineInstruction(II
);
183 if (TAI
->hasDotTypeDotSizeDirective())
184 O
<< "\t.size\t" << CurrentFnName
<< ", .-" << CurrentFnName
<< "\n";
186 if (TAI
->doesSupportDebugInformation()) {
187 // Emit post-function debug information.
191 // Print out jump tables referenced by the function.
192 EmitJumpTableInfo(MF
.getJumpTableInfo(), MF
);
194 // We didn't modify anything.
198 static inline bool printGOT(TargetMachine
&TM
, const X86Subtarget
* ST
) {
199 return ST
->isPICStyleGOT() && TM
.getRelocationModel() == Reloc::PIC_
;
202 static inline bool printStub(TargetMachine
&TM
, const X86Subtarget
* ST
) {
203 return ST
->isPICStyleStub() && TM
.getRelocationModel() != Reloc::Static
;
206 void X86ATTAsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
207 const char *Modifier
, bool NotRIPRel
) {
208 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
209 const MRegisterInfo
&RI
= *TM
.getRegisterInfo();
210 switch (MO
.getType()) {
211 case MachineOperand::MO_Register
: {
212 assert(MRegisterInfo::isPhysicalRegister(MO
.getReg()) &&
213 "Virtual registers should not make it this far!");
215 unsigned Reg
= MO
.getReg();
216 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
217 MVT::ValueType VT
= (strcmp(Modifier
+6,"64") == 0) ?
218 MVT::i64
: ((strcmp(Modifier
+6, "32") == 0) ? MVT::i32
:
219 ((strcmp(Modifier
+6,"16") == 0) ? MVT::i16
: MVT::i8
));
220 Reg
= getX86SubSuperRegister(Reg
, VT
);
222 for (const char *Name
= RI
.get(Reg
).Name
; *Name
; ++Name
)
223 O
<< (char)tolower(*Name
);
227 case MachineOperand::MO_Immediate
:
229 (strcmp(Modifier
, "debug") && strcmp(Modifier
, "mem")))
231 O
<< MO
.getImmedValue();
233 case MachineOperand::MO_MachineBasicBlock
:
234 printBasicBlockLabel(MO
.getMachineBasicBlock());
236 case MachineOperand::MO_JumpTableIndex
: {
237 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
238 if (!isMemOp
) O
<< '$';
239 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_"
240 << MO
.getJumpTableIndex();
242 if (TM
.getRelocationModel() == Reloc::PIC_
) {
243 if (Subtarget
->isPICStyleStub())
244 O
<< "-\"" << TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
246 else if (Subtarget
->isPICStyleGOT())
250 if (isMemOp
&& Subtarget
->isPICStyleRIPRel() && !NotRIPRel
)
254 case MachineOperand::MO_ConstantPoolIndex
: {
255 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
256 if (!isMemOp
) O
<< '$';
257 O
<< TAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
258 << MO
.getConstantPoolIndex();
260 if (TM
.getRelocationModel() == Reloc::PIC_
) {
261 if (Subtarget
->isPICStyleStub())
262 O
<< "-\"" << TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
264 else if (Subtarget
->isPICStyleGOT())
268 int Offset
= MO
.getOffset();
274 if (isMemOp
&& Subtarget
->isPICStyleRIPRel() && !NotRIPRel
)
278 case MachineOperand::MO_GlobalAddress
: {
279 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
280 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
281 bool needCloseParen
= false;
283 GlobalValue
*GV
= MO
.getGlobal();
284 GlobalVariable
*GVar
= dyn_cast
<GlobalVariable
>(GV
);
285 bool isThreadLocal
= GVar
&& GVar
->isThreadLocal();
287 std::string Name
= Mang
->getValueName(GV
);
288 X86SharedAsmPrinter::decorateName(Name
, GV
);
290 if (!isMemOp
&& !isCallOp
)
292 else if (Name
[0] == '$') {
293 // The name begins with a dollar-sign. In order to avoid having it look
294 // like an integer immediate to the assembler, enclose it in parens.
296 needCloseParen
= true;
299 if (printStub(TM
, Subtarget
)) {
300 // Link-once, declaration, or Weakly-linked global variables need
301 // non-lazily-resolved stubs
302 if (GV
->isDeclaration() ||
303 GV
->hasWeakLinkage() ||
304 GV
->hasLinkOnceLinkage()) {
305 // Dynamically-resolved functions need a stub for the function.
306 if (isCallOp
&& isa
<Function
>(GV
)) {
307 FnStubs
.insert(Name
);
308 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
310 GVStubs
.insert(Name
);
311 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$non_lazy_ptr";
314 if (GV
->hasDLLImportLinkage())
319 if (!isCallOp
&& TM
.getRelocationModel() == Reloc::PIC_
)
320 O
<< "-\"" << TAI
->getPrivateGlobalPrefix() << getFunctionNumber()
323 if (GV
->hasDLLImportLinkage()) {
328 if (isCallOp
&& isa
<Function
>(GV
)) {
329 if (printGOT(TM
, Subtarget
)) {
330 // Assemble call via PLT for non-local symbols
331 if (!(GV
->hasHiddenVisibility() || GV
->hasProtectedVisibility()) ||
335 if (Subtarget
->isTargetCygMing() && GV
->isDeclaration())
336 // Save function name for later type emission
337 FnStubs
.insert(Name
);
341 if (GV
->hasExternalWeakLinkage())
342 ExtWeakSymbols
.insert(GV
);
344 int Offset
= MO
.getOffset();
351 if (TM
.getRelocationModel() == Reloc::PIC_
)
352 O
<< "@TLSGD"; // general dynamic TLS model
354 if (GV
->isDeclaration())
355 O
<< "@INDNTPOFF"; // initial exec TLS model
357 O
<< "@NTPOFF"; // local exec TLS model
358 } else if (isMemOp
) {
359 if (printGOT(TM
, Subtarget
)) {
360 if (Subtarget
->GVRequiresExtraLoad(GV
, TM
, false))
364 } else if (Subtarget
->isPICStyleRIPRel() && !NotRIPRel
) {
365 if ((GV
->isDeclaration() ||
366 GV
->hasWeakLinkage() ||
367 GV
->hasLinkOnceLinkage()) &&
368 TM
.getRelocationModel() != Reloc::Static
)
371 if (needCloseParen
) {
372 needCloseParen
= false;
376 // Use rip when possible to reduce code size, except when
377 // index or base register are also part of the address. e.g.
378 // foo(%rip)(%rcx,%rax,4) is not legal
388 case MachineOperand::MO_ExternalSymbol
: {
389 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
390 bool needCloseParen
= false;
391 std::string
Name(TAI
->getGlobalPrefix());
392 Name
+= MO
.getSymbolName();
393 if (isCallOp
&& printStub(TM
, Subtarget
)) {
394 FnStubs
.insert(Name
);
395 O
<< TAI
->getPrivateGlobalPrefix() << Name
<< "$stub";
400 else if (Name
[0] == '$') {
401 // The name begins with a dollar-sign. In order to avoid having it look
402 // like an integer immediate to the assembler, enclose it in parens.
404 needCloseParen
= true;
409 if (printGOT(TM
, Subtarget
)) {
410 std::string
GOTName(TAI
->getGlobalPrefix());
411 GOTName
+="_GLOBAL_OFFSET_TABLE_";
413 // HACK! Emit extra offset to PC during printing GOT offset to
414 // compensate for the size of popl instruction. The resulting code
418 // popl %some_register
419 // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
421 << computePICLabel(getFunctionNumber(), TAI
, Subtarget
) << "]";
430 if (!isCallOp
&& Subtarget
->isPICStyleRIPRel())
436 O
<< "<unknown operand type>"; return;
440 void X86ATTAsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
) {
441 unsigned char value
= MI
->getOperand(Op
).getImmedValue();
442 assert(value
<= 7 && "Invalid ssecc argument!");
444 case 0: O
<< "eq"; break;
445 case 1: O
<< "lt"; break;
446 case 2: O
<< "le"; break;
447 case 3: O
<< "unord"; break;
448 case 4: O
<< "neq"; break;
449 case 5: O
<< "nlt"; break;
450 case 6: O
<< "nle"; break;
451 case 7: O
<< "ord"; break;
455 void X86ATTAsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
456 const char *Modifier
){
457 assert(isMem(MI
, Op
) && "Invalid memory reference!");
458 MachineOperand BaseReg
= MI
->getOperand(Op
);
459 MachineOperand IndexReg
= MI
->getOperand(Op
+2);
460 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
462 bool NotRIPRel
= IndexReg
.getReg() || BaseReg
.getReg();
463 if (DispSpec
.isGlobalAddress() ||
464 DispSpec
.isConstantPoolIndex() ||
465 DispSpec
.isJumpTableIndex()) {
466 printOperand(MI
, Op
+3, "mem", NotRIPRel
);
468 int DispVal
= DispSpec
.getImmedValue();
469 if (DispVal
|| (!IndexReg
.getReg() && !BaseReg
.getReg()))
473 if (IndexReg
.getReg() || BaseReg
.getReg()) {
474 unsigned ScaleVal
= MI
->getOperand(Op
+1).getImmedValue();
475 unsigned BaseRegOperand
= 0, IndexRegOperand
= 2;
477 // There are cases where we can end up with ESP/RSP in the indexreg slot.
478 // If this happens, swap the base/index register to support assemblers that
479 // don't work when the index is *SP.
480 if (IndexReg
.getReg() == X86::ESP
|| IndexReg
.getReg() == X86::RSP
) {
481 assert(ScaleVal
== 1 && "Scale not supported for stack pointer!");
482 std::swap(BaseReg
, IndexReg
);
483 std::swap(BaseRegOperand
, IndexRegOperand
);
487 if (BaseReg
.getReg())
488 printOperand(MI
, Op
+BaseRegOperand
, Modifier
);
490 if (IndexReg
.getReg()) {
492 printOperand(MI
, Op
+IndexRegOperand
, Modifier
);
494 O
<< "," << ScaleVal
;
500 void X86ATTAsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
) {
501 std::string label
= computePICLabel(getFunctionNumber(), TAI
, Subtarget
);
502 O
<< label
<< "\n" << label
<< ":";
506 bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand
&MO
,
508 const MRegisterInfo
&RI
= *TM
.getRegisterInfo();
509 unsigned Reg
= MO
.getReg();
511 default: return true; // Unknown mode.
512 case 'b': // Print QImode register
513 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
515 case 'h': // Print QImode high register
516 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
518 case 'w': // Print HImode register
519 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
521 case 'k': // Print SImode register
522 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
527 for (const char *Name
= RI
.get(Reg
).Name
; *Name
; ++Name
)
528 O
<< (char)tolower(*Name
);
532 /// PrintAsmOperand - Print out an operand for an inline asm expression.
534 bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
536 const char *ExtraCode
) {
537 // Does this asm operand have a single letter operand modifier?
538 if (ExtraCode
&& ExtraCode
[0]) {
539 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
541 switch (ExtraCode
[0]) {
542 default: return true; // Unknown modifier.
543 case 'c': // Don't print "$" before a global var name or constant.
544 printOperand(MI
, OpNo
, "mem");
546 case 'b': // Print QImode register
547 case 'h': // Print QImode high register
548 case 'w': // Print HImode register
549 case 'k': // Print SImode register
550 if (MI
->getOperand(OpNo
).isRegister())
551 return printAsmMRegister(MI
->getOperand(OpNo
), ExtraCode
[0]);
552 printOperand(MI
, OpNo
);
555 case 'P': // Don't print @PLT, but do print as memory.
556 printOperand(MI
, OpNo
, "mem");
561 printOperand(MI
, OpNo
);
565 bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
568 const char *ExtraCode
) {
569 if (ExtraCode
&& ExtraCode
[0])
570 return true; // Unknown modifier.
571 printMemReference(MI
, OpNo
);
575 /// printMachineInstruction -- Print out a single X86 LLVM instruction
576 /// MI in AT&T syntax to the current output stream.
578 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
581 // See if a truncate instruction can be turned into a nop.
582 switch (MI
->getOpcode()) {
584 case X86::PsMOVZX64rr32
:
585 O
<< TAI
->getCommentString() << " ZERO-EXTEND " << "\n\t";
589 // Call the autogenerated instruction printer routines.
590 printInstruction(MI
);
593 // Include the auto-generated portion of the assembly writer.
594 #include "X86GenAsmWriter.inc"