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::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
218 const char *Modifier
) {
219 printOp(MI
->getOperand(OpNo
), Modifier
);
222 void X86IntelAsmPrinter::printOp(const MachineOperand
&MO
,
223 const char *Modifier
) {
224 switch (MO
.getType()) {
225 case MachineOperand::MO_Register
: {
226 unsigned Reg
= MO
.getReg();
227 if (Modifier
&& strncmp(Modifier
, "subreg", strlen("subreg")) == 0) {
228 EVT VT
= (strcmp(Modifier
,"subreg64") == 0) ?
229 MVT::i64
: ((strcmp(Modifier
, "subreg32") == 0) ? MVT::i32
:
230 ((strcmp(Modifier
,"subreg16") == 0) ? MVT::i16
:MVT::i8
));
231 Reg
= getX86SubSuperRegister(Reg
, VT
);
233 PrintRegName(O
, getRegisterName(Reg
));
236 case MachineOperand::MO_Immediate
:
239 case MachineOperand::MO_JumpTableIndex
: {
240 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
241 if (!isMemOp
) O
<< "OFFSET ";
242 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
243 << "_" << MO
.getIndex();
246 case MachineOperand::MO_ConstantPoolIndex
: {
247 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
248 if (!isMemOp
) O
<< "OFFSET ";
249 O
<< "[" << MAI
->getPrivateGlobalPrefix() << "CPI"
250 << getFunctionNumber() << "_" << MO
.getIndex();
251 printOffset(MO
.getOffset());
255 case MachineOperand::MO_GlobalAddress
: {
256 bool isMemOp
= Modifier
&& !strcmp(Modifier
, "mem");
257 GlobalValue
*GV
= MO
.getGlobal();
258 std::string Name
= Mang
->getMangledName(GV
);
259 decorateName(Name
, GV
);
261 if (!isMemOp
) O
<< "OFFSET ";
263 // Handle dllimport linkage.
264 // FIXME: This should be fixed with full support of stdcall & fastcall
266 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
270 printOffset(MO
.getOffset());
273 case MachineOperand::MO_ExternalSymbol
: {
274 O
<< MAI
->getGlobalPrefix() << MO
.getSymbolName();
278 O
<< "<unknown operand type>"; return;
282 void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr
*MI
, unsigned OpNo
){
283 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
284 switch (MO
.getType()) {
285 default: llvm_unreachable("Unknown pcrel immediate operand");
286 case MachineOperand::MO_Immediate
:
289 case MachineOperand::MO_MachineBasicBlock
:
290 GetMBBSymbol(MO
.getMBB()->getNumber())->print(O
, MAI
);
293 case MachineOperand::MO_GlobalAddress
: {
294 GlobalValue
*GV
= MO
.getGlobal();
295 std::string Name
= Mang
->getMangledName(GV
);
296 decorateName(Name
, GV
);
298 // Handle dllimport linkage.
299 // FIXME: This should be fixed with full support of stdcall & fastcall
301 if (MO
.getTargetFlags() == X86II::MO_DLLIMPORT
)
304 printOffset(MO
.getOffset());
308 case MachineOperand::MO_ExternalSymbol
:
309 O
<< MAI
->getGlobalPrefix() << MO
.getSymbolName();
315 void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr
*MI
,
317 const char *Modifier
) {
318 const MachineOperand
&BaseReg
= MI
->getOperand(Op
);
319 int ScaleVal
= MI
->getOperand(Op
+1).getImm();
320 const MachineOperand
&IndexReg
= MI
->getOperand(Op
+2);
321 const MachineOperand
&DispSpec
= MI
->getOperand(Op
+3);
324 bool NeedPlus
= false;
325 if (BaseReg
.getReg()) {
326 printOp(BaseReg
, Modifier
);
330 if (IndexReg
.getReg()) {
331 if (NeedPlus
) O
<< " + ";
333 O
<< ScaleVal
<< "*";
334 printOp(IndexReg
, Modifier
);
338 if (DispSpec
.isGlobal() || DispSpec
.isCPI() ||
342 printOp(DispSpec
, "mem");
344 int DispVal
= DispSpec
.getImm();
345 if (DispVal
|| (!BaseReg
.getReg() && !IndexReg
.getReg())) {
360 void X86IntelAsmPrinter::printMemReference(const MachineInstr
*MI
, unsigned Op
,
361 const char *Modifier
) {
362 assert(isMem(MI
, Op
) && "Invalid memory reference!");
363 MachineOperand Segment
= MI
->getOperand(Op
+4);
364 if (Segment
.getReg()) {
365 printOperand(MI
, Op
+4, Modifier
);
368 printLeaMemReference(MI
, Op
, Modifier
);
371 void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid
,
372 const MachineBasicBlock
*MBB
) const {
373 if (!MAI
->getSetDirective())
376 O
<< MAI
->getSetDirective() << ' ' << MAI
->getPrivateGlobalPrefix()
377 << getFunctionNumber() << '_' << uid
<< "_set_" << MBB
->getNumber() << ',';
378 GetMBBSymbol(MBB
->getNumber())->print(O
, MAI
);
379 O
<< '-' << "\"L" << getFunctionNumber() << "$pb\"'\n";
382 void X86IntelAsmPrinter::printPICLabel(const MachineInstr
*MI
, unsigned Op
) {
383 O
<< "L" << getFunctionNumber() << "$pb\n";
384 O
<< "L" << getFunctionNumber() << "$pb:";
387 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand
&MO
,
389 unsigned Reg
= MO
.getReg();
391 default: return true; // Unknown mode.
392 case 'b': // Print QImode register
393 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
);
395 case 'h': // Print QImode high register
396 Reg
= getX86SubSuperRegister(Reg
, MVT::i8
, true);
398 case 'w': // Print HImode register
399 Reg
= getX86SubSuperRegister(Reg
, MVT::i16
);
401 case 'k': // Print SImode register
402 Reg
= getX86SubSuperRegister(Reg
, MVT::i32
);
406 PrintRegName(O
, getRegisterName(Reg
));
410 /// PrintAsmOperand - Print out an operand for an inline asm expression.
412 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
414 const char *ExtraCode
) {
415 // Does this asm operand have a single letter operand modifier?
416 if (ExtraCode
&& ExtraCode
[0]) {
417 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
419 switch (ExtraCode
[0]) {
420 default: return true; // Unknown modifier.
421 case 'b': // Print QImode register
422 case 'h': // Print QImode high register
423 case 'w': // Print HImode register
424 case 'k': // Print SImode register
425 return printAsmMRegister(MI
->getOperand(OpNo
), ExtraCode
[0]);
429 printOperand(MI
, OpNo
);
433 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
,
436 const char *ExtraCode
) {
437 if (ExtraCode
&& ExtraCode
[0])
438 return true; // Unknown modifier.
439 printMemReference(MI
, OpNo
);
443 /// printMachineInstruction -- Print out a single X86 LLVM instruction
444 /// MI in Intel syntax to the current output stream.
446 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr
*MI
) {
449 processDebugLoc(MI
->getDebugLoc());
451 // Call the autogenerated instruction printer routines.
452 printInstruction(MI
);
454 if (VerboseAsm
&& !MI
->getDebugLoc().isUnknown())
459 bool X86IntelAsmPrinter::doInitialization(Module
&M
) {
460 bool Result
= AsmPrinter::doInitialization(M
);
462 O
<< "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n";
464 // Emit declarations for external functions.
465 for (Module::iterator I
= M
.begin(), E
= M
.end(); I
!= E
; ++I
)
466 if (I
->isDeclaration()) {
467 std::string Name
= Mang
->getMangledName(I
);
468 decorateName(Name
, I
);
471 if (I
->hasDLLImportLinkage()) {
474 O
<< Name
<< ":near\n";
477 // Emit declarations for external globals. Note that VC++ always declares
478 // external globals to have type byte, and if that's good enough for VC++...
479 for (Module::const_global_iterator I
= M
.global_begin(), E
= M
.global_end();
481 if (I
->isDeclaration()) {
482 std::string Name
= Mang
->getMangledName(I
);
485 if (I
->hasDLLImportLinkage()) {
488 O
<< Name
<< ":byte\n";
495 void X86IntelAsmPrinter::PrintGlobalVariable(const GlobalVariable
*GV
) {
496 // Check to see if this is a special global used by LLVM, if so, emit it.
497 if (GV
->isDeclaration() ||
498 EmitSpecialLLVMGlobal(GV
))
501 const TargetData
*TD
= TM
.getTargetData();
503 std::string name
= Mang
->getMangledName(GV
);
504 Constant
*C
= GV
->getInitializer();
505 unsigned Align
= TD
->getPreferredAlignmentLog(GV
);
506 bool bCustomSegment
= false;
508 switch (GV
->getLinkage()) {
509 case GlobalValue::CommonLinkage
:
510 case GlobalValue::LinkOnceAnyLinkage
:
511 case GlobalValue::LinkOnceODRLinkage
:
512 case GlobalValue::WeakAnyLinkage
:
513 case GlobalValue::WeakODRLinkage
:
514 // FIXME: make a MCSection.
515 O
<< name
<< "?\tSEGEMNT PARA common 'COMMON'\n";
516 bCustomSegment
= true;
517 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
518 // are also available.
520 case GlobalValue::AppendingLinkage
:
521 // FIXME: make a MCSection.
522 O
<< name
<< "?\tSEGMENT PARA public 'DATA'\n";
523 bCustomSegment
= true;
524 // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
525 // are also available.
527 case GlobalValue::DLLExportLinkage
:
528 DLLExportedGVs
.insert(name
);
530 case GlobalValue::ExternalLinkage
:
531 O
<< "\tpublic " << name
<< "\n";
533 case GlobalValue::InternalLinkage
:
534 OutStreamer
.SwitchSection(getObjFileLowering().getDataSection());
537 llvm_unreachable("Unknown linkage type!");
541 EmitAlignment(Align
, GV
);
545 O
.PadToColumn(MAI
->getCommentColumn());
546 O
<< MAI
->getCommentString()
547 << " " << GV
->getName();
550 EmitGlobalConstant(C
);
553 O
<< name
<< "?\tends\n";
556 bool X86IntelAsmPrinter::doFinalization(Module
&M
) {
557 // Output linker support code for dllexported globals
558 if (!DLLExportedGVs
.empty() || !DLLExportedFns
.empty()) {
559 O
<< "; WARNING: The following code is valid only with MASM v8.x"
560 << "and (possible) higher\n"
561 << "; This version of MASM is usually shipped with Microsoft "
562 << "Visual Studio 2005\n"
563 << "; or (possible) further versions. Unfortunately, there is no "
564 << "way to support\n"
565 << "; dllexported symbols in the earlier versions of MASM in fully "
566 << "automatic way\n\n";
567 O
<< "_drectve\t segment info alias('.drectve')\n";
569 for (StringSet
<>::iterator i
= DLLExportedGVs
.begin(),
570 e
= DLLExportedGVs
.end();
572 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << ",data'\n";
574 for (StringSet
<>::iterator i
= DLLExportedFns
.begin(),
575 e
= DLLExportedFns
.end();
577 O
<< "\t db ' /EXPORT:" << i
->getKeyData() << "'\n";
579 O
<< "_drectve\t ends\n";
582 // Bypass X86SharedAsmPrinter::doFinalization().
583 bool Result
= AsmPrinter::doFinalization(M
);
588 void X86IntelAsmPrinter::EmitString(const ConstantArray
*CVA
) const {
589 unsigned NumElts
= CVA
->getNumOperands();
590 if (NumElts
== 0) return;
592 // ML does not have escape sequences except '' for '. It also has a maximum
593 // string length of 255.
595 bool inString
= false;
596 for (unsigned i
= 0; i
< NumElts
; i
++) {
597 int n
= cast
<ConstantInt
>(CVA
->getOperand(i
))->getZExtValue() & 255;
601 if (n
>= 32 && n
<= 127) {
628 len
+= 1 + (n
> 9) + (n
> 99);
648 // Include the auto-generated portion of the assembly writer.
649 #include "X86GenAsmWriter1.inc"