Adding codegeneration for StdCall & FastCall calling conventions
[oota-llvm.git] / lib / Target / X86 / X86IntelAsmPrinter.cpp
1 //===-- X86IntelAsmPrinter.cpp - Convert X86 LLVM code to Intel assembly --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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'.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "X86IntelAsmPrinter.h"
17 #include "X86TargetAsmInfo.h"
18 #include "X86.h"
19 #include "llvm/CallingConv.h"
20 #include "llvm/Constants.h"
21 #include "llvm/Module.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/Support/Mangler.h"
24 #include "llvm/Target/TargetAsmInfo.h"
25 #include "llvm/Target/TargetOptions.h"
26 using namespace llvm;
27
28 /// runOnMachineFunction - This uses the printMachineInstruction()
29 /// method to print assembly for each instruction.
30 ///
31 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
32   SetupMachineFunction(MF);
33   O << "\n\n";
34
35   // Print out constants referenced by the function
36   EmitConstantPool(MF.getConstantPool());
37
38   // Print out labels for the function.
39   const Function* F = MF.getFunction();
40   unsigned CC = F->getCallingConv();
41
42   // Populate function information map.  Actually, We don't want to populate
43   // non-stdcall or non-fastcall functions' information right now.
44   if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall) {
45     FunctionInfoMap[F] = *(MF.getInfo<X86FunctionInfo>());
46   }
47
48   X86SharedAsmPrinter::decorateName(CurrentFnName, F);
49
50   switch (F->getLinkage()) {
51   default: assert(0 && "Unsupported linkage type!");
52   case Function::InternalLinkage:
53     SwitchToTextSection("_text", F);
54     EmitAlignment(4);
55     break;    
56   case Function::DLLExportLinkage:
57     DLLExportedFns.insert(CurrentFnName);
58     //FALLS THROUGH
59   case Function::ExternalLinkage:
60     O << "\tpublic " << CurrentFnName << "\n";
61     SwitchToTextSection("_text", F);
62     EmitAlignment(4);
63     break;    
64   }
65   
66   O << CurrentFnName << "\tproc near\n";
67   
68   // Print out code for the function.
69   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
70        I != E; ++I) {
71     // Print a label for the basic block if there are any predecessors.
72     if (I->pred_begin() != I->pred_end()) {
73       printBasicBlockLabel(I, true);
74       O << '\n';
75     }
76     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
77          II != E; ++II) {
78       // Print the assembly for the instruction.
79       O << "\t";
80       printMachineInstruction(II);
81     }
82   }
83
84   O << CurrentFnName << "\tendp\n";
85
86   // We didn't modify anything.
87   return false;
88 }
89
90 void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
91   unsigned char value = MI->getOperand(Op).getImmedValue();
92   assert(value <= 7 && "Invalid ssecc argument!");
93   switch (value) {
94   case 0: O << "eq"; break;
95   case 1: O << "lt"; break;
96   case 2: O << "le"; break;
97   case 3: O << "unord"; break;
98   case 4: O << "neq"; break;
99   case 5: O << "nlt"; break;
100   case 6: O << "nle"; break;
101   case 7: O << "ord"; break;
102   }
103 }
104
105 void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 
106                                  const char *Modifier) {
107   const MRegisterInfo &RI = *TM.getRegisterInfo();
108   switch (MO.getType()) {
109   case MachineOperand::MO_Register:
110     if (MRegisterInfo::isPhysicalRegister(MO.getReg())) {
111       unsigned Reg = MO.getReg();
112       if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
113         MVT::ValueType VT = (strcmp(Modifier,"subreg64") == 0) ?
114           MVT::i64 : ((strcmp(Modifier, "subreg32") == 0) ? MVT::i32 :
115                       ((strcmp(Modifier,"subreg16") == 0) ? MVT::i16 :MVT::i8));
116         Reg = getX86SubSuperRegister(Reg, VT);
117       }
118       O << RI.get(Reg).Name;
119     } else
120       O << "reg" << MO.getReg();
121     return;
122
123   case MachineOperand::MO_Immediate:
124     O << MO.getImmedValue();
125     return;
126   case MachineOperand::MO_MachineBasicBlock:
127     printBasicBlockLabel(MO.getMachineBasicBlock());
128     return;
129   case MachineOperand::MO_ConstantPoolIndex: {
130     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
131     if (!isMemOp) O << "OFFSET ";
132     O << "[" << TAI->getPrivateGlobalPrefix() << "CPI"
133       << getFunctionNumber() << "_" << MO.getConstantPoolIndex();
134     int Offset = MO.getOffset();
135     if (Offset > 0)
136       O << " + " << Offset;
137     else if (Offset < 0)
138       O << Offset;
139     O << "]";
140     return;
141   }
142   case MachineOperand::MO_GlobalAddress: {
143     bool isCallOp = Modifier && !strcmp(Modifier, "call");
144     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
145     GlobalValue *GV = MO.getGlobal();    
146     std::string Name = Mang->getValueName(GV);
147
148     X86SharedAsmPrinter::decorateName(Name, GV);
149
150     if (!isMemOp && !isCallOp) O << "OFFSET ";
151     if (GV->hasDLLImportLinkage()) {
152       // FIXME: This should be fixed with full support of stdcall & fastcall
153       // CC's
154       O << "__imp_";          
155     } 
156     O << Name;
157     int Offset = MO.getOffset();
158     if (Offset > 0)
159       O << " + " << Offset;
160     else if (Offset < 0)
161       O << Offset;
162     return;
163   }
164   case MachineOperand::MO_ExternalSymbol: {
165     bool isCallOp = Modifier && !strcmp(Modifier, "call");
166     if (!isCallOp) O << "OFFSET ";
167     O << TAI->getGlobalPrefix() << MO.getSymbolName();
168     return;
169   }
170   default:
171     O << "<unknown operand type>"; return;
172   }
173 }
174
175 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
176                                            const char *Modifier) {
177   assert(isMem(MI, Op) && "Invalid memory reference!");
178
179   const MachineOperand &BaseReg  = MI->getOperand(Op);
180   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
181   const MachineOperand &IndexReg = MI->getOperand(Op+2);
182   const MachineOperand &DispSpec = MI->getOperand(Op+3);
183
184   if (BaseReg.isFrameIndex()) {
185     O << "[frame slot #" << BaseReg.getFrameIndex();
186     if (DispSpec.getImmedValue())
187       O << " + " << DispSpec.getImmedValue();
188     O << "]";
189     return;
190   }
191
192   O << "[";
193   bool NeedPlus = false;
194   if (BaseReg.getReg()) {
195     printOp(BaseReg, Modifier);
196     NeedPlus = true;
197   }
198
199   if (IndexReg.getReg()) {
200     if (NeedPlus) O << " + ";
201     if (ScaleVal != 1)
202       O << ScaleVal << "*";
203     printOp(IndexReg, Modifier);
204     NeedPlus = true;
205   }
206
207   if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) {
208     if (NeedPlus)
209       O << " + ";
210     printOp(DispSpec, "mem");
211   } else {
212     int DispVal = DispSpec.getImmedValue();
213     if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
214       if (NeedPlus)
215         if (DispVal > 0)
216           O << " + ";
217         else {
218           O << " - ";
219           DispVal = -DispVal;
220         }
221       O << DispVal;
222     }
223   }
224   O << "]";
225 }
226
227 void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
228   O << "\"L" << getFunctionNumber() << "$pb\"\n";
229   O << "\"L" << getFunctionNumber() << "$pb\":";
230 }
231
232 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO,
233                                            const char Mode) {
234   const MRegisterInfo &RI = *TM.getRegisterInfo();
235   unsigned Reg = MO.getReg();
236   switch (Mode) {
237   default: return true;  // Unknown mode.
238   case 'b': // Print QImode register
239     Reg = getX86SubSuperRegister(Reg, MVT::i8);
240     break;
241   case 'h': // Print QImode high register
242     Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
243     break;
244   case 'w': // Print HImode register
245     Reg = getX86SubSuperRegister(Reg, MVT::i16);
246     break;
247   case 'k': // Print SImode register
248     Reg = getX86SubSuperRegister(Reg, MVT::i32);
249     break;
250   }
251
252   O << '%' << RI.get(Reg).Name;
253   return false;
254 }
255
256 /// PrintAsmOperand - Print out an operand for an inline asm expression.
257 ///
258 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
259                                          unsigned AsmVariant, 
260                                          const char *ExtraCode) {
261   // Does this asm operand have a single letter operand modifier?
262   if (ExtraCode && ExtraCode[0]) {
263     if (ExtraCode[1] != 0) return true; // Unknown modifier.
264     
265     switch (ExtraCode[0]) {
266     default: return true;  // Unknown modifier.
267     case 'b': // Print QImode register
268     case 'h': // Print QImode high register
269     case 'w': // Print HImode register
270     case 'k': // Print SImode register
271       return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
272     }
273   }
274   
275   printOperand(MI, OpNo);
276   return false;
277 }
278
279 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
280                                                unsigned OpNo,
281                                                unsigned AsmVariant, 
282                                                const char *ExtraCode) {
283   if (ExtraCode && ExtraCode[0])
284     return true; // Unknown modifier.
285   printMemReference(MI, OpNo);
286   return false;
287 }
288
289 /// printMachineInstruction -- Print out a single X86 LLVM instruction
290 /// MI in Intel syntax to the current output stream.
291 ///
292 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
293   ++EmittedInsts;
294
295   // See if a truncate instruction can be turned into a nop.
296   switch (MI->getOpcode()) {
297   default: break;
298   case X86::TRUNC_64to32:
299   case X86::TRUNC_64to16:
300   case X86::TRUNC_32to16:
301   case X86::TRUNC_32to8:
302   case X86::TRUNC_16to8:
303   case X86::TRUNC_32_to8:
304   case X86::TRUNC_16_to8: {
305     const MachineOperand &MO0 = MI->getOperand(0);
306     const MachineOperand &MO1 = MI->getOperand(1);
307     unsigned Reg0 = MO0.getReg();
308     unsigned Reg1 = MO1.getReg();
309     unsigned Opc = MI->getOpcode();
310     if (Opc == X86::TRUNC_64to32)
311       Reg1 = getX86SubSuperRegister(Reg1, MVT::i32);
312     else if (Opc == X86::TRUNC_32to16 || Opc == X86::TRUNC_64to16)
313       Reg1 = getX86SubSuperRegister(Reg1, MVT::i16);
314     else
315       Reg1 = getX86SubSuperRegister(Reg1, MVT::i8);
316     O << TAI->getCommentString() << " TRUNCATE ";
317     if (Reg0 != Reg1)
318       O << "\n\t";
319     break;
320   }
321   case X86::PsMOVZX64rr32:
322     O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
323     break;
324   }
325
326   // Call the autogenerated instruction printer routines.
327   printInstruction(MI);
328 }
329
330 bool X86IntelAsmPrinter::doInitialization(Module &M) {
331   X86SharedAsmPrinter::doInitialization(M);
332   
333   Mang->markCharUnacceptable('.');
334
335   O << "\t.686\n\t.model flat\n\n";
336
337   // Emit declarations for external functions.
338   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
339     if (I->isExternal()) {
340       std::string Name = Mang->getValueName(I);
341       X86SharedAsmPrinter::decorateName(Name, I);
342
343       O << "\textern " ;
344       if (I->hasDLLImportLinkage()) {
345         O << "__imp_";
346       }      
347       O << Name << ":near\n";
348     }
349   
350   // Emit declarations for external globals.  Note that VC++ always declares
351   // external globals to have type byte, and if that's good enough for VC++...
352   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
353        I != E; ++I) {
354     if (I->isExternal()) {
355       std::string Name = Mang->getValueName(I);
356
357       O << "\textern " ;
358       if (I->hasDLLImportLinkage()) {
359         O << "__imp_";
360       }      
361       O << Name << ":byte\n";
362     }
363   }
364
365   return false;
366 }
367
368 bool X86IntelAsmPrinter::doFinalization(Module &M) {
369   const TargetData *TD = TM.getTargetData();
370
371   // Print out module-level global variables here.
372   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
373        I != E; ++I) {
374     if (I->isExternal()) continue;   // External global require no code
375     
376     // Check to see if this is a special global used by LLVM, if so, emit it.
377     if (EmitSpecialLLVMGlobal(I))
378       continue;
379     
380     std::string name = Mang->getValueName(I);
381     Constant *C = I->getInitializer();
382     unsigned Size = TD->getTypeSize(C->getType());
383     unsigned Align = getPreferredAlignmentLog(I);
384     bool bCustomSegment = false;
385
386     switch (I->getLinkage()) {
387     case GlobalValue::LinkOnceLinkage:
388     case GlobalValue::WeakLinkage:
389       SwitchToDataSection("", 0);
390       O << name << "?\tsegment common 'COMMON'\n";
391       bCustomSegment = true;
392       // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
393       // are also available.
394       break;
395     case GlobalValue::AppendingLinkage:
396       SwitchToDataSection("", 0);
397       O << name << "?\tsegment public 'DATA'\n";
398       bCustomSegment = true;
399       // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
400       // are also available.
401       break;
402     case GlobalValue::DLLExportLinkage:
403       DLLExportedGVs.insert(name);
404       // FALL THROUGH
405     case GlobalValue::ExternalLinkage:
406       O << "\tpublic " << name << "\n";
407       // FALL THROUGH
408     case GlobalValue::InternalLinkage:
409       SwitchToDataSection(TAI->getDataSection(), I);
410       break;
411     default:
412       assert(0 && "Unknown linkage type!");
413     }
414
415     if (!bCustomSegment)
416       EmitAlignment(Align, I);
417
418     O << name << ":\t\t\t\t" << TAI->getCommentString()
419       << " " << I->getName() << '\n';
420
421     EmitGlobalConstant(C);
422
423     if (bCustomSegment)
424       O << name << "?\tends\n";
425   }
426
427     // Output linker support code for dllexported globals
428   if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
429       (DLLExportedFns.begin() != DLLExportedFns.end())) {
430     SwitchToDataSection("", 0);
431     O << "; WARNING: The following code is valid only with MASM v8.x and (possible) higher\n"
432       << "; This version of MASM is usually shipped with Microsoft Visual Studio 2005\n"
433       << "; or (possible) further versions. Unfortunately, there is no way to support\n"
434       << "; dllexported symbols in the earlier versions of MASM in fully automatic way\n\n";
435     O << "_drectve\t segment info alias('.drectve')\n";
436   }
437
438   for (std::set<std::string>::iterator i = DLLExportedGVs.begin(),
439          e = DLLExportedGVs.end();
440          i != e; ++i) {
441     O << "\t db ' /EXPORT:" << *i << ",data'\n";
442   }    
443
444   for (std::set<std::string>::iterator i = DLLExportedFns.begin(),
445          e = DLLExportedFns.end();
446          i != e; ++i) {
447     O << "\t db ' /EXPORT:" << *i << "'\n";
448   }    
449
450   if ((DLLExportedGVs.begin() != DLLExportedGVs.end()) ||
451       (DLLExportedFns.begin() != DLLExportedFns.end())) {
452     O << "_drectve\t ends\n";    
453   }
454   
455   // Bypass X86SharedAsmPrinter::doFinalization().
456   AsmPrinter::doFinalization(M);
457   SwitchToDataSection("", 0);
458   O << "\tend\n";
459   return false; // success
460 }
461
462 void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const {
463   unsigned NumElts = CVA->getNumOperands();
464   if (NumElts) {
465     // ML does not have escape sequences except '' for '.  It also has a maximum
466     // string length of 255.
467     unsigned len = 0;
468     bool inString = false;
469     for (unsigned i = 0; i < NumElts; i++) {
470       int n = cast<ConstantInt>(CVA->getOperand(i))->getRawValue() & 255;
471       if (len == 0)
472         O << "\tdb ";
473
474       if (n >= 32 && n <= 127) {
475         if (!inString) {
476           if (len > 0) {
477             O << ",'";
478             len += 2;
479           } else {
480             O << "'";
481             len++;
482           }
483           inString = true;
484         }
485         if (n == '\'') {
486           O << "'";
487           len++;
488         }
489         O << char(n);
490       } else {
491         if (inString) {
492           O << "'";
493           len++;
494           inString = false;
495         }
496         if (len > 0) {
497           O << ",";
498           len++;
499         }
500         O << n;
501         len += 1 + (n > 9) + (n > 99);
502       }
503
504       if (len > 60) {
505         if (inString) {
506           O << "'";
507           inString = false;
508         }
509         O << "\n";
510         len = 0;
511       }
512     }
513
514     if (len > 0) {
515       if (inString)
516         O << "'";
517       O << "\n";
518     }
519   }
520 }
521
522 // Include the auto-generated portion of the assembly writer.
523 #include "X86GenAsmWriter1.inc"