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 "X86MCAsmInfo.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/MC/MCAsmInfo.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCSymbol.h"
32 #include "llvm/Target/TargetLoweringObjectFile.h"
33 #include "llvm/Target/TargetOptions.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/Mangler.h"
38 STATISTIC(EmittedInsts
, "Number of machine instrs printed");
40 static X86MachineFunctionInfo
calculateFunctionInfo(const Function
*F
,
41 const TargetData
*TD
) {
42 X86MachineFunctionInfo Info
;
45 switch (F
->getCallingConv()) {
46 case CallingConv::X86_StdCall
:
47 Info
.setDecorationStyle(StdCall
);
49 case CallingConv::X86_FastCall
:
50 Info
.setDecorationStyle(FastCall
);
57 for (Function::const_arg_iterator AI
= F
->arg_begin(), AE
= F
->arg_end();
58 AI
!= AE
; ++AI
, ++argNum
) {
59 const Type
* Ty
= AI
->getType();
61 // 'Dereference' type in case of byval parameter attribute
62 if (F
->paramHasAttr(argNum
, Attribute::ByVal
))
63 Ty
= cast
<PointerType
>(Ty
)->getElementType();
65 // Size should be aligned to DWORD boundary
66 Size
+= ((TD
->getTypeAllocSize(Ty
) + 3)/4)*4;
69 // We're not supporting tooooo huge arguments :)
70 Info
.setBytesToPopOnReturn((unsigned int)Size
);
75 /// decorateName - Query FunctionInfoMap and use this information for various
77 void X86IntelAsmPrinter::decorateName(std::string
&Name
,
78 const GlobalValue
*GV
) {
79 const Function
*F
= dyn_cast
<Function
>(GV
);
82 // We don't want to decorate non-stdcall or non-fastcall functions right now
83 CallingConv::ID CC
= F
->getCallingConv();
84 if (CC
!= CallingConv::X86_StdCall
&& CC
!= CallingConv::X86_FastCall
)
87 FMFInfoMap::const_iterator info_item
= FunctionInfoMap
.find(F
);
89 const X86MachineFunctionInfo
*Info
;
90 if (info_item
== FunctionInfoMap
.end()) {
91 // Calculate apropriate function info and populate map
92 FunctionInfoMap
[F
] = calculateFunctionInfo(F
, TM
.getTargetData());
93 Info
= &FunctionInfoMap
[F
];
95 Info
= &info_item
->second
;
98 const FunctionType
*FT
= F
->getFunctionType();
99 switch (Info
->getDecorationStyle()) {
103 // "Pure" variadic functions do not receive @0 suffix.
104 if (!FT
->isVarArg() || (FT
->getNumParams() == 0) ||
105 (FT
->getNumParams() == 1 && F
->hasStructRetAttr()))
106 Name
+= '@' + utostr_32(Info
->getBytesToPopOnReturn());
109 // "Pure" variadic functions do not receive @0 suffix.
110 if (!FT
->isVarArg() || (FT
->getNumParams() == 0) ||
111 (FT
->getNumParams() == 1 && F
->hasStructRetAttr()))
112 Name
+= '@' + utostr_32(Info
->getBytesToPopOnReturn());
121 llvm_unreachable("Unsupported DecorationStyle");
125 /// runOnMachineFunction - This uses the printMachineInstruction()
126 /// method to print assembly for each instruction.
128 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction
&MF
) {
130 SetupMachineFunction(MF
);
133 // Print out constants referenced by the function
134 EmitConstantPool(MF
.getConstantPool());
136 // Print out labels for the function.
137 const Function
*F
= MF
.getFunction();
138 CallingConv::ID CC
= F
->getCallingConv();
139 unsigned FnAlign
= MF
.getAlignment();
141 // Populate function information map. Actually, We don't want to populate
142 // non-stdcall or non-fastcall functions' information right now.
143 if (CC
== CallingConv::X86_StdCall
|| CC
== CallingConv::X86_FastCall
)
144 FunctionInfoMap
[F
] = *MF
.getInfo
<X86MachineFunctionInfo
>();
146 decorateName(CurrentFnName
, F
);
148 OutStreamer
.SwitchSection(getObjFileLowering().SectionForGlobal(F
, Mang
, TM
));
150 switch (F
->getLinkage()) {
151 default: llvm_unreachable("Unsupported linkage type!");
152 case Function::LinkOnceAnyLinkage
:
153 case Function::LinkOnceODRLinkage
:
154 case Function::WeakAnyLinkage
:
155 case Function::WeakODRLinkage
:
157 case Function::PrivateLinkage
:
158 case Function::LinkerPrivateLinkage
:
159 case Function::InternalLinkage
:
160 EmitAlignment(FnAlign
);
162 case Function::DLLExportLinkage
:
163 DLLExportedFns
.insert(CurrentFnName
);
165 case Function::ExternalLinkage
:
166 O
<< "\tpublic " << CurrentFnName
<< "\n";
167 EmitAlignment(FnAlign
);
171 O
<< CurrentFnName
<< "\tproc near\n";
173 // Print out code for the function.
174 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
176 // Print a label for the basic block if there are any predecessors.
177 if (!I
->pred_empty()) {
178 EmitBasicBlockStart(I
);
181 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
183 // Print the assembly for the instruction.
184 printMachineInstruction(II
);
188 // Print out jump tables referenced by the function.
189 EmitJumpTableInfo(MF
.getJumpTableInfo(), MF
);
191 O
<< CurrentFnName
<< "\tendp\n";
193 // We didn't modify anything.
197 void X86IntelAsmPrinter::printSSECC(const MachineInstr
*MI
, unsigned Op
) {
198 unsigned char value
= MI
->getOperand(Op
).getImm();
199 assert(value
<= 7 && "Invalid ssecc argument!");
201 case 0: O
<< "eq"; break;
202 case 1: O
<< "lt"; break;
203 case 2: O
<< "le"; break;
204 case 3: O
<< "unord"; break;
205 case 4: O
<< "neq"; break;
206 case 5: O
<< "nlt"; break;
207 case 6: O
<< "nle"; break;
208 case 7: O
<< "ord"; break;
212 static void PrintRegName(raw_ostream
&O
, StringRef RegName
) {
213 for (unsigned i
= 0, e
= RegName
.size(); i
!= e
; ++i
)
214 O
<< (char)toupper(RegName
[i
]);
217 void X86IntelAsmPrinter::printOp(const MachineOperand
&MO
,
218 const char *Modifier
) {
219 switch (MO
.getType()) {
220 case MachineOperand::MO_Register
: {
221 assert(TargetRegisterInfo::isPhysicalRegister(MO
.getReg()));
222 unsigned Reg
= MO
.getReg();
223 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
224 EVT VT
= (strcmp(Modifier
,"subreg64") == 0) ?
225 MVT::i64
: ((strcmp(Modifier
, "subreg32") == 0) ? MVT::i32
:
226 ((strcmp(Modifier
,"subreg16") == 0) ? MVT::i16
:MVT::i8
));
227 Reg
= getX86SubSuperRegister(Reg
, VT
);
229 PrintRegName(O
, TRI
->getAsmName(Reg
));
232 case MachineOperand::MO_Immediate
:
235 case MachineOperand::MO_JumpTableIndex
: {
236 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
237 if (!isMemOp
) O
<< "OFFSET ";
238 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
239 << "_" << MO
.getIndex();
242 case MachineOperand::MO_ConstantPoolIndex
: {
243 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
244 if (!isMemOp
) O
<< "OFFSET ";
245 O
<< "[" << MAI
->getPrivateGlobalPrefix() << "CPI"
246 << getFunctionNumber() << "_" << MO
.getIndex();
247 printOffset(MO
.getOffset());
251 case MachineOperand::MO_GlobalAddress
: {
252 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
253 GlobalValue
*GV
= MO
.getGlobal();
254 std::string Name
= Mang
->getMangledName(GV
);
255 decorateName(Name
, GV
);
257 if (!isMemOp
) O
<< "OFFSET ";
259 // Handle dllimport linkage.
260 // FIXME: This should be fixed with full support of stdcall & fastcall
262 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
266 printOffset(MO
.getOffset());
269 case MachineOperand::MO_ExternalSymbol
: {
270 O
<< MAI
->getGlobalPrefix() << MO
.getSymbolName();
274 O
<< "<unknown operand type>"; return;
278 void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr
*MI
, unsigned OpNo
){
279 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
280 switch (MO
.getType()) {
281 default: llvm_unreachable("Unknown pcrel immediate operand");
282 case MachineOperand::MO_Immediate
:
285 case MachineOperand::MO_MachineBasicBlock
:
286 GetMBBSymbol(MO
.getMBB()->getNumber())->print(O
, MAI
);
289 case MachineOperand::MO_GlobalAddress
: {
290 GlobalValue
*GV
= MO
.getGlobal();
291 std::string Name
= Mang
->getMangledName(GV
);
292 decorateName(Name
, GV
);
294 // Handle dllimport linkage.
295 // FIXME: This should be fixed with full support of stdcall & fastcall
297 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
300 printOffset(MO
.getOffset());
304 case MachineOperand::MO_ExternalSymbol
:
305 O
<< MAI
->getGlobalPrefix() << MO
.getSymbolName();
311 void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr
*MI
,
313 const char *Modifier
) {
314 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
315 int ScaleVal
= MI
->getOperand(Op
+1).getImm();
316 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
317 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
320 bool NeedPlus
= false;
321 if (BaseReg
.getReg()) {
322 printOp(BaseReg
, Modifier
);
326 if (IndexReg
.getReg()) {
327 if (NeedPlus
) O
<< " + ";
329 O
<< ScaleVal
<< "*";
330 printOp(IndexReg
, Modifier
);
334 if (DispSpec
.isGlobal() || DispSpec
.isCPI() ||
338 printOp(DispSpec
, "mem");
340 int DispVal
= DispSpec
.getImm();
341 if (DispVal
|| (!BaseReg
.getReg() && !IndexReg
.getReg())) {
356 void X86IntelAsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
357 const char *Modifier
) {
358 assert(isMem(MI
, Op
) && "Invalid memory reference!");
359 MachineOperand Segment
= MI
->getOperand(Op
+4);
360 if (Segment
.getReg()) {
361 printOperand(MI
, Op
+4, Modifier
);
364 printLeaMemReference(MI
, Op
, Modifier
);
367 void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid
,
368 const MachineBasicBlock
*MBB
) const {
369 if (!MAI
->getSetDirective())
372 O
<< MAI
->getSetDirective() << ' ' << MAI
->getPrivateGlobalPrefix()
373 << getFunctionNumber() << '_' << uid
<< "_set_" << MBB
->getNumber() << ',';
374 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
375 O
<< '-' << "\"L" << getFunctionNumber() << "$pb\"'\n";
378 void X86IntelAsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
) {
379 O
<< "L" << getFunctionNumber() << "$pb\n";
380 O
<< "L" << getFunctionNumber() << "$pb:";
383 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand
&MO
,
385 unsigned Reg
= MO
.getReg();
387 default: return true; // Unknown mode.
388 case 'b': // Print QImode register
389 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
391 case 'h': // Print QImode high register
392 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
394 case 'w': // Print HImode register
395 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
397 case 'k': // Print SImode register
398 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
402 PrintRegName(O
, TRI
->getAsmName(Reg
));
406 /// PrintAsmOperand - Print out an operand for an inline asm expression.
408 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
410 const char *ExtraCode
) {
411 // Does this asm operand have a single letter operand modifier?
412 if (ExtraCode
&& ExtraCode
[0]) {
413 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
415 switch (ExtraCode
[0]) {
416 default: return true; // Unknown modifier.
417 case 'b': // Print QImode register
418 case 'h': // Print QImode high register
419 case 'w': // Print HImode register
420 case 'k': // Print SImode register
421 return printAsmMRegister(MI
->getOperand(OpNo
), ExtraCode
[0]);
425 printOperand(MI
, OpNo
);
429 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
432 const char *ExtraCode
) {
433 if (ExtraCode
&& ExtraCode
[0])
434 return true; // Unknown modifier.
435 printMemReference(MI
, OpNo
);
439 /// printMachineInstruction -- Print out a single X86 LLVM instruction
440 /// MI in Intel syntax to the current output stream.
442 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
445 processDebugLoc(MI
->getDebugLoc());
447 // Call the autogenerated instruction printer routines.
448 printInstruction(MI
);
450 if (VerboseAsm
&& !MI
->getDebugLoc().isUnknown())
455 bool X86IntelAsmPrinter::doInitialization(Module
&M
) {
456 bool Result
= AsmPrinter::doInitialization(M
);
458 O
<< "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n";
460 // Emit declarations for external functions.
461 for (Module::iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
462 if (I
->isDeclaration()) {
463 std::string Name
= Mang
->getMangledName(I
);
464 decorateName(Name
, I
);
467 if (I
->hasDLLImportLinkage()) {
470 O
<< Name
<< ":near\n";
473 // Emit declarations for external globals. Note that VC++ always declares
474 // external globals to have type byte, and if that's good enough for VC++...
475 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
477 if (I
->isDeclaration()) {
478 std::string Name
= Mang
->getMangledName(I
);
481 if (I
->hasDLLImportLinkage()) {
484 O
<< Name
<< ":byte\n";
491 void X86IntelAsmPrinter::PrintGlobalVariable(const GlobalVariable
*GV
) {
492 // Check to see if this is a special global used by LLVM, if so, emit it.
493 if (GV
->isDeclaration() ||
494 EmitSpecialLLVMGlobal(GV
))
497 const TargetData
*TD
= TM
.getTargetData();
499 std::string name
= Mang
->getMangledName(GV
);
500 Constant
*C
= GV
->getInitializer();
501 unsigned Align
= TD
->getPreferredAlignmentLog(GV
);
502 bool bCustomSegment
= false;
504 switch (GV
->getLinkage()) {
505 case GlobalValue::CommonLinkage
:
506 case GlobalValue::LinkOnceAnyLinkage
:
507 case GlobalValue::LinkOnceODRLinkage
:
508 case GlobalValue::WeakAnyLinkage
:
509 case GlobalValue::WeakODRLinkage
:
510 // FIXME: make a MCSection.
511 O
<< name
<< "?\tSEGEMNT PARA common 'COMMON'\n";
512 bCustomSegment
= true;
513 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
514 // are also available.
516 case GlobalValue::AppendingLinkage
:
517 // FIXME: make a MCSection.
518 O
<< name
<< "?\tSEGMENT PARA public 'DATA'\n";
519 bCustomSegment
= true;
520 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
521 // are also available.
523 case GlobalValue::DLLExportLinkage
:
524 DLLExportedGVs
.insert(name
);
526 case GlobalValue::ExternalLinkage
:
527 O
<< "\tpublic " << name
<< "\n";
529 case GlobalValue::InternalLinkage
:
530 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
533 llvm_unreachable("Unknown linkage type!");
537 EmitAlignment(Align
, GV
);
541 O
.PadToColumn(MAI
->getCommentColumn());
542 O
<< MAI
->getCommentString()
543 << " " << GV
->getName();
546 EmitGlobalConstant(C
);
549 O
<< name
<< "?\tends\n";
552 bool X86IntelAsmPrinter::doFinalization(Module
&M
) {
553 // Output linker support code for dllexported globals
554 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty()) {
555 O
<< "; WARNING: The following code is valid only with MASM v8.x"
556 << "and (possible) higher\n"
557 << "; This version of MASM is usually shipped with Microsoft "
558 << "Visual Studio 2005\n"
559 << "; or (possible) further versions. Unfortunately, there is no "
560 << "way to support\n"
561 << "; dllexported symbols in the earlier versions of MASM in fully "
562 << "automatic way\n\n";
563 O
<< "_drectve\t segment info alias('.drectve')\n";
565 for (StringSet
<>::iterator i
= DLLExportedGVs
.begin(),
566 e
= DLLExportedGVs
.end();
568 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << ",data'\n";
570 for (StringSet
<>::iterator i
= DLLExportedFns
.begin(),
571 e
= DLLExportedFns
.end();
573 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << "'\n";
575 O
<< "_drectve\t ends\n";
578 // Bypass X86SharedAsmPrinter::doFinalization().
579 bool Result
= AsmPrinter::doFinalization(M
);
584 void X86IntelAsmPrinter::EmitString(const ConstantArray
*CVA
) const {
585 unsigned NumElts
= CVA
->getNumOperands();
586 if (NumElts
== 0) return;
588 // ML does not have escape sequences except '' for '. It also has a maximum
589 // string length of 255.
591 bool inString
= false;
592 for (unsigned i
= 0; i
< NumElts
; i
++) {
593 int n
= cast
<ConstantInt
>(CVA
->getOperand(i
))->getZExtValue() & 255;
597 if (n
>= 32 && n
<= 127) {
624 len
+= 1 + (n
> 9) + (n
> 99);
644 // Include the auto-generated portion of the assembly writer.
645 #include "X86GenAsmWriter1.inc"