De-virtualize EmitZeroes.
[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 "X86.h"
18 #include "llvm/Constants.h"
19 #include "llvm/Module.h"
20 #include "llvm/Assembly/Writer.h"
21 #include "llvm/Support/Mangler.h"
22 #include "llvm/Target/TargetOptions.h"
23 using namespace llvm;
24
25 X86IntelAsmPrinter::X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM)
26     : X86SharedAsmPrinter(O, TM) {
27   CommentString = ";";
28   GlobalPrefix = "_";
29   PrivateGlobalPrefix = "$";
30   AlignDirective = "\talign\t";
31   ZeroDirective = "\tdb\t";
32   ZeroDirectiveSuffix = " dup(0)";
33   AsciiDirective = "\tdb\t";
34   AscizDirective = 0;
35   Data8bitsDirective = "\t.db\t";
36   Data16bitsDirective = "\t.dw\t";
37   Data32bitsDirective = "\t.dd\t";
38   Data64bitsDirective = "\t.dq\t";
39   HasDotTypeDotSizeDirective = false;
40 }
41
42 /// runOnMachineFunction - This uses the printMachineInstruction()
43 /// method to print assembly for each instruction.
44 ///
45 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
46   if (forDarwin) {
47     // Let PassManager know we need debug information and relay
48     // the MachineDebugInfo address on to DwarfWriter.
49     DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
50   }
51
52   SetupMachineFunction(MF);
53   O << "\n\n";
54
55   // Print out constants referenced by the function
56   EmitConstantPool(MF.getConstantPool());
57
58   // Print out labels for the function.
59   SwitchSection(".code", MF.getFunction());
60   EmitAlignment(4);
61   if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
62     O << "\tpublic " << CurrentFnName << "\n";
63   O << CurrentFnName << "\tproc near\n";
64   
65   if (forDarwin) {
66     // Emit pre-function debug information.
67     DW.BeginFunction(&MF);
68   }
69
70   // Print out code for the function.
71   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
72        I != E; ++I) {
73     // Print a label for the basic block if there are any predecessors.
74     if (I->pred_begin() != I->pred_end())
75       O << PrivateGlobalPrefix << "BB" << CurrentFnName << "_" << I->getNumber()
76         << ":\t"
77         << CommentString << " " << I->getBasicBlock()->getName() << "\n";
78     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
79          II != E; ++II) {
80       // Print the assembly for the instruction.
81       O << "\t";
82       printMachineInstruction(II);
83     }
84   }
85
86   if (forDarwin) {
87     // Emit post-function debug information.
88     DW.EndFunction();
89   }
90
91   O << CurrentFnName << "\tendp\n";
92
93   // We didn't modify anything.
94   return false;
95 }
96
97 void X86IntelAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
98   unsigned char value = MI->getOperand(Op).getImmedValue();
99   assert(value <= 7 && "Invalid ssecc argument!");
100   switch (value) {
101   case 0: O << "eq"; break;
102   case 1: O << "lt"; break;
103   case 2: O << "le"; break;
104   case 3: O << "unord"; break;
105   case 4: O << "neq"; break;
106   case 5: O << "nlt"; break;
107   case 6: O << "nle"; break;
108   case 7: O << "ord"; break;
109   }
110 }
111
112 void X86IntelAsmPrinter::printOp(const MachineOperand &MO, 
113                                  const char *Modifier) {
114   const MRegisterInfo &RI = *TM.getRegisterInfo();
115   switch (MO.getType()) {
116   case MachineOperand::MO_VirtualRegister:
117     if (Value *V = MO.getVRegValueOrNull()) {
118       O << "<" << V->getName() << ">";
119       return;
120     }
121     // FALLTHROUGH
122   case MachineOperand::MO_MachineRegister:
123     if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
124       O << RI.get(MO.getReg()).Name;
125     else
126       O << "reg" << MO.getReg();
127     return;
128
129   case MachineOperand::MO_SignExtendedImmed:
130   case MachineOperand::MO_UnextendedImmed:
131     O << (int)MO.getImmedValue();
132     return;
133   case MachineOperand::MO_MachineBasicBlock:
134     printBasicBlockLabel(MO.getMachineBasicBlock());
135     return;
136   case MachineOperand::MO_PCRelativeDisp:
137     assert(0 && "Shouldn't use addPCDisp() when building X86 MachineInstrs");
138     abort ();
139     return;
140   case MachineOperand::MO_ConstantPoolIndex: {
141     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
142     if (!isMemOp) O << "OFFSET ";
143     O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
144       << MO.getConstantPoolIndex();
145     if (forDarwin && TM.getRelocationModel() == Reloc::PIC)
146       O << "-\"L" << getFunctionNumber() << "$pb\"";
147     int Offset = MO.getOffset();
148     if (Offset > 0)
149       O << " + " << Offset;
150     else if (Offset < 0)
151       O << Offset;
152     O << "]";
153     return;
154   }
155   case MachineOperand::MO_GlobalAddress: {
156     bool isCallOp = Modifier && !strcmp(Modifier, "call");
157     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
158     if (!isMemOp && !isCallOp) O << "OFFSET ";
159     if (forDarwin && TM.getRelocationModel() != Reloc::Static) {
160       GlobalValue *GV = MO.getGlobal();
161       std::string Name = Mang->getValueName(GV);
162       if (!isMemOp && !isCallOp) O << '$';
163       // Link-once, External, or Weakly-linked global variables need
164       // non-lazily-resolved stubs
165       if (GV->isExternal() || GV->hasWeakLinkage() ||
166           GV->hasLinkOnceLinkage()) {
167         // Dynamically-resolved functions need a stub for the function.
168         if (isCallOp && isa<Function>(GV) && cast<Function>(GV)->isExternal()) {
169           FnStubs.insert(Name);
170           O << "L" << Name << "$stub";
171         } else {
172           GVStubs.insert(Name);
173           O << "L" << Name << "$non_lazy_ptr";
174         }
175       } else {
176         O << Mang->getValueName(GV);
177       }
178       if (!isCallOp && TM.getRelocationModel() == Reloc::PIC)
179         O << "-\"L" << getFunctionNumber() << "$pb\"";
180     } else
181       O << Mang->getValueName(MO.getGlobal());
182     int Offset = MO.getOffset();
183     if (Offset > 0)
184       O << " + " << Offset;
185     else if (Offset < 0)
186       O << Offset;
187     return;
188   }
189   case MachineOperand::MO_ExternalSymbol: {
190     bool isCallOp = Modifier && !strcmp(Modifier, "call");
191     if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) {
192       std::string Name(GlobalPrefix);
193       Name += MO.getSymbolName();
194       FnStubs.insert(Name);
195       O << "L" << Name << "$stub";
196       return;
197     }
198     if (!isCallOp) O << "OFFSET ";
199     O << GlobalPrefix << MO.getSymbolName();
200     return;
201   }
202   default:
203     O << "<unknown operand type>"; return;
204   }
205 }
206
207 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
208   assert(isMem(MI, Op) && "Invalid memory reference!");
209
210   const MachineOperand &BaseReg  = MI->getOperand(Op);
211   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
212   const MachineOperand &IndexReg = MI->getOperand(Op+2);
213   const MachineOperand &DispSpec = MI->getOperand(Op+3);
214
215   if (BaseReg.isFrameIndex()) {
216     O << "[frame slot #" << BaseReg.getFrameIndex();
217     if (DispSpec.getImmedValue())
218       O << " + " << DispSpec.getImmedValue();
219     O << "]";
220     return;
221   }
222
223   O << "[";
224   bool NeedPlus = false;
225   if (BaseReg.getReg()) {
226     printOp(BaseReg, "mem");
227     NeedPlus = true;
228   }
229
230   if (IndexReg.getReg()) {
231     if (NeedPlus) O << " + ";
232     if (ScaleVal != 1)
233       O << ScaleVal << "*";
234     printOp(IndexReg);
235     NeedPlus = true;
236   }
237
238   if (DispSpec.isGlobalAddress() || DispSpec.isConstantPoolIndex()) {
239     if (NeedPlus)
240       O << " + ";
241     printOp(DispSpec, "mem");
242   } else {
243     int DispVal = DispSpec.getImmedValue();
244     if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
245       if (NeedPlus)
246         if (DispVal > 0)
247           O << " + ";
248         else {
249           O << " - ";
250           DispVal = -DispVal;
251         }
252       O << DispVal;
253     }
254   }
255   O << "]";
256 }
257
258 void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
259   O << "\"L" << getFunctionNumber() << "$pb\"\n";
260   O << "\"L" << getFunctionNumber() << "$pb\":";
261 }
262
263 bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO,
264                                            const char Mode) {
265   const MRegisterInfo &RI = *TM.getRegisterInfo();
266   unsigned Reg = MO.getReg();
267   const char *Name = RI.get(Reg).Name;
268   switch (Mode) {
269   default: return true;  // Unknown mode.
270   case 'b': // Print QImode register
271     switch (Reg) {
272     default: return true;
273     case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
274       Name = "AL";
275       break;
276     case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
277       Name = "DL";
278       break;
279     case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
280       Name = "CL";
281       break;
282     case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
283       Name = "BL";
284       break;
285     case X86::ESI:
286       Name = "SIL";
287       break;
288     case X86::EDI:
289       Name = "DIL";
290       break;
291     case X86::EBP:
292       Name = "BPL";
293       break;
294     case X86::ESP:
295       Name = "SPL";
296       break;
297     }
298     break;
299   case 'h': // Print QImode high register
300     switch (Reg) {
301     default: return true;
302     case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
303       Name = "AL";
304       break;
305     case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
306       Name = "DL";
307       break;
308     case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
309       Name = "CL";
310       break;
311     case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
312       Name = "BL";
313       break;
314     }
315     break;
316   case 'w': // Print HImode register
317     switch (Reg) {
318     default: return true;
319     case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
320       Name = "AX";
321       break;
322     case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
323       Name = "DX";
324       break;
325     case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
326       Name = "CX";
327       break;
328     case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
329       Name = "BX";
330       break;
331     case X86::ESI:
332       Name = "SI";
333       break;
334     case X86::EDI:
335       Name = "DI";
336       break;
337     case X86::EBP:
338       Name = "BP";
339       break;
340     case X86::ESP:
341       Name = "SP";
342       break;
343     }
344     break;
345   case 'k': // Print SImode register
346     switch (Reg) {
347     default: return true;
348     case X86::AH: case X86::AL: case X86::AX: case X86::EAX:
349       Name = "EAX";
350       break;
351     case X86::DH: case X86::DL: case X86::DX: case X86::EDX:
352       Name = "EDX";
353       break;
354     case X86::CH: case X86::CL: case X86::CX: case X86::ECX:
355       Name = "ECX";
356       break;
357     case X86::BH: case X86::BL: case X86::BX: case X86::EBX:
358       Name = "EBX";
359       break;
360     case X86::ESI:
361       Name = "ESI";
362       break;
363     case X86::EDI:
364       Name = "EDI";
365       break;
366     case X86::EBP:
367       Name = "EBP";
368       break;
369     case X86::ESP:
370       Name = "ESP";
371       break;
372     }
373     break;
374   }
375
376   O << Name;
377   return false;
378 }
379
380 /// PrintAsmOperand - Print out an operand for an inline asm expression.
381 ///
382 bool X86IntelAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
383                                          unsigned AsmVariant, 
384                                          const char *ExtraCode) {
385   // Does this asm operand have a single letter operand modifier?
386   if (ExtraCode && ExtraCode[0]) {
387     if (ExtraCode[1] != 0) return true; // Unknown modifier.
388     
389     switch (ExtraCode[0]) {
390     default: return true;  // Unknown modifier.
391     case 'b': // Print QImode register
392     case 'h': // Print QImode high register
393     case 'w': // Print HImode register
394     case 'k': // Print SImode register
395       return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
396     }
397   }
398   
399   printOperand(MI, OpNo);
400   return false;
401 }
402
403 bool X86IntelAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
404                                                unsigned OpNo,
405                                                unsigned AsmVariant, 
406                                                const char *ExtraCode) {
407   if (ExtraCode && ExtraCode[0])
408     return true; // Unknown modifier.
409   printMemReference(MI, OpNo);
410   return false;
411 }
412
413 /// printMachineInstruction -- Print out a single X86 LLVM instruction
414 /// MI in Intel syntax to the current output stream.
415 ///
416 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
417   ++EmittedInsts;
418
419   // Call the autogenerated instruction printer routines.
420   printInstruction(MI);
421 }
422
423 bool X86IntelAsmPrinter::doInitialization(Module &M) {
424   X86SharedAsmPrinter::doInitialization(M);
425   Mang->markCharUnacceptable('.');
426   PrivateGlobalPrefix = "$";  // need this here too :(
427   O << "\t.686\n\t.model flat\n\n";
428
429   // Emit declarations for external functions.
430   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
431     if (I->isExternal())
432       O << "\textern " << Mang->getValueName(I) << ":near\n";
433
434   // Emit declarations for external globals.
435   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
436        I != E; ++I) {
437     if (I->isExternal())
438       O << "\textern " << Mang->getValueName(I) << ":byte\n";
439   }
440
441   return false;
442 }
443
444 bool X86IntelAsmPrinter::doFinalization(Module &M) {
445   X86SharedAsmPrinter::doFinalization(M);
446   if (CurrentSection != "")
447     O << CurrentSection << "\tends\n";
448   O << "\tend\n";
449   return false;
450 }
451
452 void X86IntelAsmPrinter::SwitchSection(const char *NewSection,
453                                        const GlobalValue *GV) {
454   if (*NewSection == 0)
455     return;
456   
457   std::string NS;
458   bool isData = strcmp(NewSection , ".data") == 0;
459
460   if (GV && GV->hasSection())
461     NS = GV->getSection();
462   else if (isData)
463     NS = "_data";
464   else
465     NS = "_text";
466
467   if (CurrentSection != NS) {
468     if (CurrentSection != "")
469       O << CurrentSection << "\tends\n";
470     CurrentSection = NS;
471     O << CurrentSection << (isData ? "\tsegment 'DATA'\n"
472                                    : "\tsegment 'CODE'\n");
473   }
474 }
475
476 void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const {
477   unsigned NumElts = CVA->getNumOperands();
478   if (NumElts) {
479     // ML does not have escape sequences except '' for '.  It also has a maximum
480     // string length of 255.
481     unsigned len = 0;
482     bool inString = false;
483     for (unsigned i = 0; i < NumElts; i++) {
484       int n = cast<ConstantInt>(CVA->getOperand(i))->getRawValue() & 255;
485       if (len == 0)
486         O << "\tdb ";
487
488       if (n >= 32 && n <= 127) {
489         if (!inString) {
490           if (len > 0) {
491             O << ",'";
492             len += 2;
493           } else {
494             O << "'";
495             len++;
496           }
497           inString = true;
498         }
499         if (n == '\'') {
500           O << "'";
501           len++;
502         }
503         O << char(n);
504       } else {
505         if (inString) {
506           O << "'";
507           len++;
508           inString = false;
509         }
510         if (len > 0) {
511           O << ",";
512           len++;
513         }
514         O << n;
515         len += 1 + (n > 9) + (n > 99);
516       }
517
518       if (len > 60) {
519         if (inString) {
520           O << "'";
521           inString = false;
522         }
523         O << "\n";
524         len = 0;
525       }
526     }
527
528     if (len > 0) {
529       if (inString)
530         O << "'";
531       O << "\n";
532     }
533   }
534 }
535
536 // Include the auto-generated portion of the assembly writer.
537 #include "X86GenAsmWriter1.inc"