Make the x86 asm printer darwin-aware. This mostly entails doing the same
[oota-llvm.git] / lib / Target / X86 / X86AsmPrinter.cpp
1 //===-- X86AsmPrinter.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 and AT&T format assembly
12 // language. This printer is the output mechanism used by `llc' and `lli
13 // -print-machineinstrs' on X86.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #include "X86.h"
18 #include "X86TargetMachine.h"
19 #include "llvm/Module.h"
20 #include "llvm/Type.h"
21 #include "llvm/Assembly/Writer.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/ValueTypes.h"
26 #include "llvm/Target/TargetMachine.h"
27 #include "llvm/Support/Mangler.h"
28 #include "llvm/ADT/Statistic.h"
29 #include "llvm/Support/CommandLine.h"
30 using namespace llvm;
31
32 namespace {
33   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
34   enum AsmWriterFlavor { att, intel };
35
36   cl::opt<AsmWriterFlavor>
37   AsmWriterFlavor("x86-asm-syntax",
38                   cl::desc("Choose style of code to emit from X86 backend:"),
39                   cl::values(
40                              clEnumVal(att,   "  Emit AT&T-style assembly"),
41                              clEnumVal(intel, "  Emit Intel-style assembly"),
42                              clEnumValEnd),
43                   cl::init(att));
44
45   struct X86SharedAsmPrinter : public AsmPrinter {
46     X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM)
47       : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { }
48
49     bool doInitialization(Module &M);
50     void printConstantPool(MachineConstantPool *MCP);
51     bool doFinalization(Module &M);
52     bool forCygwin;
53     bool forDarwin;
54   };
55 }
56
57 static bool isScale(const MachineOperand &MO) {
58   return MO.isImmediate() &&
59     (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 ||
60      MO.getImmedValue() == 4 || MO.getImmedValue() == 8);
61 }
62
63 static bool isMem(const MachineInstr *MI, unsigned Op) {
64   if (MI->getOperand(Op).isFrameIndex()) return true;
65   if (MI->getOperand(Op).isConstantPoolIndex()) return true;
66   return Op+4 <= MI->getNumOperands() &&
67     MI->getOperand(Op  ).isRegister() && isScale(MI->getOperand(Op+1)) &&
68     MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate() ||
69         MI->getOperand(Op+3).isGlobalAddress());
70 }
71
72 // SwitchSection - Switch to the specified section of the executable if we are
73 // not already in it!
74 //
75 static void SwitchSection(std::ostream &OS, std::string &CurSection,
76                           const char *NewSection) {
77   if (CurSection != NewSection) {
78     CurSection = NewSection;
79     if (!CurSection.empty())
80       OS << "\t" << NewSection << "\n";
81   }
82 }
83
84 /// doInitialization - determine
85 bool X86SharedAsmPrinter::doInitialization(Module& M) {
86   const std::string& TT = M.getTargetTriple();
87   if (TT.length() > 5) {
88     forCygwin = TT.find("cygwin") != std::string::npos ||
89                 TT.find("mingw")  != std::string::npos;
90     forDarwin = TT.find("darwin") != std::string::npos;
91   } else if (TT.empty()) {
92 #if defined(__CYGWIN__) || defined(__MINGW32__)
93     forCygwin = true;
94 #elif defined(__MACOSX__)
95     forDarwin = true;
96 #endif
97   }
98   if (forCygwin || forDarwin)
99     GlobalPrefix = "_";
100   if (forDarwin)
101     AlignmentIsInBytes = false;
102   return AsmPrinter::doInitialization(M);
103 }
104
105 /// printConstantPool - Print to the current output stream assembly
106 /// representations of the constants in the constant pool MCP. This is
107 /// used to print out constants which have been "spilled to memory" by
108 /// the code generator.
109 ///
110 void X86SharedAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
111   const std::vector<Constant*> &CP = MCP->getConstants();
112   const TargetData &TD = TM.getTargetData();
113
114   if (CP.empty()) return;
115
116   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
117     O << "\t.section .rodata\n";
118     emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
119     O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
120       << *CP[i] << "\n";
121     emitGlobalConstant(CP[i]);
122   }
123 }
124
125 bool X86SharedAsmPrinter::doFinalization(Module &M) {
126   const TargetData &TD = TM.getTargetData();
127   std::string CurSection;
128
129   // Print out module-level global variables here.
130   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
131     if (I->hasInitializer()) {   // External global require no code
132       O << "\n\n";
133       std::string name = Mang->getValueName(I);
134       Constant *C = I->getInitializer();
135       unsigned Size = TD.getTypeSize(C->getType());
136       unsigned Align = TD.getTypeAlignmentShift(C->getType());
137
138       if (C->isNullValue() &&
139           (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
140            I->hasWeakLinkage() /* FIXME: Verify correct */)) {
141         SwitchSection(O, CurSection, ".data");
142         if (!forCygwin && I->hasInternalLinkage())
143           O << "\t.local " << name << "\n";
144
145         O << "\t.comm " << name << "," << TD.getTypeSize(C->getType());
146         if (!forCygwin)
147           O << "," << (1 << Align);
148         O << "\t\t# ";
149         WriteAsOperand(O, I, true, true, &M);
150         O << "\n";
151       } else {
152         switch (I->getLinkage()) {
153         case GlobalValue::LinkOnceLinkage:
154         case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
155           // Nonnull linkonce -> weak
156           O << "\t.weak " << name << "\n";
157           SwitchSection(O, CurSection, "");
158           O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
159           break;
160         case GlobalValue::AppendingLinkage:
161           // FIXME: appending linkage variables should go into a section of
162           // their name or something.  For now, just emit them as external.
163         case GlobalValue::ExternalLinkage:
164           // If external or appending, declare as a global symbol
165           O << "\t.globl " << name << "\n";
166           // FALL THROUGH
167         case GlobalValue::InternalLinkage:
168           if (C->isNullValue())
169             SwitchSection(O, CurSection, ".bss");
170           else
171             SwitchSection(O, CurSection, ".data");
172           break;
173         case GlobalValue::GhostLinkage:
174           std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n";
175           abort();
176         }
177
178         emitAlignment(Align);
179         if (!forCygwin && !forDarwin) {
180           O << "\t.type " << name << ",@object\n";
181           O << "\t.size " << name << "," << Size << "\n";
182         }
183         O << name << ":\t\t\t\t# ";
184         WriteAsOperand(O, I, true, true, &M);
185         O << " = ";
186         WriteAsOperand(O, C, false, false, &M);
187         O << "\n";
188         emitGlobalConstant(C);
189       }
190     }
191
192   AsmPrinter::doFinalization(M);
193   return false; // success
194 }
195
196 namespace {
197   struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
198     X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM)
199       : X86SharedAsmPrinter(O, TM) { }
200
201     virtual const char *getPassName() const {
202       return "X86 Intel-Style Assembly Printer";
203     }
204
205     /// printInstruction - This method is automatically generated by tablegen
206     /// from the instruction set description.  This method returns true if the
207     /// machine instruction was sufficiently described to print it, otherwise it
208     /// returns false.
209     bool printInstruction(const MachineInstr *MI);
210
211     // This method is used by the tablegen'erated instruction printer.
212     void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
213       const MachineOperand &MO = MI->getOperand(OpNo);
214       if (MO.getType() == MachineOperand::MO_MachineRegister) {
215         assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??");
216         // Bug Workaround: See note in Printer::doInitialization about %.
217         O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name;
218       } else {
219         printOp(MO);
220       }
221     }
222
223     void printCallOperand(const MachineInstr *MI, unsigned OpNo,
224                           MVT::ValueType VT) {
225       printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET".
226     }
227
228     void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
229                             MVT::ValueType VT) {
230       switch (VT) {
231       default: assert(0 && "Unknown arg size!");
232       case MVT::i8:   O << "BYTE PTR "; break;
233       case MVT::i16:  O << "WORD PTR "; break;
234       case MVT::i32:
235       case MVT::f32:  O << "DWORD PTR "; break;
236       case MVT::i64:
237       case MVT::f64:  O << "QWORD PTR "; break;
238       case MVT::f80:  O << "XWORD PTR "; break;
239       }
240       printMemReference(MI, OpNo);
241     }
242
243     void printMachineInstruction(const MachineInstr *MI);
244     void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false);
245     void printMemReference(const MachineInstr *MI, unsigned Op);
246     bool runOnMachineFunction(MachineFunction &F);
247     bool doInitialization(Module &M);
248   };
249 } // end of anonymous namespace
250
251
252 // Include the auto-generated portion of the assembly writer.
253 #include "X86GenAsmWriter1.inc"
254
255
256 /// runOnMachineFunction - This uses the printMachineInstruction()
257 /// method to print assembly for each instruction.
258 ///
259 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
260   setupMachineFunction(MF);
261   O << "\n\n";
262
263   // Print out constants referenced by the function
264   printConstantPool(MF.getConstantPool());
265
266   // Print out labels for the function.
267   O << "\t.text\n";
268   emitAlignment(4);
269   O << "\t.globl\t" << CurrentFnName << "\n";
270   if (!forCygwin && !forDarwin)
271     O << "\t.type\t" << CurrentFnName << ", @function\n";
272   O << CurrentFnName << ":\n";
273
274   // Print out code for the function.
275   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
276        I != E; ++I) {
277     // Print a label for the basic block if there are any predecessors.
278     if (I->pred_begin() != I->pred_end())
279       O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
280         << CommentString << " " << I->getBasicBlock()->getName() << "\n";
281     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
282          II != E; ++II) {
283       // Print the assembly for the instruction.
284       O << "\t";
285       printMachineInstruction(II);
286     }
287   }
288
289   // We didn't modify anything.
290   return false;
291 }
292
293 void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
294                                  bool elideOffsetKeyword /* = false */) {
295   const MRegisterInfo &RI = *TM.getRegisterInfo();
296   switch (MO.getType()) {
297   case MachineOperand::MO_VirtualRegister:
298     if (Value *V = MO.getVRegValueOrNull()) {
299       O << "<" << V->getName() << ">";
300       return;
301     }
302     // FALLTHROUGH
303   case MachineOperand::MO_MachineRegister:
304     if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
305       // Bug Workaround: See note in Printer::doInitialization about %.
306       O << "%" << RI.get(MO.getReg()).Name;
307     else
308       O << "%reg" << MO.getReg();
309     return;
310
311   case MachineOperand::MO_SignExtendedImmed:
312   case MachineOperand::MO_UnextendedImmed:
313     O << (int)MO.getImmedValue();
314     return;
315   case MachineOperand::MO_MachineBasicBlock: {
316     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
317     O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
318       << "_" << MBBOp->getNumber () << '\t' << CommentString
319       << MBBOp->getBasicBlock ()->getName ();
320     return;
321   }
322   case MachineOperand::MO_PCRelativeDisp:
323     std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
324     abort ();
325     return;
326   case MachineOperand::MO_GlobalAddress: {
327     if (!elideOffsetKeyword)
328       O << "OFFSET ";
329     O << Mang->getValueName(MO.getGlobal());
330     int Offset = MO.getOffset();
331     if (Offset > 0)
332       O << " + " << Offset;
333     else if (Offset < 0)
334       O << " - " << -Offset;
335     return;
336   }
337   case MachineOperand::MO_ExternalSymbol:
338     O << GlobalPrefix << MO.getSymbolName();
339     return;
340   default:
341     O << "<unknown operand type>"; return;
342   }
343 }
344
345 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
346   assert(isMem(MI, Op) && "Invalid memory reference!");
347
348   const MachineOperand &BaseReg  = MI->getOperand(Op);
349   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
350   const MachineOperand &IndexReg = MI->getOperand(Op+2);
351   const MachineOperand &DispSpec = MI->getOperand(Op+3);
352
353   if (BaseReg.isFrameIndex()) {
354     O << "[frame slot #" << BaseReg.getFrameIndex();
355     if (DispSpec.getImmedValue())
356       O << " + " << DispSpec.getImmedValue();
357     O << "]";
358     return;
359   } else if (BaseReg.isConstantPoolIndex()) {
360     O << "[.CPI" << CurrentFnName << "_"
361       << BaseReg.getConstantPoolIndex();
362
363     if (IndexReg.getReg()) {
364       O << " + ";
365       if (ScaleVal != 1)
366         O << ScaleVal << "*";
367       printOp(IndexReg);
368     }
369
370     if (DispSpec.getImmedValue())
371       O << " + " << DispSpec.getImmedValue();
372     O << "]";
373     return;
374   }
375
376   O << "[";
377   bool NeedPlus = false;
378   if (BaseReg.getReg()) {
379     printOp(BaseReg, true);
380     NeedPlus = true;
381   }
382
383   if (IndexReg.getReg()) {
384     if (NeedPlus) O << " + ";
385     if (ScaleVal != 1)
386       O << ScaleVal << "*";
387     printOp(IndexReg);
388     NeedPlus = true;
389   }
390
391   if (DispSpec.isGlobalAddress()) {
392     if (NeedPlus)
393       O << " + ";
394     printOp(DispSpec, true);
395   } else {
396     int DispVal = DispSpec.getImmedValue();
397     if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) {
398       if (NeedPlus)
399         if (DispVal > 0)
400           O << " + ";
401         else {
402           O << " - ";
403           DispVal = -DispVal;
404         }
405       O << DispVal;
406     }
407   }
408   O << "]";
409 }
410
411
412 /// printMachineInstruction -- Print out a single X86 LLVM instruction
413 /// MI in Intel syntax to the current output stream.
414 ///
415 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
416   ++EmittedInsts;
417
418   // Call the autogenerated instruction printer routines.
419   printInstruction(MI);
420 }
421
422 bool X86IntelAsmPrinter::doInitialization(Module &M) {
423   AsmPrinter::doInitialization(M);
424   // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
425   //
426   // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
427   // instruction as a reference to the register named sp, and if you try to
428   // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
429   // before being looked up in the symbol table. This creates spurious
430   // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
431   // mode, and decorate all register names with percent signs.
432   O << "\t.intel_syntax\n";
433   return false;
434 }
435
436
437
438 namespace {
439   struct X86ATTAsmPrinter : public X86SharedAsmPrinter {
440     X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM)
441       : X86SharedAsmPrinter(O, TM) { }
442
443     virtual const char *getPassName() const {
444       return "X86 AT&T-Style Assembly Printer";
445     }
446
447     /// printInstruction - This method is automatically generated by tablegen
448     /// from the instruction set description.  This method returns true if the
449     /// machine instruction was sufficiently described to print it, otherwise it
450     /// returns false.
451     bool printInstruction(const MachineInstr *MI);
452
453     // This method is used by the tablegen'erated instruction printer.
454     void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){
455       printOp(MI->getOperand(OpNo));
456     }
457
458     void printCallOperand(const MachineInstr *MI, unsigned OpNo,
459                           MVT::ValueType VT) {
460       printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix.
461     }
462
463     void printMemoryOperand(const MachineInstr *MI, unsigned OpNo,
464                             MVT::ValueType VT) {
465       printMemReference(MI, OpNo);
466     }
467
468     void printMachineInstruction(const MachineInstr *MI);
469     void printOp(const MachineOperand &MO, bool isCallOperand = false);
470     void printMemReference(const MachineInstr *MI, unsigned Op);
471     bool runOnMachineFunction(MachineFunction &F);
472   };
473 } // end of anonymous namespace
474
475
476 // Include the auto-generated portion of the assembly writer.
477 #include "X86GenAsmWriter.inc"
478
479
480 /// runOnMachineFunction - This uses the printMachineInstruction()
481 /// method to print assembly for each instruction.
482 ///
483 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
484   setupMachineFunction(MF);
485   O << "\n\n";
486
487   // Print out constants referenced by the function
488   printConstantPool(MF.getConstantPool());
489
490   // Print out labels for the function.
491   O << "\t.text\n";
492   emitAlignment(4);
493   O << "\t.globl\t" << CurrentFnName << "\n";
494   if (!forCygwin && !forDarwin)
495     O << "\t.type\t" << CurrentFnName << ", @function\n";
496   O << CurrentFnName << ":\n";
497
498   // Print out code for the function.
499   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
500        I != E; ++I) {
501     // Print a label for the basic block.
502     if (I->pred_begin() != I->pred_end())
503       O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"
504         << CommentString << " " << I->getBasicBlock()->getName() << "\n";
505     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
506          II != E; ++II) {
507       // Print the assembly for the instruction.
508       O << "\t";
509       printMachineInstruction(II);
510     }
511   }
512
513   // We didn't modify anything.
514   return false;
515 }
516
517 void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) {
518   const MRegisterInfo &RI = *TM.getRegisterInfo();
519   switch (MO.getType()) {
520   case MachineOperand::MO_VirtualRegister:
521   case MachineOperand::MO_MachineRegister:
522     assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
523            "Virtual registers should not make it this far!");
524     O << '%';
525     for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name)
526       O << (char)tolower(*Name);
527     return;
528
529   case MachineOperand::MO_SignExtendedImmed:
530   case MachineOperand::MO_UnextendedImmed:
531     O << '$' << (int)MO.getImmedValue();
532     return;
533   case MachineOperand::MO_MachineBasicBlock: {
534     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
535     O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
536       << "_" << MBBOp->getNumber () << '\t' << CommentString
537       << MBBOp->getBasicBlock ()->getName ();
538     return;
539   }
540   case MachineOperand::MO_PCRelativeDisp:
541     std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs";
542     abort ();
543     return;
544   case MachineOperand::MO_GlobalAddress: {
545     if (!isCallOp) O << '$';
546     O << Mang->getValueName(MO.getGlobal());
547     int Offset = MO.getOffset();
548     if (Offset > 0)
549       O << "+" << Offset;
550     else if (Offset < 0)
551       O << Offset;
552     return;
553   }
554   case MachineOperand::MO_ExternalSymbol:
555     if (!isCallOp) O << '$';
556     O << GlobalPrefix << MO.getSymbolName();
557     return;
558   default:
559     O << "<unknown operand type>"; return;
560   }
561 }
562
563 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){
564   assert(isMem(MI, Op) && "Invalid memory reference!");
565
566   const MachineOperand &BaseReg  = MI->getOperand(Op);
567   int ScaleVal                   = MI->getOperand(Op+1).getImmedValue();
568   const MachineOperand &IndexReg = MI->getOperand(Op+2);
569   const MachineOperand &DispSpec = MI->getOperand(Op+3);
570
571   if (BaseReg.isFrameIndex()) {
572     O << "[frame slot #" << BaseReg.getFrameIndex();
573     if (DispSpec.getImmedValue())
574       O << " + " << DispSpec.getImmedValue();
575     O << "]";
576     return;
577   } else if (BaseReg.isConstantPoolIndex()) {
578     O << ".CPI" << CurrentFnName << "_"
579       << BaseReg.getConstantPoolIndex();
580     if (DispSpec.getImmedValue())
581       O << "+" << DispSpec.getImmedValue();
582     if (IndexReg.getReg()) {
583       O << "(,";
584       printOp(IndexReg);
585       if (ScaleVal != 1)
586         O << "," << ScaleVal;
587       O << ")";
588     }
589     return;
590   }
591
592   if (DispSpec.isGlobalAddress()) {
593     printOp(DispSpec, true);
594   } else {
595     int DispVal = DispSpec.getImmedValue();
596     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
597       O << DispVal;
598   }
599
600   if (IndexReg.getReg() || BaseReg.getReg()) {
601     O << "(";
602     if (BaseReg.getReg())
603       printOp(BaseReg);
604
605     if (IndexReg.getReg()) {
606       O << ",";
607       printOp(IndexReg);
608       if (ScaleVal != 1)
609         O << "," << ScaleVal;
610     }
611
612     O << ")";
613   }
614 }
615
616
617 /// printMachineInstruction -- Print out a single X86 LLVM instruction
618 /// MI in Intel syntax to the current output stream.
619 ///
620 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
621   ++EmittedInsts;
622   // Call the autogenerated instruction printer routines.
623   printInstruction(MI);
624 }
625
626
627 /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code
628 /// for a MachineFunction to the given output stream, using the given target
629 /// machine description.
630 ///
631 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
632   switch (AsmWriterFlavor) {
633   default:
634     assert(0 && "Unknown asm flavor!");
635   case intel:
636     return new X86IntelAsmPrinter(o, tm);
637   case att:
638     return new X86ATTAsmPrinter(o, tm);
639   }
640 }