diff options
Diffstat (limited to 'contrib/llvm/lib/Target/X86/AsmPrinter')
11 files changed, 275 insertions, 1454 deletions
diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/CMakeLists.txt b/contrib/llvm/lib/Target/X86/AsmPrinter/CMakeLists.txt index b70a587..033973e 100644 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/CMakeLists.txt +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/CMakeLists.txt @@ -2,8 +2,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/ add_llvm_library(LLVMX86AsmPrinter X86ATTInstPrinter.cpp - X86AsmPrinter.cpp X86IntelInstPrinter.cpp - X86MCInstLower.cpp + X86InstComments.cpp ) add_dependencies(LLVMX86AsmPrinter X86CodeGenTable_gen) diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp index f2cdb5b..554b96c 100644 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "asm-printer" #include "X86ATTInstPrinter.h" +#include "X86InstComments.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" @@ -31,6 +32,10 @@ using namespace llvm; void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { printInstruction(MI, OS); + + // If verbose assembly is enabled, we can print some informative comments. + if (CommentStream) + EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); } StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const { return getInstructionName(Opcode); diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h b/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h index 3be4bae..eb98664 100644 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.h @@ -56,6 +56,9 @@ public: void printi128mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { printMemReference(MI, OpNo, O); } + void printi256mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { + printMemReference(MI, OpNo, O); + } void printf32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { printMemReference(MI, OpNo, O); } diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp deleted file mode 100644 index 08e6486..0000000 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ /dev/null @@ -1,680 +0,0 @@ -//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to X86 machine code. -// -//===----------------------------------------------------------------------===// - -#include "X86AsmPrinter.h" -#include "X86ATTInstPrinter.h" -#include "X86IntelInstPrinter.h" -#include "X86MCInstLower.h" -#include "X86.h" -#include "X86COFFMachineModuleInfo.h" -#include "X86MachineFunctionInfo.h" -#include "X86TargetMachine.h" -#include "llvm/CallingConv.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Assembly/Writer.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/CodeGen/MachineModuleInfoImpls.h" -#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" -#include "llvm/Support/COFF.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/ADT/SmallString.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Primitive Helper Functions. -//===----------------------------------------------------------------------===// - -void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream &O) const { - const TargetLowering *TLI = TM.getTargetLowering(); - O << *static_cast<const X86TargetLowering*>(TLI)->getPICBaseSymbol(MF, - OutContext); -} - -/// runOnMachineFunction - Emit the function body. -/// -bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { - SetupMachineFunction(MF); - - if (Subtarget->isTargetCOFF()) { - bool Intrn = MF.getFunction()->hasInternalLinkage(); - OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); - OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC - : COFF::IMAGE_SYM_CLASS_EXTERNAL); - OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION - << COFF::SCT_COMPLEX_TYPE_SHIFT); - OutStreamer.EndCOFFSymbolDef(); - } - - // Have common code print out the function header with linkage info etc. - EmitFunctionHeader(); - - // Emit the rest of the function body. - EmitFunctionBody(); - - // We didn't modify anything. - return false; -} - -/// printSymbolOperand - Print a raw symbol reference operand. This handles -/// jump tables, constant pools, global address and external symbols, all of -/// which print to a label with various suffixes for relocation types etc. -void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO, - raw_ostream &O) { - switch (MO.getType()) { - default: llvm_unreachable("unknown symbol type!"); - case MachineOperand::MO_JumpTableIndex: - O << *GetJTISymbol(MO.getIndex()); - break; - case MachineOperand::MO_ConstantPoolIndex: - O << *GetCPISymbol(MO.getIndex()); - printOffset(MO.getOffset(), O); - break; - case MachineOperand::MO_GlobalAddress: { - const GlobalValue *GV = MO.getGlobal(); - - MCSymbol *GVSym; - if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) - GVSym = GetSymbolWithGlobalValueBase(GV, "$stub"); - else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || - MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) - GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); - else - GVSym = Mang->getSymbol(GV); - - // Handle dllimport linkage. - if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) - GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName()); - - if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { - MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); - MachineModuleInfoImpl::StubValueTy &StubSym = - MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); - if (StubSym.getPointer() == 0) - StubSym = MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); - } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ - MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); - MachineModuleInfoImpl::StubValueTy &StubSym = - MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym); - if (StubSym.getPointer() == 0) - StubSym = MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); - } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); - MachineModuleInfoImpl::StubValueTy &StubSym = - MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); - if (StubSym.getPointer() == 0) - StubSym = MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); - } - - // If the name begins with a dollar-sign, enclose it in parens. We do this - // to avoid having it look like an integer immediate to the assembler. - if (GVSym->getName()[0] != '$') - O << *GVSym; - else - O << '(' << *GVSym << ')'; - printOffset(MO.getOffset(), O); - break; - } - case MachineOperand::MO_ExternalSymbol: { - const MCSymbol *SymToPrint; - if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - SmallString<128> TempNameStr; - TempNameStr += StringRef(MO.getSymbolName()); - TempNameStr += StringRef("$stub"); - - MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); - MachineModuleInfoImpl::StubValueTy &StubSym = - MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); - if (StubSym.getPointer() == 0) { - TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); - StubSym = MachineModuleInfoImpl:: - StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()), - true); - } - SymToPrint = StubSym.getPointer(); - } else { - SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName()); - } - - // If the name begins with a dollar-sign, enclose it in parens. We do this - // to avoid having it look like an integer immediate to the assembler. - if (SymToPrint->getName()[0] != '$') - O << *SymToPrint; - else - O << '(' << *SymToPrint << '('; - break; - } - } - - switch (MO.getTargetFlags()) { - default: - llvm_unreachable("Unknown target flag on GV operand"); - case X86II::MO_NO_FLAG: // No flag. - break; - case X86II::MO_DARWIN_NONLAZY: - case X86II::MO_DLLIMPORT: - case X86II::MO_DARWIN_STUB: - // These affect the name of the symbol, not any suffix. - break; - case X86II::MO_GOT_ABSOLUTE_ADDRESS: - O << " + [.-"; - PrintPICBaseSymbol(O); - O << ']'; - break; - case X86II::MO_PIC_BASE_OFFSET: - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: - case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: - O << '-'; - PrintPICBaseSymbol(O); - break; - case X86II::MO_TLSGD: O << "@TLSGD"; break; - case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; - case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; - case X86II::MO_TPOFF: O << "@TPOFF"; break; - case X86II::MO_NTPOFF: O << "@NTPOFF"; break; - case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; - case X86II::MO_GOT: O << "@GOT"; break; - case X86II::MO_GOTOFF: O << "@GOTOFF"; break; - case X86II::MO_PLT: O << "@PLT"; break; - case X86II::MO_TLVP: O << "@TLVP"; break; - case X86II::MO_TLVP_PIC_BASE: - O << "@TLVP" << '-'; - PrintPICBaseSymbol(O); - break; - } -} - -/// print_pcrel_imm - This is used to print an immediate value that ends up -/// being encoded as a pc-relative value. These print slightly differently, for -/// example, a $ is not emitted. -void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: llvm_unreachable("Unknown pcrel immediate operand"); - case MachineOperand::MO_Immediate: - O << MO.getImm(); - return; - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - return; - case MachineOperand::MO_GlobalAddress: - case MachineOperand::MO_ExternalSymbol: - printSymbolOperand(MO, O); - return; - } -} - - -void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, - raw_ostream &O, const char *Modifier) { - const MachineOperand &MO = MI->getOperand(OpNo); - switch (MO.getType()) { - default: llvm_unreachable("unknown operand type!"); - case MachineOperand::MO_Register: { - O << '%'; - unsigned Reg = MO.getReg(); - if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { - EVT VT = (strcmp(Modifier+6,"64") == 0) ? - MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : - ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); - Reg = getX86SubSuperRegister(Reg, VT); - } - O << X86ATTInstPrinter::getRegisterName(Reg); - return; - } - - case MachineOperand::MO_Immediate: - O << '$' << MO.getImm(); - return; - - case MachineOperand::MO_JumpTableIndex: - case MachineOperand::MO_ConstantPoolIndex: - case MachineOperand::MO_GlobalAddress: - case MachineOperand::MO_ExternalSymbol: { - O << '$'; - printSymbolOperand(MO, O); - break; - } - } -} - -void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op, - raw_ostream &O) { - unsigned char value = MI->getOperand(Op).getImm(); - assert(value <= 7 && "Invalid ssecc argument!"); - switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; - } -} - -void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, - raw_ostream &O, const char *Modifier) { - const MachineOperand &BaseReg = MI->getOperand(Op); - const MachineOperand &IndexReg = MI->getOperand(Op+2); - const MachineOperand &DispSpec = MI->getOperand(Op+3); - - // If we really don't want to print out (rip), don't. - bool HasBaseReg = BaseReg.getReg() != 0; - if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && - BaseReg.getReg() == X86::RIP) - HasBaseReg = false; - - // HasParenPart - True if we will print out the () part of the mem ref. - bool HasParenPart = IndexReg.getReg() || HasBaseReg; - - if (DispSpec.isImm()) { - int DispVal = DispSpec.getImm(); - if (DispVal || !HasParenPart) - O << DispVal; - } else { - assert(DispSpec.isGlobal() || DispSpec.isCPI() || - DispSpec.isJTI() || DispSpec.isSymbol()); - printSymbolOperand(MI->getOperand(Op+3), O); - } - - if (HasParenPart) { - assert(IndexReg.getReg() != X86::ESP && - "X86 doesn't allow scaling by ESP"); - - O << '('; - if (HasBaseReg) - printOperand(MI, Op, O, Modifier); - - if (IndexReg.getReg()) { - O << ','; - printOperand(MI, Op+2, O, Modifier); - unsigned ScaleVal = MI->getOperand(Op+1).getImm(); - if (ScaleVal != 1) - O << ',' << ScaleVal; - } - O << ')'; - } -} - -void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, - raw_ostream &O, const char *Modifier) { - assert(isMem(MI, Op) && "Invalid memory reference!"); - const MachineOperand &Segment = MI->getOperand(Op+4); - if (Segment.getReg()) { - printOperand(MI, Op+4, O, Modifier); - O << ':'; - } - printLeaMemReference(MI, Op, O, Modifier); -} - -void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op, - raw_ostream &O) { - PrintPICBaseSymbol(O); - O << '\n'; - PrintPICBaseSymbol(O); - O << ':'; -} - -bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode, - raw_ostream &O) { - unsigned Reg = MO.getReg(); - switch (Mode) { - default: return true; // Unknown mode. - case 'b': // Print QImode register - Reg = getX86SubSuperRegister(Reg, MVT::i8); - break; - case 'h': // Print QImode high register - Reg = getX86SubSuperRegister(Reg, MVT::i8, true); - break; - case 'w': // Print HImode register - Reg = getX86SubSuperRegister(Reg, MVT::i16); - break; - case 'k': // Print SImode register - Reg = getX86SubSuperRegister(Reg, MVT::i32); - break; - case 'q': // Print DImode register - Reg = getX86SubSuperRegister(Reg, MVT::i64); - break; - } - - O << '%' << X86ATTInstPrinter::getRegisterName(Reg); - return false; -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode, raw_ostream &O) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - const MachineOperand &MO = MI->getOperand(OpNo); - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'a': // This is an address. Currently only 'i' and 'r' are expected. - if (MO.isImm()) { - O << MO.getImm(); - return false; - } - if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) { - printSymbolOperand(MO, O); - if (Subtarget->isPICStyleRIPRel()) - O << "(%rip)"; - return false; - } - if (MO.isReg()) { - O << '('; - printOperand(MI, OpNo, O); - O << ')'; - return false; - } - return true; - - case 'c': // Don't print "$" before a global var name or constant. - if (MO.isImm()) - O << MO.getImm(); - else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) - printSymbolOperand(MO, O); - else - printOperand(MI, OpNo, O); - return false; - - case 'A': // Print '*' before a register (it must be a register) - if (MO.isReg()) { - O << '*'; - printOperand(MI, OpNo, O); - return false; - } - return true; - - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print DImode register - if (MO.isReg()) - return printAsmMRegister(MO, ExtraCode[0], O); - printOperand(MI, OpNo, O); - return false; - - case 'P': // This is the operand of a call, treat specially. - print_pcrel_imm(MI, OpNo, O); - return false; - - case 'n': // Negate the immediate or print a '-' before the operand. - // Note: this is a temporary solution. It should be handled target - // independently as part of the 'MC' work. - if (MO.isImm()) { - O << -MO.getImm(); - return false; - } - O << '-'; - } - } - - printOperand(MI, OpNo, O); - return false; -} - -bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, unsigned AsmVariant, - const char *ExtraCode, - raw_ostream &O) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'b': // Print QImode register - case 'h': // Print QImode high register - case 'w': // Print HImode register - case 'k': // Print SImode register - case 'q': // Print SImode register - // These only apply to registers, ignore on mem. - break; - case 'P': // Don't print @PLT, but do print as memory. - printMemReference(MI, OpNo, O, "no-rip"); - return false; - } - } - printMemReference(MI, OpNo, O); - return false; -} - -void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { - if (Subtarget->isTargetDarwin()) - OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); -} - - -void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { - if (Subtarget->isTargetDarwin()) { - // All darwin targets use mach-o. - MachineModuleInfoMachO &MMIMacho = - MMI->getObjFileInfo<MachineModuleInfoMachO>(); - - // Output stubs for dynamically-linked functions. - MachineModuleInfoMachO::SymbolListTy Stubs; - - Stubs = MMIMacho.GetFnStubList(); - if (!Stubs.empty()) { - const MCSection *TheSection = - OutContext.getMachOSection("__IMPORT", "__jump_table", - MCSectionMachO::S_SYMBOL_STUBS | - MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE | - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, - 5, SectionKind::getMetadata()); - OutStreamer.SwitchSection(TheSection); - - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$stub: - OutStreamer.EmitLabel(Stubs[i].first); - // .indirect_symbol _foo - OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(), - MCSA_IndirectSymbol); - // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12. - const char HltInsts[] = { -12, -12, -12, -12, -12 }; - OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/); - } - - Stubs.clear(); - OutStreamer.AddBlankLine(); - } - - // Output stubs for external and common global variables. - Stubs = MMIMacho.GetGVStubList(); - if (!Stubs.empty()) { - const MCSection *TheSection = - OutContext.getMachOSection("__IMPORT", "__pointers", - MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, - SectionKind::getMetadata()); - OutStreamer.SwitchSection(TheSection); - - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$non_lazy_ptr: - OutStreamer.EmitLabel(Stubs[i].first); - // .indirect_symbol _foo - MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; - OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), - MCSA_IndirectSymbol); - // .long 0 - if (MCSym.getInt()) - // External to current translation unit. - OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); - else - // Internal to current translation unit. - // - // When we place the LSDA into the TEXT section, the type info - // pointers need to be indirect and pc-rel. We accomplish this by - // using NLPs. However, sometimes the types are local to the file. So - // we need to fill in the value for the NLP in those cases. - OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), - OutContext), - 4/*size*/, 0/*addrspace*/); - } - Stubs.clear(); - OutStreamer.AddBlankLine(); - } - - Stubs = MMIMacho.GetHiddenGVStubList(); - if (!Stubs.empty()) { - OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); - EmitAlignment(2); - - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$non_lazy_ptr: - OutStreamer.EmitLabel(Stubs[i].first); - // .long _foo - OutStreamer.EmitValue(MCSymbolRefExpr:: - Create(Stubs[i].second.getPointer(), - OutContext), - 4/*size*/, 0/*addrspace*/); - } - Stubs.clear(); - OutStreamer.AddBlankLine(); - } - - // Funny Darwin hack: This flag tells the linker that no global symbols - // contain code that falls through to other global symbols (e.g. the obvious - // implementation of multiple entry points). If this doesn't occur, the - // linker can safely perform dead code stripping. Since LLVM never - // generates code that does this, it is always safe to set. - OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); - } - - if (Subtarget->isTargetCOFF()) { - X86COFFMachineModuleInfo &COFFMMI = - MMI->getObjFileInfo<X86COFFMachineModuleInfo>(); - - // Emit type information for external functions - typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator; - for (externals_iterator I = COFFMMI.externals_begin(), - E = COFFMMI.externals_end(); - I != E; ++I) { - OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); - OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL); - OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION - << COFF::SCT_COMPLEX_TYPE_SHIFT); - OutStreamer.EndCOFFSymbolDef(); - } - - // Necessary for dllexport support - std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals; - - const TargetLoweringObjectFileCOFF &TLOFCOFF = - static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); - - for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasDLLExportLinkage()) - DLLExportedFns.push_back(Mang->getSymbol(I)); - - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) - if (I->hasDLLExportLinkage()) - DLLExportedGlobals.push_back(Mang->getSymbol(I)); - - // Output linker support code for dllexported globals on windows. - if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { - OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); - SmallString<128> name; - for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) { - if (Subtarget->isTargetWindows()) - name = " /EXPORT:"; - else - name = " -export:"; - name += DLLExportedGlobals[i]->getName(); - if (Subtarget->isTargetWindows()) - name += ",DATA"; - else - name += ",data"; - OutStreamer.EmitBytes(name, 0); - } - - for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) { - if (Subtarget->isTargetWindows()) - name = " /EXPORT:"; - else - name = " -export:"; - name += DLLExportedFns[i]->getName(); - OutStreamer.EmitBytes(name, 0); - } - } - } - - if (Subtarget->isTargetELF()) { - const TargetLoweringObjectFileELF &TLOFELF = - static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); - - MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); - - // Output stubs for external and common global variables. - MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); - if (!Stubs.empty()) { - OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); - const TargetData *TD = TM.getTargetData(); - - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - OutStreamer.EmitLabel(Stubs[i].first); - OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), - TD->getPointerSize(), 0); - } - Stubs.clear(); - } - } -} - - -//===----------------------------------------------------------------------===// -// Target Registry Stuff -//===----------------------------------------------------------------------===// - -static MCInstPrinter *createX86MCInstPrinter(const Target &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI) { - if (SyntaxVariant == 0) - return new X86ATTInstPrinter(MAI); - if (SyntaxVariant == 1) - return new X86IntelInstPrinter(MAI); - return 0; -} - -// Force static initialization. -extern "C" void LLVMInitializeX86AsmPrinter() { - RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); - RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); - - TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,createX86MCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,createX86MCInstPrinter); -} diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.h deleted file mode 100644 index b5a7f8d..0000000 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86AsmPrinter.h +++ /dev/null @@ -1,89 +0,0 @@ -//===-- X86AsmPrinter.h - Convert X86 LLVM code to assembly -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// AT&T assembly code printer class. -// -//===----------------------------------------------------------------------===// - -#ifndef X86ASMPRINTER_H -#define X86ASMPRINTER_H - -#include "../X86.h" -#include "../X86MachineFunctionInfo.h" -#include "../X86TargetMachine.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/ValueTypes.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - -class MachineJumpTableInfo; -class MCContext; -class MCInst; -class MCStreamer; -class MCSymbol; - -class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { - const X86Subtarget *Subtarget; - public: - explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer) { - Subtarget = &TM.getSubtarget<X86Subtarget>(); - } - - virtual const char *getPassName() const { - return "X86 AT&T-Style Assembly Printer"; - } - - const X86Subtarget &getSubtarget() const { return *Subtarget; } - - virtual void EmitStartOfAsmFile(Module &M); - - virtual void EmitEndOfAsmFile(Module &M); - - virtual void EmitInstruction(const MachineInstr *MI); - - void printSymbolOperand(const MachineOperand &MO, raw_ostream &O); - - // These methods are used by the tablegen'erated instruction printer. - void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O, - const char *Modifier = 0); - void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); - - bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &OS); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &OS); - - void printMachineInstruction(const MachineInstr *MI); - void printSSECC(const MachineInstr *MI, unsigned Op, raw_ostream &O); - void printMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O, - const char *Modifier=NULL); - void printLeaMemReference(const MachineInstr *MI, unsigned Op, raw_ostream &O, - const char *Modifier=NULL); - - void printPICLabel(const MachineInstr *MI, unsigned Op, raw_ostream &O); - - void PrintPICBaseSymbol(raw_ostream &O) const; - - bool runOnMachineFunction(MachineFunction &F); - - void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); - - MachineLocation getDebugValueLocation(const MachineInstr *MI) const; -}; - -} // end namespace llvm - -#endif diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.cpp b/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.cpp new file mode 100644 index 0000000..da9d5a3 --- /dev/null +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.cpp @@ -0,0 +1,232 @@ +//===-- X86InstComments.cpp - Generate verbose-asm comments for instrs ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines functionality used to emit comments about X86 instructions to +// an output stream for -fverbose-asm. +// +//===----------------------------------------------------------------------===// + +#include "X86InstComments.h" +#include "X86GenInstrNames.inc" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/raw_ostream.h" +#include "../X86ShuffleDecode.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Top Level Entrypoint +//===----------------------------------------------------------------------===// + +/// EmitAnyX86InstComments - This function decodes x86 instructions and prints +/// newline terminated strings to the specified string if desired. This +/// information is shown in disassembly dumps when verbose assembly is enabled. +void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, + const char *(*getRegName)(unsigned)) { + // If this is a shuffle operation, the switch should fill in this state. + SmallVector<unsigned, 8> ShuffleMask; + const char *DestName = 0, *Src1Name = 0, *Src2Name = 0; + + switch (MI->getOpcode()) { + case X86::INSERTPSrr: + Src1Name = getRegName(MI->getOperand(1).getReg()); + Src2Name = getRegName(MI->getOperand(2).getReg()); + DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask); + break; + + case X86::MOVLHPSrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodeMOVLHPSMask(2, ShuffleMask); + break; + + case X86::MOVHLPSrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodeMOVHLPSMask(2, ShuffleMask); + break; + + case X86::PSHUFDri: + Src1Name = getRegName(MI->getOperand(1).getReg()); + // FALL THROUGH. + case X86::PSHUFDmi: + DestName = getRegName(MI->getOperand(0).getReg()); + DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); + break; + + case X86::PSHUFHWri: + Src1Name = getRegName(MI->getOperand(1).getReg()); + // FALL THROUGH. + case X86::PSHUFHWmi: + DestName = getRegName(MI->getOperand(0).getReg()); + DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); + break; + case X86::PSHUFLWri: + Src1Name = getRegName(MI->getOperand(1).getReg()); + // FALL THROUGH. + case X86::PSHUFLWmi: + DestName = getRegName(MI->getOperand(0).getReg()); + DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); + break; + + case X86::PUNPCKHBWrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKHBWrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKHMask(16, ShuffleMask); + break; + case X86::PUNPCKHWDrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKHWDrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKHMask(8, ShuffleMask); + break; + case X86::PUNPCKHDQrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKHDQrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKHMask(4, ShuffleMask); + break; + case X86::PUNPCKHQDQrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKHQDQrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKHMask(2, ShuffleMask); + break; + + case X86::PUNPCKLBWrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKLBWrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKLMask(16, ShuffleMask); + break; + case X86::PUNPCKLWDrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKLWDrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKLMask(8, ShuffleMask); + break; + case X86::PUNPCKLDQrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKLDQrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKLMask(4, ShuffleMask); + break; + case X86::PUNPCKLQDQrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::PUNPCKLQDQrm: + Src1Name = getRegName(MI->getOperand(0).getReg()); + DecodePUNPCKLMask(2, ShuffleMask); + break; + + case X86::SHUFPDrri: + DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + Src2Name = getRegName(MI->getOperand(2).getReg()); + break; + + case X86::SHUFPSrri: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::SHUFPSrmi: + DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + break; + + case X86::UNPCKLPDrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::UNPCKLPDrm: + DecodeUNPCKLPMask(2, ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + break; + case X86::UNPCKLPSrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::UNPCKLPSrm: + DecodeUNPCKLPMask(4, ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + break; + case X86::UNPCKHPDrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::UNPCKHPDrm: + DecodeUNPCKHPMask(2, ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + break; + case X86::UNPCKHPSrr: + Src2Name = getRegName(MI->getOperand(2).getReg()); + // FALL THROUGH. + case X86::UNPCKHPSrm: + DecodeUNPCKHPMask(4, ShuffleMask); + Src1Name = getRegName(MI->getOperand(0).getReg()); + break; + } + + + // If this was a shuffle operation, print the shuffle mask. + if (!ShuffleMask.empty()) { + if (DestName == 0) DestName = Src1Name; + OS << (DestName ? DestName : "mem") << " = "; + + // If the two sources are the same, canonicalize the input elements to be + // from the first src so that we get larger element spans. + if (Src1Name == Src2Name) { + for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) { + if ((int)ShuffleMask[i] >= 0 && // Not sentinel. + ShuffleMask[i] >= e) // From second mask. + ShuffleMask[i] -= e; + } + } + + // The shuffle mask specifies which elements of the src1/src2 fill in the + // destination, with a few sentinel values. Loop through and print them + // out. + for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) { + if (i != 0) + OS << ','; + if (ShuffleMask[i] == SM_SentinelZero) { + OS << "zero"; + continue; + } + + // Otherwise, it must come from src1 or src2. Print the span of elements + // that comes from this src. + bool isSrc1 = ShuffleMask[i] < ShuffleMask.size(); + const char *SrcName = isSrc1 ? Src1Name : Src2Name; + OS << (SrcName ? SrcName : "mem") << '['; + bool IsFirst = true; + while (i != e && + (int)ShuffleMask[i] >= 0 && + (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) { + if (!IsFirst) + OS << ','; + else + IsFirst = false; + OS << ShuffleMask[i] % ShuffleMask.size(); + ++i; + } + OS << ']'; + --i; // For loop increments element #. + } + //MI->print(OS, 0); + OS << "\n"; + } + +} diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.h b/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.h new file mode 100644 index 0000000..6b86db4 --- /dev/null +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86InstComments.h @@ -0,0 +1,25 @@ +//===-- X86InstComments.h - Generate verbose-asm comments for instrs ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines functionality used to emit comments about X86 instructions to +// an output stream for -fverbose-asm. +// +//===----------------------------------------------------------------------===// + +#ifndef X86_INST_COMMENTS_H +#define X86_INST_COMMENTS_H + +namespace llvm { + class MCInst; + class raw_ostream; + void EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS, + const char *(*getRegName)(unsigned)); +} + +#endif diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp index a632047..5625b0e 100644 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "asm-printer" #include "X86IntelInstPrinter.h" +#include "X86InstComments.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" @@ -30,6 +31,10 @@ using namespace llvm; void X86IntelInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { printInstruction(MI, OS); + + // If verbose assembly is enabled, we can print some informative comments. + if (CommentStream) + EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); } StringRef X86IntelInstPrinter::getOpcodeName(unsigned Opcode) const { return getInstructionName(Opcode); diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h b/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h index 4d68074..6f12032 100644 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h +++ b/contrib/llvm/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h @@ -64,6 +64,10 @@ public: O << "XMMWORD PTR "; printMemReference(MI, OpNo, O); } + void printi256mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { + O << "YMMWORD PTR "; + printMemReference(MI, OpNo, O); + } void printf32mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) { O << "DWORD PTR "; printMemReference(MI, OpNo, O); diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp deleted file mode 100644 index e67fc06..0000000 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ /dev/null @@ -1,632 +0,0 @@ -//===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains code to lower X86 MachineInstrs to their corresponding -// MCInst records. -// -//===----------------------------------------------------------------------===// - -#include "X86MCInstLower.h" -#include "X86AsmPrinter.h" -#include "X86COFFMachineModuleInfo.h" -#include "X86MCAsmInfo.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/CodeGen/MachineModuleInfoImpls.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Type.h" -using namespace llvm; - - -const X86Subtarget &X86MCInstLower::getSubtarget() const { - return AsmPrinter.getSubtarget(); -} - -MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const { - assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin"); - return AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoMachO>(); -} - - -MCSymbol *X86MCInstLower::GetPICBaseSymbol() const { - const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering(); - return static_cast<const X86TargetLowering*>(TLI)-> - getPICBaseSymbol(AsmPrinter.MF, Ctx); -} - -/// GetSymbolFromOperand - Lower an MO_GlobalAddress or MO_ExternalSymbol -/// operand to an MCSymbol. -MCSymbol *X86MCInstLower:: -GetSymbolFromOperand(const MachineOperand &MO) const { - assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference"); - - SmallString<128> Name; - - if (!MO.isGlobal()) { - assert(MO.isSymbol()); - Name += AsmPrinter.MAI->getGlobalPrefix(); - Name += MO.getSymbolName(); - } else { - const GlobalValue *GV = MO.getGlobal(); - bool isImplicitlyPrivate = false; - if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || - MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) - isImplicitlyPrivate = true; - - Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); - } - - // If the target flags on the operand changes the name of the symbol, do that - // before we return the symbol. - switch (MO.getTargetFlags()) { - default: break; - case X86II::MO_DLLIMPORT: { - // Handle dllimport linkage. - const char *Prefix = "__imp_"; - Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); - break; - } - case X86II::MO_DARWIN_NONLAZY: - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - - MachineModuleInfoImpl::StubValueTy &StubSym = - getMachOMMI().getGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { - assert(MO.isGlobal() && "Extern symbol not handled yet"); - StubSym = - MachineModuleInfoImpl:: - StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()), - !MO.getGlobal()->hasInternalLinkage()); - } - return Sym; - } - case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - MachineModuleInfoImpl::StubValueTy &StubSym = - getMachOMMI().getHiddenGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { - assert(MO.isGlobal() && "Extern symbol not handled yet"); - StubSym = - MachineModuleInfoImpl:: - StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()), - !MO.getGlobal()->hasInternalLinkage()); - } - return Sym; - } - case X86II::MO_DARWIN_STUB: { - Name += "$stub"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - MachineModuleInfoImpl::StubValueTy &StubSym = - getMachOMMI().getFnStubEntry(Sym); - if (StubSym.getPointer()) - return Sym; - - if (MO.isGlobal()) { - StubSym = - MachineModuleInfoImpl:: - StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()), - !MO.getGlobal()->hasInternalLinkage()); - } else { - Name.erase(Name.end()-5, Name.end()); - StubSym = - MachineModuleInfoImpl:: - StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); - } - return Sym; - } - } - - return Ctx.GetOrCreateSymbol(Name.str()); -} - -MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, - MCSymbol *Sym) const { - // FIXME: We would like an efficient form for this, so we don't have to do a - // lot of extra uniquing. - const MCExpr *Expr = 0; - MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; - - switch (MO.getTargetFlags()) { - default: llvm_unreachable("Unknown target flag on GV operand"); - case X86II::MO_NO_FLAG: // No flag. - // These affect the name of the symbol, not any suffix. - case X86II::MO_DARWIN_NONLAZY: - case X86II::MO_DLLIMPORT: - case X86II::MO_DARWIN_STUB: - break; - - case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break; - case X86II::MO_TLVP_PIC_BASE: - Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx); - // Subtract the pic base. - Expr = MCBinaryExpr::CreateSub(Expr, - MCSymbolRefExpr::Create(GetPICBaseSymbol(), - Ctx), - Ctx); - break; - case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break; - case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break; - case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break; - case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break; - case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break; - case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break; - case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; - case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; - case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; - case X86II::MO_PIC_BASE_OFFSET: - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: - case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: - Expr = MCSymbolRefExpr::Create(Sym, Ctx); - // Subtract the pic base. - Expr = MCBinaryExpr::CreateSub(Expr, - MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx), - Ctx); - if (MO.isJTI() && AsmPrinter.MAI->hasSetDirective()) { - // If .set directive is supported, use it to reduce the number of - // relocations the assembler will generate for differences between - // local labels. This is only safe when the symbols are in the same - // section so we are restricting it to jumptable references. - MCSymbol *Label = Ctx.CreateTempSymbol(); - AsmPrinter.OutStreamer.EmitAssignment(Label, Expr); - Expr = MCSymbolRefExpr::Create(Label, Ctx); - } - break; - } - - if (Expr == 0) - Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); - - if (!MO.isJTI() && MO.getOffset()) - Expr = MCBinaryExpr::CreateAdd(Expr, - MCConstantExpr::Create(MO.getOffset(), Ctx), - Ctx); - return MCOperand::CreateExpr(Expr); -} - - - -static void lower_subreg32(MCInst *MI, unsigned OpNo) { - // Convert registers in the addr mode according to subreg32. - unsigned Reg = MI->getOperand(OpNo).getReg(); - if (Reg != 0) - MI->getOperand(OpNo).setReg(getX86SubSuperRegister(Reg, MVT::i32)); -} - -static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) { - // Convert registers in the addr mode according to subreg64. - for (unsigned i = 0; i != 4; ++i) { - if (!MI->getOperand(OpNo+i).isReg()) continue; - - unsigned Reg = MI->getOperand(OpNo+i).getReg(); - if (Reg == 0) continue; - - MI->getOperand(OpNo+i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); - } -} - -/// LowerSubReg32_Op0 - Things like MOVZX16rr8 -> MOVZX32rr8. -static void LowerSubReg32_Op0(MCInst &OutMI, unsigned NewOpc) { - OutMI.setOpcode(NewOpc); - lower_subreg32(&OutMI, 0); -} -/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R -static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) { - OutMI.setOpcode(NewOpc); - OutMI.addOperand(OutMI.getOperand(0)); - OutMI.addOperand(OutMI.getOperand(0)); -} - -/// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with -/// a short fixed-register form. -static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) { - unsigned ImmOp = Inst.getNumOperands() - 1; - assert(Inst.getOperand(0).isReg() && Inst.getOperand(ImmOp).isImm() && - ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() && - Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) || - Inst.getNumOperands() == 2) && "Unexpected instruction!"); - - // Check whether the destination register can be fixed. - unsigned Reg = Inst.getOperand(0).getReg(); - if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) - return; - - // If so, rewrite the instruction. - MCOperand Saved = Inst.getOperand(ImmOp); - Inst = MCInst(); - Inst.setOpcode(Opcode); - Inst.addOperand(Saved); -} - -/// \brief Simplify things like MOV32rm to MOV32o32a. -static void SimplifyShortMoveForm(MCInst &Inst, unsigned Opcode) { - bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg(); - unsigned AddrBase = IsStore; - unsigned RegOp = IsStore ? 0 : 5; - unsigned AddrOp = AddrBase + 3; - assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() && - Inst.getOperand(AddrBase + 0).isReg() && // base - Inst.getOperand(AddrBase + 1).isImm() && // scale - Inst.getOperand(AddrBase + 2).isReg() && // index register - (Inst.getOperand(AddrOp).isExpr() || // address - Inst.getOperand(AddrOp).isImm())&& - Inst.getOperand(AddrBase + 4).isReg() && // segment - "Unexpected instruction!"); - - // Check whether the destination register can be fixed. - unsigned Reg = Inst.getOperand(RegOp).getReg(); - if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX) - return; - - // Check whether this is an absolute address. - // FIXME: We know TLVP symbol refs aren't, but there should be a better way - // to do this here. - bool Absolute = true; - if (Inst.getOperand(AddrOp).isExpr()) { - const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr(); - if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE)) - if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP) - Absolute = false; - } - - if (Absolute && - (Inst.getOperand(AddrBase + 0).getReg() != 0 || - Inst.getOperand(AddrBase + 2).getReg() != 0 || - Inst.getOperand(AddrBase + 4).getReg() != 0 || - Inst.getOperand(AddrBase + 1).getImm() != 1)) - return; - - // If so, rewrite the instruction. - MCOperand Saved = Inst.getOperand(AddrOp); - Inst = MCInst(); - Inst.setOpcode(Opcode); - Inst.addOperand(Saved); -} - -void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { - OutMI.setOpcode(MI->getOpcode()); - - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - - MCOperand MCOp; - switch (MO.getType()) { - default: - MI->dump(); - llvm_unreachable("unknown operand type"); - case MachineOperand::MO_Register: - // Ignore all implicit register operands. - if (MO.isImplicit()) continue; - MCOp = MCOperand::CreateReg(MO.getReg()); - break; - case MachineOperand::MO_Immediate: - MCOp = MCOperand::CreateImm(MO.getImm()); - break; - case MachineOperand::MO_MachineBasicBlock: - MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( - MO.getMBB()->getSymbol(), Ctx)); - break; - case MachineOperand::MO_GlobalAddress: - MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); - break; - case MachineOperand::MO_ExternalSymbol: - MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO)); - break; - case MachineOperand::MO_JumpTableIndex: - MCOp = LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex())); - break; - case MachineOperand::MO_ConstantPoolIndex: - MCOp = LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex())); - break; - case MachineOperand::MO_BlockAddress: - MCOp = LowerSymbolOperand(MO, - AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress())); - break; - } - - OutMI.addOperand(MCOp); - } - - // Handle a few special cases to eliminate operand modifiers. - switch (OutMI.getOpcode()) { - case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand. - lower_lea64_32mem(&OutMI, 1); - // FALL THROUGH. - case X86::LEA64r: - case X86::LEA16r: - case X86::LEA32r: - // LEA should have a segment register, but it must be empty. - assert(OutMI.getNumOperands() == 1+X86::AddrNumOperands && - "Unexpected # of LEA operands"); - assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 && - "LEA has segment specified!"); - break; - case X86::MOVZX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break; - case X86::MOVZX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break; - case X86::MOVSX16rr8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rr8); break; - case X86::MOVSX16rm8: LowerSubReg32_Op0(OutMI, X86::MOVSX32rm8); break; - case X86::MOVZX64rr32: LowerSubReg32_Op0(OutMI, X86::MOV32rr); break; - case X86::MOVZX64rm32: LowerSubReg32_Op0(OutMI, X86::MOV32rm); break; - case X86::MOV64ri64i32: LowerSubReg32_Op0(OutMI, X86::MOV32ri); break; - case X86::MOVZX64rr8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr8); break; - case X86::MOVZX64rm8: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm8); break; - case X86::MOVZX64rr16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rr16); break; - case X86::MOVZX64rm16: LowerSubReg32_Op0(OutMI, X86::MOVZX32rm16); break; - case X86::SETB_C8r: LowerUnaryToTwoAddr(OutMI, X86::SBB8rr); break; - case X86::SETB_C16r: LowerUnaryToTwoAddr(OutMI, X86::SBB16rr); break; - case X86::SETB_C32r: LowerUnaryToTwoAddr(OutMI, X86::SBB32rr); break; - case X86::SETB_C64r: LowerUnaryToTwoAddr(OutMI, X86::SBB64rr); break; - case X86::MOV8r0: LowerUnaryToTwoAddr(OutMI, X86::XOR8rr); break; - case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break; - case X86::MMX_V_SET0: LowerUnaryToTwoAddr(OutMI, X86::MMX_PXORrr); break; - case X86::MMX_V_SETALLONES: - LowerUnaryToTwoAddr(OutMI, X86::MMX_PCMPEQDrr); break; - case X86::FsFLD0SS: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; - case X86::FsFLD0SD: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; - case X86::V_SET0PS: LowerUnaryToTwoAddr(OutMI, X86::XORPSrr); break; - case X86::V_SET0PD: LowerUnaryToTwoAddr(OutMI, X86::XORPDrr); break; - case X86::V_SET0PI: LowerUnaryToTwoAddr(OutMI, X86::PXORrr); break; - case X86::V_SETALLONES: LowerUnaryToTwoAddr(OutMI, X86::PCMPEQDrr); break; - - case X86::MOV16r0: - LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV16r0 -> MOV32r0 - LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr - break; - case X86::MOV64r0: - LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0 - LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr - break; - - // TAILJMPr64, CALL64r, CALL64pcrel32 - These instructions have - // register inputs modeled as normal uses instead of implicit uses. As such, - // truncate off all but the first operand (the callee). FIXME: Change isel. - case X86::TAILJMPr64: - case X86::CALL64r: - case X86::CALL64pcrel32: { - unsigned Opcode = OutMI.getOpcode(); - MCOperand Saved = OutMI.getOperand(0); - OutMI = MCInst(); - OutMI.setOpcode(Opcode); - OutMI.addOperand(Saved); - break; - } - - // TAILJMPd, TAILJMPd64 - Lower to the correct jump instructions. - case X86::TAILJMPr: - case X86::TAILJMPd: - case X86::TAILJMPd64: { - unsigned Opcode; - switch (OutMI.getOpcode()) { - default: assert(0 && "Invalid opcode"); - case X86::TAILJMPr: Opcode = X86::JMP32r; break; - case X86::TAILJMPd: - case X86::TAILJMPd64: Opcode = X86::JMP_1; break; - } - - MCOperand Saved = OutMI.getOperand(0); - OutMI = MCInst(); - OutMI.setOpcode(Opcode); - OutMI.addOperand(Saved); - break; - } - - // The assembler backend wants to see branches in their small form and relax - // them to their large form. The JIT can only handle the large form because - // it does not do relaxation. For now, translate the large form to the - // small one here. - case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break; - case X86::JO_4: OutMI.setOpcode(X86::JO_1); break; - case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break; - case X86::JB_4: OutMI.setOpcode(X86::JB_1); break; - case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break; - case X86::JE_4: OutMI.setOpcode(X86::JE_1); break; - case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break; - case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break; - case X86::JA_4: OutMI.setOpcode(X86::JA_1); break; - case X86::JS_4: OutMI.setOpcode(X86::JS_1); break; - case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break; - case X86::JP_4: OutMI.setOpcode(X86::JP_1); break; - case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break; - case X86::JL_4: OutMI.setOpcode(X86::JL_1); break; - case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break; - case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break; - case X86::JG_4: OutMI.setOpcode(X86::JG_1); break; - - // We don't currently select the correct instruction form for instructions - // which have a short %eax, etc. form. Handle this by custom lowering, for - // now. - // - // Note, we are currently not handling the following instructions: - // MOV64ao8, MOV64o8a - // XCHG16ar, XCHG32ar, XCHG64ar - case X86::MOV8mr_NOREX: - case X86::MOV8mr: SimplifyShortMoveForm(OutMI, X86::MOV8ao8); break; - case X86::MOV8rm_NOREX: - case X86::MOV8rm: SimplifyShortMoveForm(OutMI, X86::MOV8o8a); break; - case X86::MOV16mr: SimplifyShortMoveForm(OutMI, X86::MOV16ao16); break; - case X86::MOV16rm: SimplifyShortMoveForm(OutMI, X86::MOV16o16a); break; - case X86::MOV32mr: SimplifyShortMoveForm(OutMI, X86::MOV32ao32); break; - case X86::MOV32rm: SimplifyShortMoveForm(OutMI, X86::MOV32o32a); break; - case X86::MOV64mr: SimplifyShortMoveForm(OutMI, X86::MOV64ao64); break; - case X86::MOV64rm: SimplifyShortMoveForm(OutMI, X86::MOV64o64a); break; - - case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break; - case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break; - case X86::ADC32ri: SimplifyShortImmForm(OutMI, X86::ADC32i32); break; - case X86::ADC64ri32: SimplifyShortImmForm(OutMI, X86::ADC64i32); break; - case X86::ADD8ri: SimplifyShortImmForm(OutMI, X86::ADD8i8); break; - case X86::ADD16ri: SimplifyShortImmForm(OutMI, X86::ADD16i16); break; - case X86::ADD32ri: SimplifyShortImmForm(OutMI, X86::ADD32i32); break; - case X86::ADD64ri32: SimplifyShortImmForm(OutMI, X86::ADD64i32); break; - case X86::AND8ri: SimplifyShortImmForm(OutMI, X86::AND8i8); break; - case X86::AND16ri: SimplifyShortImmForm(OutMI, X86::AND16i16); break; - case X86::AND32ri: SimplifyShortImmForm(OutMI, X86::AND32i32); break; - case X86::AND64ri32: SimplifyShortImmForm(OutMI, X86::AND64i32); break; - case X86::CMP8ri: SimplifyShortImmForm(OutMI, X86::CMP8i8); break; - case X86::CMP16ri: SimplifyShortImmForm(OutMI, X86::CMP16i16); break; - case X86::CMP32ri: SimplifyShortImmForm(OutMI, X86::CMP32i32); break; - case X86::CMP64ri32: SimplifyShortImmForm(OutMI, X86::CMP64i32); break; - case X86::OR8ri: SimplifyShortImmForm(OutMI, X86::OR8i8); break; - case X86::OR16ri: SimplifyShortImmForm(OutMI, X86::OR16i16); break; - case X86::OR32ri: SimplifyShortImmForm(OutMI, X86::OR32i32); break; - case X86::OR64ri32: SimplifyShortImmForm(OutMI, X86::OR64i32); break; - case X86::SBB8ri: SimplifyShortImmForm(OutMI, X86::SBB8i8); break; - case X86::SBB16ri: SimplifyShortImmForm(OutMI, X86::SBB16i16); break; - case X86::SBB32ri: SimplifyShortImmForm(OutMI, X86::SBB32i32); break; - case X86::SBB64ri32: SimplifyShortImmForm(OutMI, X86::SBB64i32); break; - case X86::SUB8ri: SimplifyShortImmForm(OutMI, X86::SUB8i8); break; - case X86::SUB16ri: SimplifyShortImmForm(OutMI, X86::SUB16i16); break; - case X86::SUB32ri: SimplifyShortImmForm(OutMI, X86::SUB32i32); break; - case X86::SUB64ri32: SimplifyShortImmForm(OutMI, X86::SUB64i32); break; - case X86::TEST8ri: SimplifyShortImmForm(OutMI, X86::TEST8i8); break; - case X86::TEST16ri: SimplifyShortImmForm(OutMI, X86::TEST16i16); break; - case X86::TEST32ri: SimplifyShortImmForm(OutMI, X86::TEST32i32); break; - case X86::TEST64ri32: SimplifyShortImmForm(OutMI, X86::TEST64i32); break; - case X86::XOR8ri: SimplifyShortImmForm(OutMI, X86::XOR8i8); break; - case X86::XOR16ri: SimplifyShortImmForm(OutMI, X86::XOR16i16); break; - case X86::XOR32ri: SimplifyShortImmForm(OutMI, X86::XOR32i32); break; - case X86::XOR64ri32: SimplifyShortImmForm(OutMI, X86::XOR64i32); break; - } -} - -void X86AsmPrinter::PrintDebugValueComment(const MachineInstr *MI, - raw_ostream &O) { - // Only the target-dependent form of DBG_VALUE should get here. - // Referencing the offset and metadata as NOps-2 and NOps-1 is - // probably portable to other targets; frame pointer location is not. - unsigned NOps = MI->getNumOperands(); - assert(NOps==7); - O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; - // cast away const; DIetc do not take const operands for some reason. - DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); - if (V.getContext().isSubprogram()) - O << DISubprogram(V.getContext()).getDisplayName() << ":"; - O << V.getName(); - O << " <- "; - // Frame address. Currently handles register +- offset only. - O << '['; - if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg()) - printOperand(MI, 0, O); - else - O << "undef"; - O << '+'; printOperand(MI, 3, O); - O << ']'; - O << "+"; - printOperand(MI, NOps-2, O); -} - -MachineLocation -X86AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { - MachineLocation Location; - assert (MI->getNumOperands() == 7 && "Invalid no. of machine operands!"); - // Frame address. Currently handles register +- offset only. - - if (MI->getOperand(0).isReg() && MI->getOperand(3).isImm()) - Location.set(MI->getOperand(0).getReg(), MI->getOperand(3).getImm()); - return Location; -} - - -void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { - X86MCInstLower MCInstLowering(OutContext, Mang, *this); - switch (MI->getOpcode()) { - case TargetOpcode::DBG_VALUE: - if (isVerbose() && OutStreamer.hasRawTextSupport()) { - std::string TmpStr; - raw_string_ostream OS(TmpStr); - PrintDebugValueComment(MI, OS); - OutStreamer.EmitRawText(StringRef(OS.str())); - } - return; - - case X86::TAILJMPr: - case X86::TAILJMPd: - case X86::TAILJMPd64: - // Lower these as normal, but add some comments. - OutStreamer.AddComment("TAILCALL"); - break; - - case X86::MOVPC32r: { - MCInst TmpInst; - // This is a pseudo op for a two instruction sequence with a label, which - // looks like: - // call "L1$pb" - // "L1$pb": - // popl %esi - - // Emit the call. - MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol(); - TmpInst.setOpcode(X86::CALLpcrel32); - // FIXME: We would like an efficient form for this, so we don't have to do a - // lot of extra uniquing. - TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase, - OutContext))); - OutStreamer.EmitInstruction(TmpInst); - - // Emit the label. - OutStreamer.EmitLabel(PICBase); - - // popl $reg - TmpInst.setOpcode(X86::POP32r); - TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg()); - OutStreamer.EmitInstruction(TmpInst); - return; - } - - case X86::ADD32ri: { - // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri. - if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) - break; - - // Okay, we have something like: - // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) - - // For this, we want to print something like: - // MYGLOBAL + (. - PICBASE) - // However, we can't generate a ".", so just emit a new label here and refer - // to it. - MCSymbol *DotSym = OutContext.CreateTempSymbol(); - OutStreamer.EmitLabel(DotSym); - - // Now that we have emitted the label, lower the complex operand expression. - MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); - - const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); - const MCExpr *PICBase = - MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext); - DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); - - DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), - DotExpr, OutContext); - - MCInst TmpInst; - TmpInst.setOpcode(X86::ADD32ri); - TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); - TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); - TmpInst.addOperand(MCOperand::CreateExpr(DotExpr)); - OutStreamer.EmitInstruction(TmpInst); - return; - } - } - - MCInst TmpInst; - MCInstLowering.Lower(MI, TmpInst); - OutStreamer.EmitInstruction(TmpInst); -} - diff --git a/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.h b/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.h deleted file mode 100644 index 9e5474f..0000000 --- a/contrib/llvm/lib/Target/X86/AsmPrinter/X86MCInstLower.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- X86MCInstLower.h - Lower MachineInstr to MCInst -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef X86_MCINSTLOWER_H -#define X86_MCINSTLOWER_H - -#include "llvm/Support/Compiler.h" - -namespace llvm { - class MCContext; - class MCInst; - class MCOperand; - class MCSymbol; - class MachineInstr; - class MachineModuleInfoMachO; - class MachineOperand; - class Mangler; - class X86AsmPrinter; - class X86Subtarget; - -/// X86MCInstLower - This class is used to lower an MachineInstr into an MCInst. -class LLVM_LIBRARY_VISIBILITY X86MCInstLower { - MCContext &Ctx; - Mangler *Mang; - X86AsmPrinter &AsmPrinter; - - const X86Subtarget &getSubtarget() const; -public: - X86MCInstLower(MCContext &ctx, Mangler *mang, X86AsmPrinter &asmprinter) - : Ctx(ctx), Mang(mang), AsmPrinter(asmprinter) {} - - void Lower(const MachineInstr *MI, MCInst &OutMI) const; - - MCSymbol *GetPICBaseSymbol() const; - - MCSymbol *GetSymbolFromOperand(const MachineOperand &MO) const; - MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; - -private: - MachineModuleInfoMachO &getMachOMMI() const; -}; - -} - -#endif |