diff options
Diffstat (limited to 'lib/Target/X86/X86AsmPrinter.cpp')
-rw-r--r-- | lib/Target/X86/X86AsmPrinter.cpp | 646 |
1 files changed, 89 insertions, 557 deletions
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index bcc0a0cb5d..a5b82b5a77 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to Intel assembly -------===// +//===-- X86AsmPrinter.cpp - Convert X86 LLVM IR to X86 assembly -----------===// // // The LLVM Compiler Infrastructure // @@ -7,98 +7,62 @@ // //===----------------------------------------------------------------------===// // -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to Intel and AT&T format assembly -// language. This printer is the output mechanism used by `llc' and `lli -// -print-machineinstrs' on X86. +// This file the shared super class printer that converts from our internal +// representation of machine-dependent LLVM code to Intel and AT&T format +// assembly language. +// This printer is the output mechanism used by `llc'. // //===----------------------------------------------------------------------===// +#include "X86ATTAsmPrinter.h" +#include "X86IntelAsmPrinter.h" #include "X86.h" -#include "X86TargetMachine.h" #include "llvm/Module.h" -#include "llvm/Type.h" #include "llvm/Assembly/Writer.h" -#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/CommandLine.h" using namespace llvm; +using namespace x86; -namespace { - Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - enum AsmWriterFlavor { att, intel }; +Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - cl::opt<AsmWriterFlavor> - AsmWriterFlavor("x86-asm-syntax", - cl::desc("Choose style of code to emit from X86 backend:"), - cl::values( - clEnumVal(att, " Emit AT&T-style assembly"), - clEnumVal(intel, " Emit Intel-style assembly"), - clEnumValEnd), - cl::init(att)); +enum AsmWriterFlavorTy { att, intel }; +cl::opt<AsmWriterFlavorTy> +AsmWriterFlavor("x86-asm-syntax", + cl::desc("Choose style of code to emit from X86 backend:"), + cl::values( + clEnumVal(att, " Emit AT&T-style assembly"), + clEnumVal(intel, " Emit Intel-style assembly"), + clEnumValEnd), + cl::init(att)); - struct X86SharedAsmPrinter : public AsmPrinter { - X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { } - - bool doInitialization(Module &M); - void printConstantPool(MachineConstantPool *MCP); - bool doFinalization(Module &M); - bool forCygwin; - bool forDarwin; - }; -} - -static bool isScale(const MachineOperand &MO) { - return MO.isImmediate() && - (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || - MO.getImmedValue() == 4 || MO.getImmedValue() == 8); -} - -static bool isMem(const MachineInstr *MI, unsigned Op) { - if (MI->getOperand(Op).isFrameIndex()) return true; - if (MI->getOperand(Op).isConstantPoolIndex()) return true; - return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate() || - MI->getOperand(Op+3).isGlobalAddress()); -} - -// SwitchSection - Switch to the specified section of the executable if we are -// not already in it! -// -static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } -} - -/// doInitialization - determine +/// doInitialization bool X86SharedAsmPrinter::doInitialization(Module& M) { + bool leadingUnderscore = false; + forCygwin = false; const std::string& TT = M.getTargetTriple(); if (TT.length() > 5) { forCygwin = TT.find("cygwin") != std::string::npos || TT.find("mingw") != std::string::npos; forDarwin = TT.find("darwin") != std::string::npos; } else if (TT.empty()) { -#if defined(__CYGWIN__) || defined(__MINGW32__) + #if defined(__CYGWIN__) || defined(__MINGW32__) forCygwin = true; -#elif defined(__MACOSX__) + #elif defined(__MACOSX__) forDarwin = true; -#endif + #elif defined(_WIN32) + leadingUnderscore = true; + #else + leadingUnderscore = false; + #endif } - if (forCygwin || forDarwin) + if (leadingUnderscore || forCygwin || forDarwin) GlobalPrefix = "_"; + if (forDarwin) AlignmentIsInBytes = false; + return AsmPrinter::doInitialization(M); } @@ -128,502 +92,70 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) { // Print out module-level global variables here. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) - if (I->hasInitializer()) { // External global require no code - O << "\n\n"; - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignmentShift(C->getType()); - - if (C->isNullValue() && - (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || - I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(O, CurSection, ".data"); - if (!forCygwin && I->hasInternalLinkage()) - O << "\t.local " << name << "\n"; - - O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()); - if (!forCygwin) - O << "," << (1 << Align); - O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << "\n"; - } else { - switch (I->getLinkage()) { - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - SwitchSection(O, CurSection, ""); - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.globl " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - if (C->isNullValue()) - SwitchSection(O, CurSection, ".bss"); - else - SwitchSection(O, CurSection, ".data"); - break; - case GlobalValue::GhostLinkage: - std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; - abort(); - } - - emitAlignment(Align); - if (!forCygwin && !forDarwin) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - } - O << name << ":\t\t\t\t# "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; - emitGlobalConstant(C); - } + if (I->hasInitializer()) { // External global require no code + O << "\n\n"; + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD.getTypeSize(C->getType()); + unsigned Align = TD.getTypeAlignmentShift(C->getType()); + + if (C->isNullValue() && + (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || + I->hasWeakLinkage() /* FIXME: Verify correct */)) { + SwitchSection(O, CurSection, ".data"); + if (!forCygwin && I->hasInternalLinkage()) + O << "\t.local " << name << "\n"; + O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()); + if (!forCygwin) + O << "," << (1 << Align); + O << "\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << "\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + SwitchSection(O, CurSection, ""); + O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.globl " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (C->isNullValue()) + SwitchSection(O, CurSection, ".bss"); + else + SwitchSection(O, CurSection, ".data"); + break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage cannot appear in X86AsmPrinter!\n"; + abort(); + } + + emitAlignment(Align); + if (!forCygwin && !forDarwin) { + O << "\t.type " << name << ",@object\n"; + O << "\t.size " << name << "," << Size << "\n"; + } + O << name << ":\t\t\t\t# "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + emitGlobalConstant(C); + } } AsmPrinter::doFinalization(M); return false; // success } -namespace { - struct X86IntelAsmPrinter : public X86SharedAsmPrinter { - X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) - : X86SharedAsmPrinter(O, TM) { } - - virtual const char *getPassName() const { - return "X86 Intel-Style Assembly Printer"; - } - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - // This method is used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ - const MachineOperand &MO = MI->getOperand(OpNo); - if (MO.getType() == MachineOperand::MO_MachineRegister) { - assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physref??"); - // Bug Workaround: See note in Printer::doInitialization about %. - O << "%" << TM.getRegisterInfo()->get(MO.getReg()).Name; - } else { - printOp(MO); - } - } - - void printCallOperand(const MachineInstr *MI, unsigned OpNo, - MVT::ValueType VT) { - printOp(MI->getOperand(OpNo), true); // Don't print "OFFSET". - } - - void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, - MVT::ValueType VT) { - switch (VT) { - default: assert(0 && "Unknown arg size!"); - case MVT::i8: O << "BYTE PTR "; break; - case MVT::i16: O << "WORD PTR "; break; - case MVT::i32: - case MVT::f32: O << "DWORD PTR "; break; - case MVT::i64: - case MVT::f64: O << "QWORD PTR "; break; - case MVT::f80: O << "XWORD PTR "; break; - } - printMemReference(MI, OpNo); - } - - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, bool elideOffsetKeyword = false); - void printMemReference(const MachineInstr *MI, unsigned Op); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - }; -} // end of anonymous namespace - - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter1.inc" - - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - setupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - printConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - O << "\t.text\n"; - emitAlignment(4); - O << "\t.globl\t" << CurrentFnName << "\n"; - if (!forCygwin && !forDarwin) - O << "\t.type\t" << CurrentFnName << ", @function\n"; - O << CurrentFnName << ":\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block if there are any predecessors. - if (I->pred_begin() != I->pred_end()) - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(II); - } - } - - // We didn't modify anything. - return false; -} - -void X86IntelAsmPrinter::printOp(const MachineOperand &MO, - bool elideOffsetKeyword /* = false */) { - const MRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - if (Value *V = MO.getVRegValueOrNull()) { - O << "<" << V->getName() << ">"; - return; - } - // FALLTHROUGH - case MachineOperand::MO_MachineRegister: - if (MRegisterInfo::isPhysicalRegister(MO.getReg())) - // Bug Workaround: See note in Printer::doInitialization about %. - O << "%" << RI.get(MO.getReg()).Name; - else - O << "%reg" << MO.getReg(); - return; - - case MachineOperand::MO_SignExtendedImmed: - case MachineOperand::MO_UnextendedImmed: - O << (int)MO.getImmedValue(); - return; - case MachineOperand::MO_MachineBasicBlock: { - MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) - << "_" << MBBOp->getNumber () << '\t' << CommentString - << MBBOp->getBasicBlock ()->getName (); - return; - } - case MachineOperand::MO_PCRelativeDisp: - std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; - abort (); - return; - case MachineOperand::MO_GlobalAddress: { - if (!elideOffsetKeyword) - O << "OFFSET "; - O << Mang->getValueName(MO.getGlobal()); - int Offset = MO.getOffset(); - if (Offset > 0) - O << " + " << Offset; - else if (Offset < 0) - O << " - " << -Offset; - return; - } - case MachineOperand::MO_ExternalSymbol: - O << GlobalPrefix << MO.getSymbolName(); - return; - default: - O << "<unknown operand type>"; return; - } -} - -void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ - assert(isMem(MI, Op) && "Invalid memory reference!"); - - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImmedValue(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - if (BaseReg.isFrameIndex()) { - O << "[frame slot #" << BaseReg.getFrameIndex(); - if (DispSpec.getImmedValue()) - O << " + " << DispSpec.getImmedValue(); - O << "]"; - return; - } else if (BaseReg.isConstantPoolIndex()) { - O << "[.CPI" << CurrentFnName << "_" - << BaseReg.getConstantPoolIndex(); - - if (IndexReg.getReg()) { - O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg); - } - - if (DispSpec.getImmedValue()) - O << " + " << DispSpec.getImmedValue(); - O << "]"; - return; - } - - O << "["; - bool NeedPlus = false; - if (BaseReg.getReg()) { - printOp(BaseReg, true); - NeedPlus = true; - } - - if (IndexReg.getReg()) { - if (NeedPlus) O << " + "; - if (ScaleVal != 1) - O << ScaleVal << "*"; - printOp(IndexReg); - NeedPlus = true; - } - - if (DispSpec.isGlobalAddress()) { - if (NeedPlus) - O << " + "; - printOp(DispSpec, true); - } else { - int DispVal = DispSpec.getImmedValue(); - if (DispVal || (!BaseReg.getReg() && !IndexReg.getReg())) { - if (NeedPlus) - if (DispVal > 0) - O << " + "; - else { - O << " - "; - DispVal = -DispVal; - } - O << DispVal; - } - } - O << "]"; -} - - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - -bool X86IntelAsmPrinter::doInitialization(Module &M) { - AsmPrinter::doInitialization(M); - // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly. - // - // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an - // instruction as a reference to the register named sp, and if you try to - // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased - // before being looked up in the symbol table. This creates spurious - // `undefined symbol' errors when linking. Workaround: Do not use `noprefix' - // mode, and decorate all register names with percent signs. - O << "\t.intel_syntax\n"; - return false; -} - - - -namespace { - struct X86ATTAsmPrinter : public X86SharedAsmPrinter { - X86ATTAsmPrinter(std::ostream &O, TargetMachine &TM) - : X86SharedAsmPrinter(O, TM) { } - - virtual const char *getPassName() const { - return "X86 AT&T-Style Assembly Printer"; - } - - /// printInstruction - This method is automatically generated by tablegen - /// from the instruction set description. This method returns true if the - /// machine instruction was sufficiently described to print it, otherwise it - /// returns false. - bool printInstruction(const MachineInstr *MI); - - // This method is used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ - printOp(MI->getOperand(OpNo)); - } - - void printCallOperand(const MachineInstr *MI, unsigned OpNo, - MVT::ValueType VT) { - printOp(MI->getOperand(OpNo), true); // Don't print '$' prefix. - } - - void printMemoryOperand(const MachineInstr *MI, unsigned OpNo, - MVT::ValueType VT) { - printMemReference(MI, OpNo); - } - - void printMachineInstruction(const MachineInstr *MI); - void printOp(const MachineOperand &MO, bool isCallOperand = false); - void printMemReference(const MachineInstr *MI, unsigned Op); - bool runOnMachineFunction(MachineFunction &F); - }; -} // end of anonymous namespace - - -// Include the auto-generated portion of the assembly writer. -#include "X86GenAsmWriter.inc" - - -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - setupMachineFunction(MF); - O << "\n\n"; - - // Print out constants referenced by the function - printConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - O << "\t.text\n"; - emitAlignment(4); - O << "\t.globl\t" << CurrentFnName << "\n"; - if (!forCygwin && !forDarwin) - O << "\t.type\t" << CurrentFnName << ", @function\n"; - O << CurrentFnName << ":\n"; - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (I->pred_begin() != I->pred_end()) - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(II); - } - } - - // We didn't modify anything. - return false; -} - -void X86ATTAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp) { - const MRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { - case MachineOperand::MO_VirtualRegister: - case MachineOperand::MO_MachineRegister: - assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && - "Virtual registers should not make it this far!"); - O << '%'; - for (const char *Name = RI.get(MO.getReg()).Name; *Name; ++Name) - O << (char)tolower(*Name); - return; - - case MachineOperand::MO_SignExtendedImmed: - case MachineOperand::MO_UnextendedImmed: - O << '$' << (int)MO.getImmedValue(); - return; - case MachineOperand::MO_MachineBasicBlock: { - MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) - << "_" << MBBOp->getNumber () << '\t' << CommentString - << MBBOp->getBasicBlock ()->getName (); - return; - } - case MachineOperand::MO_PCRelativeDisp: - std::cerr << "Shouldn't use addPCDisp() when building X86 MachineInstrs"; - abort (); - return; - case MachineOperand::MO_GlobalAddress: { - if (!isCallOp) O << '$'; - O << Mang->getValueName(MO.getGlobal()); - int Offset = MO.getOffset(); - if (Offset > 0) - O << "+" << Offset; - else if (Offset < 0) - O << Offset; - return; - } - case MachineOperand::MO_ExternalSymbol: - if (!isCallOp) O << '$'; - O << GlobalPrefix << MO.getSymbolName(); - return; - default: - O << "<unknown operand type>"; return; - } -} - -void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ - assert(isMem(MI, Op) && "Invalid memory reference!"); - - const MachineOperand &BaseReg = MI->getOperand(Op); - int ScaleVal = MI->getOperand(Op+1).getImmedValue(); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - if (BaseReg.isFrameIndex()) { - O << "[frame slot #" << BaseReg.getFrameIndex(); - if (DispSpec.getImmedValue()) - O << " + " << DispSpec.getImmedValue(); - O << "]"; - return; - } else if (BaseReg.isConstantPoolIndex()) { - O << ".CPI" << CurrentFnName << "_" - << BaseReg.getConstantPoolIndex(); - if (DispSpec.getImmedValue()) - O << "+" << DispSpec.getImmedValue(); - if (IndexReg.getReg()) { - O << "(,"; - printOp(IndexReg); - if (ScaleVal != 1) - O << "," << ScaleVal; - O << ")"; - } - return; - } - - if (DispSpec.isGlobalAddress()) { - printOp(DispSpec, true); - } else { - int DispVal = DispSpec.getImmedValue(); - if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) - O << DispVal; - } - - if (IndexReg.getReg() || BaseReg.getReg()) { - O << "("; - if (BaseReg.getReg()) - printOp(BaseReg); - - if (IndexReg.getReg()) { - O << ","; - printOp(IndexReg); - if (ScaleVal != 1) - O << "," << ScaleVal; - } - - O << ")"; - } -} - - -/// printMachineInstruction -- Print out a single X86 LLVM instruction -/// MI in Intel syntax to the current output stream. -/// -void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; - // Call the autogenerated instruction printer routines. - printInstruction(MI); -} - - /// createX86CodePrinterPass - Returns a pass that prints the X86 assembly code /// for a MachineFunction to the given output stream, using the given target /// machine description. |