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/Analysis/DebugInfo.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
->getTypePaddedSize(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 assert(0 && "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();
137 // Populate function information map. Actually, We don't want to populate
138 // non-stdcall or non-fastcall functions' information right now.
139 if (CC
== CallingConv::X86_StdCall
|| CC
== CallingConv::X86_FastCall
)
140 FunctionInfoMap
[F
] = *MF
.getInfo
<X86MachineFunctionInfo
>();
142 decorateName(CurrentFnName
, F
);
144 SwitchToTextSection("_text", F
);
146 unsigned FnAlign
= 4;
147 if (F
->hasFnAttr(Attribute::OptimizeForSize
))
149 switch (F
->getLinkage()) {
150 default: assert(0 && "Unsupported linkage type!");
151 case Function::PrivateLinkage
:
152 case Function::InternalLinkage
:
153 EmitAlignment(FnAlign
);
155 case Function::DLLExportLinkage
:
156 DLLExportedFns
.insert(CurrentFnName
);
158 case Function::ExternalLinkage
:
159 O
<< "\tpublic " << CurrentFnName
<< "\n";
160 EmitAlignment(FnAlign
);
164 O
<< CurrentFnName
<< "\tproc near\n";
166 // Print out code for the function.
167 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
169 // Print a label for the basic block if there are any predecessors.
170 if (!I
->pred_empty()) {
171 printBasicBlockLabel(I
, true, true);
174 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
176 // Print the assembly for the instruction.
177 printMachineInstruction(II
);
181 // Print out jump tables referenced by the function.
182 EmitJumpTableInfo(MF
.getJumpTableInfo(), MF
);
184 O
<< CurrentFnName
<< "\tendp\n";
188 // We didn't modify anything.
192 void X86IntelAsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
) {
193 unsigned char value
= MI
->getOperand(Op
).getImm();
194 assert(value
<= 7 && "Invalid ssecc argument!");
196 case 0: O
<< "eq"; break;
197 case 1: O
<< "lt"; break;
198 case 2: O
<< "le"; break;
199 case 3: O
<< "unord"; break;
200 case 4: O
<< "neq"; break;
201 case 5: O
<< "nlt"; break;
202 case 6: O
<< "nle"; break;
203 case 7: O
<< "ord"; break;
207 void X86IntelAsmPrinter::printOp(const MachineOperand
&MO
,
208 const char *Modifier
) {
209 switch (MO
.getType()) {
210 case MachineOperand::MO_Register
: {
211 if (TargetRegisterInfo::isPhysicalRegister(MO
.getReg())) {
212 unsigned Reg
= MO
.getReg();
213 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
214 MVT VT
= (strcmp(Modifier
,"subreg64") == 0) ?
215 MVT::i64
: ((strcmp(Modifier
, "subreg32") == 0) ? MVT::i32
:
216 ((strcmp(Modifier
,"subreg16") == 0) ? MVT::i16
:MVT::i8
));
217 Reg
= getX86SubSuperRegister(Reg
, VT
);
219 O
<< TRI
->getName(Reg
);
221 O
<< "reg" << MO
.getReg();
224 case MachineOperand::MO_Immediate
:
227 case MachineOperand::MO_MachineBasicBlock
:
228 printBasicBlockLabel(MO
.getMBB());
230 case MachineOperand::MO_JumpTableIndex
: {
231 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
232 if (!isMemOp
) O
<< "OFFSET ";
233 O
<< TAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
234 << "_" << MO
.getIndex();
237 case MachineOperand::MO_ConstantPoolIndex
: {
238 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
239 if (!isMemOp
) O
<< "OFFSET ";
240 O
<< "[" << TAI
->getPrivateGlobalPrefix() << "CPI"
241 << getFunctionNumber() << "_" << MO
.getIndex();
242 printOffset(MO
.getOffset());
246 case MachineOperand::MO_GlobalAddress
: {
247 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
248 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
249 GlobalValue
*GV
= MO
.getGlobal();
250 std::string Name
= Mang
->getValueName(GV
);
252 decorateName(Name
, GV
);
254 if (!isMemOp
&& !isCallOp
) O
<< "OFFSET ";
255 if (GV
->hasDLLImportLinkage()) {
256 // FIXME: This should be fixed with full support of stdcall & fastcall
261 printOffset(MO
.getOffset());
264 case MachineOperand::MO_ExternalSymbol
: {
265 bool isCallOp
= Modifier
&& !strcmp(Modifier
, "call");
266 if (!isCallOp
) O
<< "OFFSET ";
267 O
<< TAI
->getGlobalPrefix() << MO
.getSymbolName();
271 O
<< "<unknown operand type>"; return;
275 void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr
*MI
,
277 const char *Modifier
) {
278 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
279 int ScaleVal
= MI
->getOperand(Op
+1).getImm();
280 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
281 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
284 bool NeedPlus
= false;
285 if (BaseReg
.getReg()) {
286 printOp(BaseReg
, Modifier
);
290 if (IndexReg
.getReg()) {
291 if (NeedPlus
) O
<< " + ";
293 O
<< ScaleVal
<< "*";
294 printOp(IndexReg
, Modifier
);
298 if (DispSpec
.isGlobal() || DispSpec
.isCPI() ||
302 printOp(DispSpec
, "mem");
304 int DispVal
= DispSpec
.getImm();
305 if (DispVal
|| (!BaseReg
.getReg() && !IndexReg
.getReg())) {
320 void X86IntelAsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
321 const char *Modifier
) {
322 assert(isMem(MI
, Op
) && "Invalid memory reference!");
323 MachineOperand Segment
= MI
->getOperand(Op
+4);
324 if (Segment
.getReg()) {
325 printOperand(MI
, Op
+4, Modifier
);
328 printLeaMemReference(MI
, Op
, Modifier
);
331 void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid
,
332 const MachineBasicBlock
*MBB
) const {
333 if (!TAI
->getSetDirective())
336 O
<< TAI
->getSetDirective() << ' ' << TAI
->getPrivateGlobalPrefix()
337 << getFunctionNumber() << '_' << uid
<< "_set_" << MBB
->getNumber() << ',';
338 printBasicBlockLabel(MBB
, false, false, false);
339 O
<< '-' << "\"L" << getFunctionNumber() << "$pb\"'\n";
342 void X86IntelAsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
) {
343 O
<< "\"L" << getFunctionNumber() << "$pb\"\n";
344 O
<< "\"L" << getFunctionNumber() << "$pb\":";
347 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand
&MO
,
349 unsigned Reg
= MO
.getReg();
351 default: return true; // Unknown mode.
352 case 'b': // Print QImode register
353 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
355 case 'h': // Print QImode high register
356 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
358 case 'w': // Print HImode register
359 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
361 case 'k': // Print SImode register
362 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
366 O
<< '%' << TRI
->getName(Reg
);
370 /// PrintAsmOperand - Print out an operand for an inline asm expression.
372 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
374 const char *ExtraCode
) {
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 switch (ExtraCode
[0]) {
380 default: return true; // Unknown modifier.
381 case 'b': // Print QImode register
382 case 'h': // Print QImode high register
383 case 'w': // Print HImode register
384 case 'k': // Print SImode register
385 return printAsmMRegister(MI
->getOperand(OpNo
), ExtraCode
[0]);
389 printOperand(MI
, OpNo
);
393 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
396 const char *ExtraCode
) {
397 if (ExtraCode
&& ExtraCode
[0])
398 return true; // Unknown modifier.
399 printMemReference(MI
, OpNo
);
403 /// printMachineInstruction -- Print out a single X86 LLVM instruction
404 /// MI in Intel syntax to the current output stream.
406 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
409 // Call the autogenerated instruction printer routines.
410 printInstruction(MI
);
413 bool X86IntelAsmPrinter::doInitialization(Module
&M
) {
414 bool Result
= AsmPrinter::doInitialization(M
);
416 Mang
->markCharUnacceptable('.');
418 O
<< "\t.686\n\t.model flat\n\n";
420 // Emit declarations for external functions.
421 for (Module::iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
422 if (I
->isDeclaration()) {
423 std::string Name
= Mang
->getValueName(I
);
424 decorateName(Name
, I
);
427 if (I
->hasDLLImportLinkage()) {
430 O
<< Name
<< ":near\n";
433 // Emit declarations for external globals. Note that VC++ always declares
434 // external globals to have type byte, and if that's good enough for VC++...
435 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
437 if (I
->isDeclaration()) {
438 std::string Name
= Mang
->getValueName(I
);
441 if (I
->hasDLLImportLinkage()) {
444 O
<< Name
<< ":byte\n";
451 bool X86IntelAsmPrinter::doFinalization(Module
&M
) {
452 const TargetData
*TD
= TM
.getTargetData();
454 // Print out module-level global variables here.
455 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
457 if (I
->isDeclaration()) continue; // External global require no code
459 // Check to see if this is a special global used by LLVM, if so, emit it.
460 if (EmitSpecialLLVMGlobal(I
))
463 std::string name
= Mang
->getValueName(I
);
464 Constant
*C
= I
->getInitializer();
465 unsigned Align
= TD
->getPreferredAlignmentLog(I
);
466 bool bCustomSegment
= false;
468 switch (I
->getLinkage()) {
469 case GlobalValue::CommonLinkage
:
470 case GlobalValue::LinkOnceAnyLinkage
:
471 case GlobalValue::LinkOnceODRLinkage
:
472 case GlobalValue::WeakAnyLinkage
:
473 case GlobalValue::WeakODRLinkage
:
474 SwitchToDataSection("");
475 O
<< name
<< "?\tsegment common 'COMMON'\n";
476 bCustomSegment
= true;
477 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
478 // are also available.
480 case GlobalValue::AppendingLinkage
:
481 SwitchToDataSection("");
482 O
<< name
<< "?\tsegment public 'DATA'\n";
483 bCustomSegment
= true;
484 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
485 // are also available.
487 case GlobalValue::DLLExportLinkage
:
488 DLLExportedGVs
.insert(name
);
490 case GlobalValue::ExternalLinkage
:
491 O
<< "\tpublic " << name
<< "\n";
493 case GlobalValue::InternalLinkage
:
494 SwitchToSection(TAI
->getDataSection());
497 assert(0 && "Unknown linkage type!");
501 EmitAlignment(Align
, I
);
505 O
<< "\t\t\t\t" << TAI
->getCommentString()
506 << " " << I
->getName();
509 EmitGlobalConstant(C
);
512 O
<< name
<< "?\tends\n";
515 // Output linker support code for dllexported globals
516 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty()) {
517 SwitchToDataSection("");
518 O
<< "; WARNING: The following code is valid only with MASM v8.x"
519 << "and (possible) higher\n"
520 << "; This version of MASM is usually shipped with Microsoft "
521 << "Visual Studio 2005\n"
522 << "; or (possible) further versions. Unfortunately, there is no "
523 << "way to support\n"
524 << "; dllexported symbols in the earlier versions of MASM in fully "
525 << "automatic way\n\n";
526 O
<< "_drectve\t segment info alias('.drectve')\n";
529 for (StringSet
<>::iterator i
= DLLExportedGVs
.begin(),
530 e
= DLLExportedGVs
.end();
532 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << ",data'\n";
534 for (StringSet
<>::iterator i
= DLLExportedFns
.begin(),
535 e
= DLLExportedFns
.end();
537 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << "'\n";
539 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty())
540 O
<< "_drectve\t ends\n";
542 // Bypass X86SharedAsmPrinter::doFinalization().
543 bool Result
= AsmPrinter::doFinalization(M
);
544 SwitchToDataSection("");
549 void X86IntelAsmPrinter::EmitString(const ConstantArray
*CVA
) const {
550 unsigned NumElts
= CVA
->getNumOperands();
552 // ML does not have escape sequences except '' for '. It also has a maximum
553 // string length of 255.
555 bool inString
= false;
556 for (unsigned i
= 0; i
< NumElts
; i
++) {
557 int n
= cast
<ConstantInt
>(CVA
->getOperand(i
))->getZExtValue() & 255;
561 if (n
>= 32 && n
<= 127) {
588 len
+= 1 + (n
> 9) + (n
> 99);
609 // Include the auto-generated portion of the assembly writer.
610 #include "X86GenAsmWriter1.inc"