1 //===-- X86ATTAsmPrinter.cpp - Convert X86 LLVM code to Intel 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"
19 #include "X86MachineFunctionInfo.h"
20 #include "X86TargetMachine.h"
21 #include "X86TargetAsmInfo.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/Module.h"
24 #include "llvm/Support/Mangler.h"
25 #include "llvm/Target/TargetAsmInfo.h"
26 #include "llvm/Target/TargetOptions.h"
27 #include "llvm/ADT/Statistic.h"
30 STATISTIC(EmittedInsts, "Number of machine instrs printed");
32 /// getSectionForFunction - Return the section that we should emit the
33 /// specified function body into.
34 std::string X86ATTAsmPrinter::getSectionForFunction(const Function &F) const {
35 switch (F.getLinkage()) {
36 default: assert(0 && "Unknown linkage type!");
37 case Function::InternalLinkage:
38 case Function::DLLExportLinkage:
39 case Function::ExternalLinkage:
40 return TAI->getTextSection();
41 case Function::WeakLinkage:
42 case Function::LinkOnceLinkage:
43 if (Subtarget->isTargetDarwin()) {
44 return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
45 } else if (Subtarget->isTargetCygMing()) {
46 return "\t.section\t.text$linkonce." + CurrentFnName + ",\"ax\"\n";
48 return "\t.section\t.llvm.linkonce.t." + CurrentFnName +
49 ",\"ax\",@progbits\n";
54 /// runOnMachineFunction - This uses the printMachineInstruction()
55 /// method to print assembly for each instruction.
57 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
58 if (Subtarget->isTargetDarwin() ||
59 Subtarget->isTargetELF() ||
60 Subtarget->isTargetCygMing()) {
61 // Let PassManager know we need debug information and relay
62 // the MachineDebugInfo address on to DwarfWriter.
63 DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
66 SetupMachineFunction(MF);
69 // Print out constants referenced by the function
70 EmitConstantPool(MF.getConstantPool());
72 // Print out labels for the function.
73 const Function *F = MF.getFunction();
74 unsigned CC = F->getCallingConv();
76 // Populate function information map. Actually, We don't want to populate
77 // non-stdcall or non-fastcall functions' information right now.
78 if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall)
79 FunctionInfoMap[F] = *MF.getInfo<X86FunctionInfo>();
81 X86SharedAsmPrinter::decorateName(CurrentFnName, F);
83 // Change GNU linkonce to LLVM linkonce name
84 if (F->hasSection() &&
85 (F->getSection().find(".gnu.linkonce.t") != std::string::npos))
86 SwitchToTextSection(getSectionForFunction(*F).c_str(), NULL);
88 SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
90 switch (F->getLinkage()) {
91 default: assert(0 && "Unknown linkage type!");
92 case Function::InternalLinkage: // Symbols default to internal.
93 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
95 case Function::DLLExportLinkage:
96 DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
98 case Function::ExternalLinkage:
99 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
100 O << "\t.globl\t" << CurrentFnName << "\n";
102 case Function::LinkOnceLinkage:
103 case Function::WeakLinkage:
104 if (Subtarget->isTargetDarwin()) {
105 O << "\t.globl\t" << CurrentFnName << "\n";
106 O << "\t.weak_definition\t" << CurrentFnName << "\n";
107 } else if (Subtarget->isTargetCygMing()) {
108 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
109 O << "\t.linkonce discard\n";
110 O << "\t.globl " << CurrentFnName << "\n";
112 EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
113 O << "\t.weak " << CurrentFnName << "\n";
117 O << CurrentFnName << ":\n";
118 // Add some workaround for linkonce linkage on Cygwin\MinGW
119 if (Subtarget->isTargetCygMing() &&
120 (F->getLinkage() == Function::LinkOnceLinkage ||
121 F->getLinkage() == Function::WeakLinkage))
122 O << "_llvm$workaround$fake$stub_" << CurrentFnName << ":\n";
124 if (Subtarget->isTargetDarwin() ||
125 Subtarget->isTargetELF() ||
126 Subtarget->isTargetCygMing()) {
127 // Emit pre-function debug information.
128 DW.BeginFunction(&MF);
131 // Print out code for the function.
132 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
134 // Print a label for the basic block.
135 if (I->pred_begin() != I->pred_end()) {
136 printBasicBlockLabel(I, true);
139 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
141 // Print the assembly for the instruction.
143 printMachineInstruction(II);
147 // Print out jump tables referenced by the function.
149 // Mac OS X requires that the jump table follow the function, so that the jump
150 // table is part of the same atom that the function is in.
151 EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
153 if (TAI->hasDotTypeDotSizeDirective())
154 O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
156 if (Subtarget->isTargetDarwin() ||
157 Subtarget->isTargetELF() ||
158 Subtarget->isTargetCygMing()) {
159 // Emit post-function debug information.
163 // We didn't modify anything.
167 void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
168 const char *Modifier, bool NotRIPRel) {
169 const MachineOperand &MO = MI->getOperand(OpNo);
170 const MRegisterInfo &RI = *TM.getRegisterInfo();
171 switch (MO.getType()) {
172 case MachineOperand::MO_Register: {
173 assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
174 "Virtual registers should not make it this far!");
176 unsigned Reg = MO.getReg();
177 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
178 MVT::ValueType VT = (strcmp(Modifier+6,"64") == 0) ?
179 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
180 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
181 Reg = getX86SubSuperRegister(Reg, VT);
183 for (const char *Name = RI.get(Reg).Name; *Name; ++Name)
184 O << (char)tolower(*Name);
188 case MachineOperand::MO_Immediate:
189 if (!Modifier || strcmp(Modifier, "debug") != 0)
191 O << MO.getImmedValue();
193 case MachineOperand::MO_MachineBasicBlock:
194 printBasicBlockLabel(MO.getMachineBasicBlock());
196 case MachineOperand::MO_JumpTableIndex: {
197 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
198 if (!isMemOp) O << '$';
199 O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << "_"
200 << MO.getJumpTableIndex();
201 if (X86PICStyle == PICStyle::Stub &&
202 TM.getRelocationModel() == Reloc::PIC_)
203 O << "-\"L" << getFunctionNumber() << "$pb\"";
204 if (isMemOp && Subtarget->is64Bit() && !NotRIPRel)
208 case MachineOperand::MO_ConstantPoolIndex: {
209 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
210 if (!isMemOp) O << '$';
211 O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
212 << MO.getConstantPoolIndex();
213 if (X86PICStyle == PICStyle::Stub &&
214 TM.getRelocationModel() == Reloc::PIC_)
215 O << "-\"L" << getFunctionNumber() << "$pb\"";
216 int Offset = MO.getOffset();
222 if (isMemOp && Subtarget->is64Bit() && !NotRIPRel)
226 case MachineOperand::MO_GlobalAddress: {
227 bool isCallOp = Modifier && !strcmp(Modifier, "call");
228 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
229 if (!isMemOp && !isCallOp) O << '$';
231 GlobalValue *GV = MO.getGlobal();
232 std::string Name = Mang->getValueName(GV);
234 bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
235 GV->hasLinkOnceLinkage());
237 X86SharedAsmPrinter::decorateName(Name, GV);
239 if (X86PICStyle == PICStyle::Stub &&
240 TM.getRelocationModel() != Reloc::Static) {
241 // Link-once, External, or Weakly-linked global variables need
242 // non-lazily-resolved stubs
244 // Dynamically-resolved functions need a stub for the function.
245 if (isCallOp && isa<Function>(GV)) {
246 FnStubs.insert(Name);
247 O << "L" << Name << "$stub";
249 GVStubs.insert(Name);
250 O << "L" << Name << "$non_lazy_ptr";
253 if (GV->hasDLLImportLinkage()) {
259 if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_)
260 O << "-\"L" << getFunctionNumber() << "$pb\"";
262 if (GV->hasDLLImportLinkage()) {
268 if (GV->hasExternalWeakLinkage())
269 ExtWeakSymbols.insert(GV);
271 int Offset = MO.getOffset();
277 if (isMemOp && Subtarget->is64Bit()) {
278 if (isExt && TM.getRelocationModel() != Reloc::Static)
279 O << "@GOTPCREL(%rip)";
281 // Use rip when possible to reduce code size, except when index or
282 // base register are also part of the address. e.g.
283 // foo(%rip)(%rcx,%rax,4) is not legal
289 case MachineOperand::MO_ExternalSymbol: {
290 bool isCallOp = Modifier && !strcmp(Modifier, "call");
292 X86PICStyle == PICStyle::Stub &&
293 TM.getRelocationModel() != Reloc::Static) {
294 std::string Name(TAI->getGlobalPrefix());
295 Name += MO.getSymbolName();
296 FnStubs.insert(Name);
297 O << "L" << Name << "$stub";
300 if (!isCallOp) O << '$';
301 O << TAI->getGlobalPrefix() << MO.getSymbolName();
303 if (!isCallOp && Subtarget->is64Bit())
309 O << "<unknown operand type>"; return;
313 void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
314 unsigned char value = MI->getOperand(Op).getImmedValue();
315 assert(value <= 7 && "Invalid ssecc argument!");
317 case 0: O << "eq"; break;
318 case 1: O << "lt"; break;
319 case 2: O << "le"; break;
320 case 3: O << "unord"; break;
321 case 4: O << "neq"; break;
322 case 5: O << "nlt"; break;
323 case 6: O << "nle"; break;
324 case 7: O << "ord"; break;
328 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
329 const char *Modifier){
330 assert(isMem(MI, Op) && "Invalid memory reference!");
332 const MachineOperand &BaseReg = MI->getOperand(Op);
333 int ScaleVal = MI->getOperand(Op+1).getImmedValue();
334 const MachineOperand &IndexReg = MI->getOperand(Op+2);
335 const MachineOperand &DispSpec = MI->getOperand(Op+3);
337 if (BaseReg.isFrameIndex()) {
338 O << "[frame slot #" << BaseReg.getFrameIndex();
339 if (DispSpec.getImmedValue())
340 O << " + " << DispSpec.getImmedValue();
345 bool NotRIPRel = IndexReg.getReg() || BaseReg.getReg();
346 if (DispSpec.isGlobalAddress() ||
347 DispSpec.isConstantPoolIndex() ||
348 DispSpec.isJumpTableIndex()) {
349 printOperand(MI, Op+3, "mem", NotRIPRel);
351 int DispVal = DispSpec.getImmedValue();
352 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
356 if (IndexReg.getReg() || BaseReg.getReg()) {
358 if (BaseReg.getReg()) {
359 printOperand(MI, Op, Modifier);
362 if (IndexReg.getReg()) {
364 printOperand(MI, Op+2, Modifier);
366 O << "," << ScaleVal;
373 void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
374 O << "\"L" << getFunctionNumber() << "$pb\"\n";
375 O << "\"L" << getFunctionNumber() << "$pb\":";
379 bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO,
381 const MRegisterInfo &RI = *TM.getRegisterInfo();
382 unsigned Reg = MO.getReg();
384 default: return true; // Unknown mode.
385 case 'b': // Print QImode register
386 Reg = getX86SubSuperRegister(Reg, MVT::i8);
388 case 'h': // Print QImode high register
389 Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
391 case 'w': // Print HImode register
392 Reg = getX86SubSuperRegister(Reg, MVT::i16);
394 case 'k': // Print SImode register
395 Reg = getX86SubSuperRegister(Reg, MVT::i32);
400 for (const char *Name = RI.get(Reg).Name; *Name; ++Name)
401 O << (char)tolower(*Name);
405 /// PrintAsmOperand - Print out an operand for an inline asm expression.
407 bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
409 const char *ExtraCode) {
410 // Does this asm operand have a single letter operand modifier?
411 if (ExtraCode && ExtraCode[0]) {
412 if (ExtraCode[1] != 0) return true; // Unknown modifier.
414 switch (ExtraCode[0]) {
415 default: return true; // Unknown modifier.
416 case 'c': // Don't print "$" before a global var name.
417 printOperand(MI, OpNo, "mem");
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 return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
427 printOperand(MI, OpNo);
431 bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
434 const char *ExtraCode) {
435 if (ExtraCode && ExtraCode[0])
436 return true; // Unknown modifier.
437 printMemReference(MI, OpNo);
441 /// printMachineInstruction -- Print out a single X86 LLVM instruction
442 /// MI in Intel syntax to the current output stream.
444 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
447 // See if a truncate instruction can be turned into a nop.
448 switch (MI->getOpcode()) {
450 case X86::TRUNC_64to32:
451 case X86::TRUNC_64to16:
452 case X86::TRUNC_32to16:
453 case X86::TRUNC_32to8:
454 case X86::TRUNC_16to8:
455 case X86::TRUNC_32_to8:
456 case X86::TRUNC_16_to8: {
457 const MachineOperand &MO0 = MI->getOperand(0);
458 const MachineOperand &MO1 = MI->getOperand(1);
459 unsigned Reg0 = MO0.getReg();
460 unsigned Reg1 = MO1.getReg();
461 unsigned Opc = MI->getOpcode();
462 if (Opc == X86::TRUNC_64to32)
463 Reg1 = getX86SubSuperRegister(Reg1, MVT::i32);
464 else if (Opc == X86::TRUNC_32to16 || Opc == X86::TRUNC_64to16)
465 Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
467 Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
468 O << TAI->getCommentString() << " TRUNCATE ";
473 case X86::PsMOVZX64rr32:
474 O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
478 // Call the autogenerated instruction printer routines.
479 printInstruction(MI);
482 // Include the auto-generated portion of the assembly writer.
483 #include "X86GenAsmWriter.inc"