1 //===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel 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 Intel format assembly language.
12 // This printer is the output mechanism used by `llc'.
14 //===----------------------------------------------------------------------===//
16 #define DEBUG_TYPE "asm-printer"
17 #include "X86IntelAsmPrinter.h"
18 #include "X86InstrInfo.h"
19 #include "X86TargetAsmInfo.h"
21 #include "llvm/CallingConv.h"
22 #include "llvm/Constants.h"
23 #include "llvm/DerivedTypes.h"
24 #include "llvm/Module.h"
25 #include "llvm/ADT/Statistic.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/Assembly/Writer.h"
28 #include "llvm/CodeGen/DwarfWriter.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/Mangler.h"
31 #include "llvm/Target/TargetAsmInfo.h"
32 #include "llvm/Target/TargetOptions.h"
35 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
37 static X86MachineFunctionInfo
calculateFunctionInfo(const Function
*F
,
38 const TargetData
*TD
) {
39 X86MachineFunctionInfo Info
;
42 switch (F
->getCallingConv()) {
43 case CallingConv::X86_StdCall
:
44 Info
.setDecorationStyle(StdCall
);
46 case CallingConv::X86_FastCall
:
47 Info
.setDecorationStyle(FastCall
);
54 for (Function::const_arg_iterator AI
= F
->arg_begin(), AE
= F
->arg_end();
55 AI
!= AE
; ++AI
, ++argNum
) {
56 const Type
* Ty
= AI
->getType();
58 // 'Dereference' type in case of byval parameter attribute
59 if (F
->paramHasAttr(argNum
, Attribute::ByVal
))
60 Ty
= cast
<PointerType
>(Ty
)->getElementType();
62 // Size should be aligned to DWORD boundary
63 Size
+= ((TD
->getTypeAllocSize(Ty
) + 3)/4)*4;
66 // We're not supporting tooooo huge arguments :)
67 Info
.setBytesToPopOnReturn((unsigned int)Size
);
72 /// decorateName - Query FunctionInfoMap and use this information for various
74 void X86IntelAsmPrinter::decorateName(std::string
&Name
,
75 const GlobalValue
*GV
) {
76 const Function
*F
= dyn_cast
<Function
>(GV
);
79 // We don't want to decorate non-stdcall or non-fastcall functions right now
80 unsigned CC
= F
->getCallingConv();
81 if (CC
!= CallingConv::X86_StdCall
&& CC
!= CallingConv::X86_FastCall
)
84 FMFInfoMap::const_iterator info_item
= FunctionInfoMap
.find(F
);
86 const X86MachineFunctionInfo
*Info
;
87 if (info_item
== FunctionInfoMap
.end()) {
88 // Calculate apropriate function info and populate map
89 FunctionInfoMap
[F
] = calculateFunctionInfo(F
, TM
.getTargetData());
90 Info
= &FunctionInfoMap
[F
];
92 Info
= &info_item
->second
;
95 const FunctionType
*FT
= F
->getFunctionType();
96 switch (Info
->getDecorationStyle()) {
100 // "Pure" variadic functions do not receive @0 suffix.
101 if (!FT
->isVarArg() || (FT
->getNumParams() == 0) ||
102 (FT
->getNumParams() == 1 && F
->hasStructRetAttr()))
103 Name
+= '@' + utostr_32(Info
->getBytesToPopOnReturn());
106 // "Pure" variadic functions do not receive @0 suffix.
107 if (!FT
->isVarArg() || (FT
->getNumParams() == 0) ||
108 (FT
->getNumParams() == 1 && F
->hasStructRetAttr()))
109 Name
+= '@' + utostr_32(Info
->getBytesToPopOnReturn());
118 llvm_unreachable("Unsupported DecorationStyle");
122 /// runOnMachineFunction - This uses the printMachineInstruction()
123 /// method to print assembly for each instruction.
125 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
127 SetupMachineFunction(MF
);
130 // Print out constants referenced by the function
131 EmitConstantPool(MF
.getConstantPool());
133 // Print out labels for the function.
134 const Function
*F
= MF
.getFunction();
135 unsigned CC
= F
->getCallingConv();
136 unsigned FnAlign
= MF
.getAlignment();
138 // Populate function information map. Actually, We don't want to populate
139 // non-stdcall or non-fastcall functions' information right now.
140 if (CC
== CallingConv::X86_StdCall
|| CC
== CallingConv::X86_FastCall
)
141 FunctionInfoMap
[F
] = *MF
.getInfo
<X86MachineFunctionInfo
>();
143 decorateName(CurrentFnName
, F
);
145 SwitchToTextSection("_text", F
);
146 switch (F
->getLinkage()) {
147 default: llvm_unreachable("Unsupported linkage type!");
148 case Function::PrivateLinkage
:
149 case Function::InternalLinkage
:
150 EmitAlignment(FnAlign
);
152 case Function::DLLExportLinkage
:
153 DLLExportedFns
.insert(CurrentFnName
);
155 case Function::ExternalLinkage
:
156 O
<< "\tpublic " << CurrentFnName
<< "\n";
157 EmitAlignment(FnAlign
);
161 O
<< CurrentFnName
<< "\tproc near\n";
163 // Print out code for the function.
164 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
166 // Print a label for the basic block if there are any predecessors.
167 if (!I
->pred_empty()) {
168 printBasicBlockLabel(I
, true, true);
171 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
173 // Print the assembly for the instruction.
174 printMachineInstruction(II
);
178 // Print out jump tables referenced by the function.
179 EmitJumpTableInfo(MF
.getJumpTableInfo(), MF
);
181 O
<< CurrentFnName
<< "\tendp\n";
185 // We didn't modify anything.
189 void X86IntelAsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
) {
190 unsigned char value
= MI
->getOperand(Op
).getImm();
191 assert(value
<= 7 && "Invalid ssecc argument!");
193 case 0: O
<< "eq"; break;
194 case 1: O
<< "lt"; break;
195 case 2: O
<< "le"; break;
196 case 3: O
<< "unord"; break;
197 case 4: O
<< "neq"; break;
198 case 5: O
<< "nlt"; break;
199 case 6: O
<< "nle"; break;
200 case 7: O
<< "ord"; break;
204 void X86IntelAsmPrinter::printOp(const MachineOperand
&MO
,
205 const char *Modifier
) {
206 switch (MO
.getType()) {
207 case MachineOperand::MO_Register
: {
208 if (TargetRegisterInfo::isPhysicalRegister(MO
.getReg())) {
209 unsigned Reg
= MO
.getReg();
210 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
211 MVT VT
= (strcmp(Modifier
,"subreg64") == 0) ?
212 MVT::i64
: ((strcmp(Modifier
, "subreg32") == 0) ? MVT::i32
:
213 ((strcmp(Modifier
,"subreg16") == 0) ? MVT::i16
:MVT::i8
));
214 Reg
= getX86SubSuperRegister(Reg
, VT
);
216 O
<< TRI
->getName(Reg
);
218 O
<< "reg" << MO
.getReg();
221 case MachineOperand::MO_Immediate
:
224 case MachineOperand::MO_JumpTableIndex
: {
225 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
226 if (!isMemOp
) O
<< "OFFSET ";
227 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
228 << "_" << MO
.getIndex();
231 case MachineOperand::MO_ConstantPoolIndex
: {
232 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
233 if (!isMemOp
) O
<< "OFFSET ";
234 O
<< "[" << TAI
->getPrivateGlobalPrefix() << "CPI"
235 << getFunctionNumber() << "_" << MO
.getIndex();
236 printOffset(MO
.getOffset());
240 case MachineOperand::MO_GlobalAddress
: {
241 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
242 GlobalValue
*GV
= MO
.getGlobal();
243 std::string Name
= Mang
->getMangledName(GV
);
244 decorateName(Name
, GV
);
246 if (!isMemOp
) O
<< "OFFSET ";
248 // Handle dllimport linkage.
249 // FIXME: This should be fixed with full support of stdcall & fastcall
251 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
255 printOffset(MO
.getOffset());
258 case MachineOperand::MO_ExternalSymbol
: {
259 O
<< TAI
->getGlobalPrefix() << MO
.getSymbolName();
263 O
<< "<unknown operand type>"; return;
267 void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr
*MI
, unsigned OpNo
){
268 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
269 switch (MO
.getType()) {
270 default: llvm_unreachable("Unknown pcrel immediate operand");
271 case MachineOperand::MO_Immediate
:
274 case MachineOperand::MO_MachineBasicBlock
:
275 printBasicBlockLabel(MO
.getMBB());
278 case MachineOperand::MO_GlobalAddress
: {
279 GlobalValue
*GV
= MO
.getGlobal();
280 std::string Name
= Mang
->getMangledName(GV
);
281 decorateName(Name
, GV
);
283 // Handle dllimport linkage.
284 // FIXME: This should be fixed with full support of stdcall & fastcall
286 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
289 printOffset(MO
.getOffset());
293 case MachineOperand::MO_ExternalSymbol
:
294 O
<< TAI
->getGlobalPrefix() << MO
.getSymbolName();
300 void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr
*MI
,
302 const char *Modifier
) {
303 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
304 int ScaleVal
= MI
->getOperand(Op
+1).getImm();
305 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
306 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
309 bool NeedPlus
= false;
310 if (BaseReg
.getReg()) {
311 printOp(BaseReg
, Modifier
);
315 if (IndexReg
.getReg()) {
316 if (NeedPlus
) O
<< " + ";
318 O
<< ScaleVal
<< "*";
319 printOp(IndexReg
, Modifier
);
323 if (DispSpec
.isGlobal() || DispSpec
.isCPI() ||
327 printOp(DispSpec
, "mem");
329 int DispVal
= DispSpec
.getImm();
330 if (DispVal
|| (!BaseReg
.getReg() && !IndexReg
.getReg())) {
345 void X86IntelAsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
346 const char *Modifier
) {
347 assert(isMem(MI
, Op
) && "Invalid memory reference!");
348 MachineOperand Segment
= MI
->getOperand(Op
+4);
349 if (Segment
.getReg()) {
350 printOperand(MI
, Op
+4, Modifier
);
353 printLeaMemReference(MI
, Op
, Modifier
);
356 void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid
,
357 const MachineBasicBlock
*MBB
) const {
358 if (!TAI
->getSetDirective())
361 O
<< TAI
->getSetDirective() << ' ' << TAI
->getPrivateGlobalPrefix()
362 << getFunctionNumber() << '_' << uid
<< "_set_" << MBB
->getNumber() << ',';
363 printBasicBlockLabel(MBB
, false, false, false);
364 O
<< '-' << "\"L" << getFunctionNumber() << "$pb\"'\n";
367 void X86IntelAsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
) {
368 O
<< "L" << getFunctionNumber() << "$pb\n";
369 O
<< "L" << getFunctionNumber() << "$pb:";
372 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand
&MO
,
374 unsigned Reg
= MO
.getReg();
376 default: return true; // Unknown mode.
377 case 'b': // Print QImode register
378 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
380 case 'h': // Print QImode high register
381 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
383 case 'w': // Print HImode register
384 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
386 case 'k': // Print SImode register
387 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
391 O
<< TRI
->getName(Reg
);
395 /// PrintAsmOperand - Print out an operand for an inline asm expression.
397 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
399 const char *ExtraCode
) {
400 // Does this asm operand have a single letter operand modifier?
401 if (ExtraCode
&& ExtraCode
[0]) {
402 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
404 switch (ExtraCode
[0]) {
405 default: return true; // Unknown modifier.
406 case 'b': // Print QImode register
407 case 'h': // Print QImode high register
408 case 'w': // Print HImode register
409 case 'k': // Print SImode register
410 return printAsmMRegister(MI
->getOperand(OpNo
), ExtraCode
[0]);
414 printOperand(MI
, OpNo
);
418 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
421 const char *ExtraCode
) {
422 if (ExtraCode
&& ExtraCode
[0])
423 return true; // Unknown modifier.
424 printMemReference(MI
, OpNo
);
428 /// printMachineInstruction -- Print out a single X86 LLVM instruction
429 /// MI in Intel syntax to the current output stream.
431 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
434 // Call the autogenerated instruction printer routines.
435 printInstruction(MI
);
438 bool X86IntelAsmPrinter::doInitialization(Module
&M
) {
439 bool Result
= AsmPrinter::doInitialization(M
);
441 Mang
->markCharUnacceptable('.');
443 O
<< "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n";
445 // Emit declarations for external functions.
446 for (Module::iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
447 if (I
->isDeclaration()) {
448 std::string Name
= Mang
->getMangledName(I
);
449 decorateName(Name
, I
);
452 if (I
->hasDLLImportLinkage()) {
455 O
<< Name
<< ":near\n";
458 // Emit declarations for external globals. Note that VC++ always declares
459 // external globals to have type byte, and if that's good enough for VC++...
460 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
462 if (I
->isDeclaration()) {
463 std::string Name
= Mang
->getMangledName(I
);
466 if (I
->hasDLLImportLinkage()) {
469 O
<< Name
<< ":byte\n";
476 bool X86IntelAsmPrinter::doFinalization(Module
&M
) {
477 const TargetData
*TD
= TM
.getTargetData();
479 // Print out module-level global variables here.
480 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
482 if (I
->isDeclaration()) continue; // External global require no code
484 // Check to see if this is a special global used by LLVM, if so, emit it.
485 if (EmitSpecialLLVMGlobal(I
))
488 std::string name
= Mang
->getMangledName(I
);
489 Constant
*C
= I
->getInitializer();
490 unsigned Align
= TD
->getPreferredAlignmentLog(I
);
491 bool bCustomSegment
= false;
493 switch (I
->getLinkage()) {
494 case GlobalValue::CommonLinkage
:
495 case GlobalValue::LinkOnceAnyLinkage
:
496 case GlobalValue::LinkOnceODRLinkage
:
497 case GlobalValue::WeakAnyLinkage
:
498 case GlobalValue::WeakODRLinkage
:
499 SwitchToDataSection("");
500 O
<< name
<< "?\tSEGEMNT PARA common 'COMMON'\n";
501 bCustomSegment
= true;
502 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
503 // are also available.
505 case GlobalValue::AppendingLinkage
:
506 SwitchToDataSection("");
507 O
<< name
<< "?\tSEGMENT PARA public 'DATA'\n";
508 bCustomSegment
= true;
509 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
510 // are also available.
512 case GlobalValue::DLLExportLinkage
:
513 DLLExportedGVs
.insert(name
);
515 case GlobalValue::ExternalLinkage
:
516 O
<< "\tpublic " << name
<< "\n";
518 case GlobalValue::InternalLinkage
:
519 SwitchToSection(TAI
->getDataSection());
522 llvm_unreachable("Unknown linkage type!");
526 EmitAlignment(Align
, I
);
530 O
<< "\t\t\t\t" << TAI
->getCommentString()
531 << " " << I
->getName();
534 EmitGlobalConstant(C
);
537 O
<< name
<< "?\tends\n";
540 // Output linker support code for dllexported globals
541 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty()) {
542 SwitchToDataSection("");
543 O
<< "; WARNING: The following code is valid only with MASM v8.x"
544 << "and (possible) higher\n"
545 << "; This version of MASM is usually shipped with Microsoft "
546 << "Visual Studio 2005\n"
547 << "; or (possible) further versions. Unfortunately, there is no "
548 << "way to support\n"
549 << "; dllexported symbols in the earlier versions of MASM in fully "
550 << "automatic way\n\n";
551 O
<< "_drectve\t segment info alias('.drectve')\n";
554 for (StringSet
<>::iterator i
= DLLExportedGVs
.begin(),
555 e
= DLLExportedGVs
.end();
557 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << ",data'\n";
559 for (StringSet
<>::iterator i
= DLLExportedFns
.begin(),
560 e
= DLLExportedFns
.end();
562 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << "'\n";
564 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty())
565 O
<< "_drectve\t ends\n";
567 // Bypass X86SharedAsmPrinter::doFinalization().
568 bool Result
= AsmPrinter::doFinalization(M
);
569 SwitchToDataSection("");
574 void X86IntelAsmPrinter::EmitString(const ConstantArray
*CVA
) const {
575 unsigned NumElts
= CVA
->getNumOperands();
577 // ML does not have escape sequences except '' for '. It also has a maximum
578 // string length of 255.
580 bool inString
= false;
581 for (unsigned i
= 0; i
< NumElts
; i
++) {
582 int n
= cast
<ConstantInt
>(CVA
->getOperand(i
))->getZExtValue() & 255;
586 if (n
>= 32 && n
<= 127) {
613 len
+= 1 + (n
> 9) + (n
> 99);
634 // Include the auto-generated portion of the assembly writer.
635 #include "X86GenAsmWriter1.inc"