diff options
author | ed <ed@FreeBSD.org> | 2009-06-22 08:08:12 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-22 08:08:12 +0000 |
commit | a4c19d68f13cf0a83bc0da53bd6d547fcaf635fe (patch) | |
tree | 86c1bc482baa6c81fc70b8d715153bfa93377186 /lib/Target/X86 | |
parent | db89e312d968c258aba3c79c1c398f5fb19267a3 (diff) | |
download | FreeBSD-src-a4c19d68f13cf0a83bc0da53bd6d547fcaf635fe.zip FreeBSD-src-a4c19d68f13cf0a83bc0da53bd6d547fcaf635fe.tar.gz |
Update LLVM sources to r73879.
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/AsmPrinter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp | 320 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h | 58 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp | 143 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 14 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp | 57 | ||||
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h | 3 | ||||
-rw-r--r-- | lib/Target/X86/README.txt | 45 | ||||
-rw-r--r-- | lib/Target/X86/X86FloatingPoint.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 28 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 33 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 113 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.cpp | 27 | ||||
-rw-r--r-- | lib/Target/X86/X86Subtarget.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetAsmInfo.cpp | 62 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 5 |
18 files changed, 703 insertions, 238 deletions
diff --git a/lib/Target/X86/AsmPrinter/CMakeLists.txt b/lib/Target/X86/AsmPrinter/CMakeLists.txt index dbd03d8..368bcaa 100644 --- a/lib/Target/X86/AsmPrinter/CMakeLists.txt +++ b/lib/Target/X86/AsmPrinter/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/ add_partially_linked_object(LLVMX86AsmPrinter X86ATTAsmPrinter.cpp + X86ATTInstPrinter.cpp X86AsmPrinter.cpp X86IntelAsmPrinter.cpp ) diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index 8afe2ea..60ed4f0 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -26,8 +26,10 @@ #include "llvm/Type.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCInst.h" #include "llvm/CodeGen/DwarfWriter.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetAsmInfo.h" @@ -36,6 +38,9 @@ using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); +static cl::opt<bool> NewAsmPrinter("experimental-asm-printer", + cl::Hidden); + static std::string getPICLabelString(unsigned FnNum, const TargetAsmInfo *TAI, const X86Subtarget* Subtarget) { @@ -266,7 +271,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) { O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; // Emit post-function debug information. - if (TAI->doesSupportDebugInformation()) + if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) DW->EndFunction(&MF); // Print out jump tables referenced by the function. @@ -291,6 +296,136 @@ static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) { return ST->isPICStyleStub() && TM.getRelocationModel() != Reloc::Static; } +/// 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 X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) { + const MachineOperand &MO = MI->getOperand(OpNo); + switch (MO.getType()) { + default: assert(0 && "Unknown pcrel immediate operand"); + case MachineOperand::MO_Immediate: + O << MO.getImm(); + return; + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm); + return; + + case MachineOperand::MO_GlobalAddress: { + const GlobalValue *GV = MO.getGlobal(); + std::string Name = Mang->getValueName(GV); + decorateName(Name, GV); + + bool needCloseParen = false; + if (Name[0] == '$') { + // The name begins with a dollar-sign. In order to avoid having it look + // like an integer immediate to the assembler, enclose it in parens. + O << '('; + needCloseParen = true; + } + + if (shouldPrintStub(TM, Subtarget)) { + // Link-once, declaration, or Weakly-linked global variables need + // non-lazily-resolved stubs + if (GV->isDeclaration() || GV->isWeakForLinker()) { + // Dynamically-resolved functions need a stub for the function. + if (isa<Function>(GV)) { + // Function stubs are no longer needed for Mac OS X 10.5 and up. + if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { + O << Name; + } else { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); + } + } else if (GV->hasHiddenVisibility()) { + if (!GV->isDeclaration() && !GV->hasCommonLinkage()) + // Definition is not definitely in the current translation unit. + O << Name; + else { + HiddenGVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + GVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + if (GV->hasDLLImportLinkage()) + O << "__imp_"; + O << Name; + } + } else { + if (GV->hasDLLImportLinkage()) { + O << "__imp_"; + } + O << Name; + + if (shouldPrintPLT(TM, Subtarget)) { + // Assemble call via PLT for externally visible symbols + if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && + !GV->hasLocalLinkage()) + O << "@PLT"; + } + if (Subtarget->isTargetCygMing() && GV->isDeclaration()) + // Save function name for later type emission + FnStubs.insert(Name); + } + + if (GV->hasExternalWeakLinkage()) + ExtWeakSymbols.insert(GV); + + printOffset(MO.getOffset()); + + if (needCloseParen) + O << ')'; + return; + } + + case MachineOperand::MO_ExternalSymbol: { + bool needCloseParen = false; + std::string Name(TAI->getGlobalPrefix()); + Name += MO.getSymbolName(); + // Print function stub suffix unless it's Mac OS X 10.5 and up. + if (shouldPrintStub(TM, Subtarget) && + !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { + FnStubs.insert(Name); + printSuffixedName(Name, "$stub"); + return; + } + + if (Name[0] == '$') { + // The name begins with a dollar-sign. In order to avoid having it look + // like an integer immediate to the assembler, enclose it in parens. + O << '('; + needCloseParen = true; + } + + O << Name; + + if (shouldPrintPLT(TM, Subtarget)) { + std::string GOTName(TAI->getGlobalPrefix()); + GOTName+="_GLOBAL_OFFSET_TABLE_"; + if (Name == GOTName) + // HACK! Emit extra offset to PC during printing GOT offset to + // compensate for the size of popl instruction. The resulting code + // should look like: + // call .piclabel + // piclabel: + // popl %some_register + // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register + O << " + [.-" + << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']'; + + O << "@PLT"; + } + + if (needCloseParen) + O << ')'; + + return; + } + } +} + void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, const char *Modifier, bool NotRIPRel) { const MachineOperand &MO = MI->getOperand(OpNo); @@ -312,14 +447,10 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, case MachineOperand::MO_Immediate: if (!Modifier || (strcmp(Modifier, "debug") && - strcmp(Modifier, "mem") && - strcmp(Modifier, "call"))) + strcmp(Modifier, "mem"))) O << '$'; O << MO.getImm(); return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm); - return; case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << '$'; @@ -359,8 +490,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, return; } case MachineOperand::MO_GlobalAddress: { - bool isCallOp = Modifier && !strcmp(Modifier, "call"); - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); bool needCloseParen = false; const GlobalValue *GV = MO.getGlobal(); @@ -369,7 +499,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, // If GV is an alias then use the aliasee for determining // thread-localness. if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) - GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false)); + GVar =dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false)); } bool isThreadLocal = GVar && GVar->isThreadLocal(); @@ -377,7 +507,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, std::string Name = Mang->getValueName(GV); decorateName(Name, GV); - if (!isMemOp && !isCallOp) + if (!isMemOp) O << '$'; else if (Name[0] == '$') { // The name begins with a dollar-sign. In order to avoid having it look @@ -391,15 +521,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, // non-lazily-resolved stubs if (GV->isDeclaration() || GV->isWeakForLinker()) { // Dynamically-resolved functions need a stub for the function. - if (isCallOp && isa<Function>(GV)) { - // Function stubs are no longer needed for Mac OS X 10.5 and up. - if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) { - O << Name; - } else { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - } - } else if (GV->hasHiddenVisibility()) { + if (GV->hasHiddenVisibility()) { if (!GV->isDeclaration() && !GV->hasCommonLinkage()) // Definition is not definitely in the current translation unit. O << Name; @@ -417,25 +539,12 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << Name; } - if (!isCallOp && TM.getRelocationModel() == Reloc::PIC_) + if (TM.getRelocationModel() == Reloc::PIC_) O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget); } else { - if (GV->hasDLLImportLinkage()) { + if (GV->hasDLLImportLinkage()) O << "__imp_"; - } O << Name; - - if (isCallOp) { - if (shouldPrintPLT(TM, Subtarget)) { - // Assemble call via PLT for externally visible symbols - if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() && - !GV->hasLocalLinkage()) - O << "@PLT"; - } - if (Subtarget->isTargetCygMing() && GV->isDeclaration()) - // Save function name for later type emission - FnStubs.insert(Name); - } } if (GV->hasExternalWeakLinkage()) @@ -443,6 +552,10 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, printOffset(MO.getOffset()); + if (needCloseParen) + O << ')'; + + bool isRIPRelative = false; if (isThreadLocal) { TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel()); switch (model) { @@ -456,7 +569,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, case TLSModel::InitialExec: if (Subtarget->is64Bit()) { assert (!NotRIPRel); - O << "@GOTTPOFF(%rip)"; + O << "@GOTTPOFF"; + isRIPRelative = true; } else { O << "@INDNTPOFF"; } @@ -476,43 +590,33 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, O << "@GOT"; else O << "@GOTOFF"; - } else if (Subtarget->isPICStyleRIPRel() && !NotRIPRel) { + } else if (Subtarget->isPICStyleRIPRel() && + !NotRIPRel) { if (TM.getRelocationModel() != Reloc::Static) { if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) O << "@GOTPCREL"; - - if (needCloseParen) { - needCloseParen = false; - O << ')'; - } } - - // Use rip when possible to reduce code size, except when - // index or base register are also part of the address. e.g. - // foo(%rip)(%rcx,%rax,4) is not legal - O << "(%rip)"; + + isRIPRelative = true; } } - if (needCloseParen) - O << ')'; - + // Use rip when possible to reduce code size, except when + // index or base register are also part of the address. e.g. + // foo(%rip)(%rcx,%rax,4) is not legal. + if (isRIPRelative) + O << "(%rip)"; + return; } case MachineOperand::MO_ExternalSymbol: { - bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); bool needCloseParen = false; std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); + // Print function stub suffix unless it's Mac OS X 10.5 and up. - if (isCallOp && shouldPrintStub(TM, Subtarget) && - !(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) { - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); - return; - } - if (!isMemOp && !isCallOp) + if (!isMemOp) O << '$'; else if (Name[0] == '$') { // The name begins with a dollar-sign. In order to avoid having it look @@ -536,17 +640,13 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register O << " + [.-" << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']'; - - if (isCallOp) - O << "@PLT"; } if (needCloseParen) O << ')'; - if (!isCallOp && Subtarget->isPICStyleRIPRel()) + if (Subtarget->isPICStyleRIPRel()) O << "(%rip)"; - return; } default: @@ -673,8 +773,7 @@ void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, printBasicBlockLabel(MBB, false, false, false); } -bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, - const char Mode) { +bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) { unsigned Reg = MO.getReg(); switch (Mode) { default: return true; // Unknown mode. @@ -758,38 +857,85 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } +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(i).isReg()) continue; + + unsigned Reg = MI->getOperand(i).getReg(); + if (Reg == 0) continue; + + MI->getOperand(i).setReg(getX86SubSuperRegister(Reg, MVT::i64)); + } +} + /// printMachineInstruction -- Print out a single X86 LLVM instruction MI in /// AT&T syntax to the current output stream. /// void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; + if (NewAsmPrinter) { + if (MI->getOpcode() == TargetInstrInfo::INLINEASM) { + O << "\t"; + printInlineAsm(MI); + return; + } else if (MI->isLabel()) { + printLabel(MI); + return; + } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) { + printDeclare(MI); + return; + } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + printImplicitDef(MI); + return; + } + + O << "NEW: "; + MCInst TmpInst; + + TmpInst.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + + MCOperand MCOp; + if (MO.isReg()) { + MCOp.MakeReg(MO.getReg()); + } else if (MO.isImm()) { + MCOp.MakeImm(MO.getImm()); + } else if (MO.isMBB()) { + MCOp.MakeMBBLabel(getFunctionNumber(), MO.getMBB()->getNumber()); + } else { + assert(0 && "Unimp"); + } + + TmpInst.addOperand(MCOp); + } + + switch (TmpInst.getOpcode()) { + case X86::LEA64_32r: + // Handle the 'subreg rewriting' for the lea64_32mem operand. + lower_lea64_32mem(&TmpInst, 1); + break; + } + + // FIXME: Convert TmpInst. + printInstruction(&TmpInst); + O << "OLD: "; + } + // Call the autogenerated instruction printer routines. printInstruction(MI); } /// doInitialization bool X86ATTAsmPrinter::doInitialization(Module &M) { - - bool Result = AsmPrinter::doInitialization(M); - - if (TAI->doesSupportDebugInformation()) { - // Let PassManager know we need debug information and relay - // the MachineModuleInfo address on to DwarfWriter. - // AsmPrinter::doInitialization did this analysis. + if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) MMI = getAnalysisIfAvailable<MachineModuleInfo>(); - DW = getAnalysisIfAvailable<DwarfWriter>(); - DW->BeginModule(&M, MMI, O, this, TAI); - } - - // Darwin wants symbols to be quoted if they have complex names. - if (Subtarget->isTargetDarwin()) - Mang->setUseQuotes(true); - - return Result; + return AsmPrinter::doInitialization(M); } - void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { const TargetData *TD = TM.getTargetData(); @@ -1040,8 +1186,8 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) { } // Emit final debug information. - DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>(); - DW->EndModule(); + if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) + DW->EndModule(); // 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 @@ -1060,12 +1206,12 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) { } // Emit final debug information. - DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>(); - DW->EndModule(); + if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) + DW->EndModule(); } else if (Subtarget->isTargetELF()) { // Emit final debug information. - DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>(); - DW->EndModule(); + if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling()) + DW->EndModule(); } return AsmPrinter::doFinalization(M); diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h index 5b40e73..68a6bc8 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h @@ -27,16 +27,16 @@ namespace llvm { class MachineJumpTableInfo; +class MCInst; class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { - DwarfWriter *DW; MachineModuleInfo *MMI; const X86Subtarget *Subtarget; public: explicit X86ATTAsmPrinter(raw_ostream &O, X86TargetMachine &TM, const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V) - : AsmPrinter(O, TM, T, OL, V), DW(0), MMI(0) { + : AsmPrinter(O, TM, T, OL, V), MMI(0) { Subtarget = &TM.getSubtarget<X86Subtarget>(); } @@ -63,10 +63,62 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { /// machine instruction was sufficiently described to print it, otherwise it /// returns false. bool printInstruction(const MachineInstr *MI); + + + // New MCInst printing stuff. + bool printInstruction(const MCInst *MI); + + void printOperand(const MCInst *MI, unsigned OpNo, + const char *Modifier = 0, bool NotRIPRel = false); + void printMemReference(const MCInst *MI, unsigned Op); + void printLeaMemReference(const MCInst *MI, unsigned Op); + void printSSECC(const MCInst *MI, unsigned Op); + void printPICLabel(const MCInst *MI, unsigned Op); + void print_pcrel_imm(const MCInst *MI, unsigned OpNo); + + void printi8mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printi16mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printi32mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printi64mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printi128mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printf32mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printf64mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printf80mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printf128mem(const MCInst *MI, unsigned OpNo) { + printMemReference(MI, OpNo); + } + void printlea32mem(const MCInst *MI, unsigned OpNo) { + printLeaMemReference(MI, OpNo); + } + void printlea64mem(const MCInst *MI, unsigned OpNo) { + printLeaMemReference(MI, OpNo); + } + void printlea64_32mem(const MCInst *MI, unsigned OpNo) { + printLeaMemReference(MI, OpNo); + } + + // These methods are used by the tablegen'erated instruction printer. void printOperand(const MachineInstr *MI, unsigned OpNo, const char *Modifier = 0, bool NotRIPRel = false); + void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); void printi8mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } @@ -104,7 +156,7 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { printLeaMemReference(MI, OpNo, "subreg64"); } - bool printAsmMRegister(const MachineOperand &MO, const char Mode); + bool printAsmMRegister(const MachineOperand &MO, char Mode); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp new file mode 100644 index 0000000..9d50edc --- /dev/null +++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp @@ -0,0 +1,143 @@ +//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file includes code for rendering MCInst instances as AT&T-style +// assembly. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "llvm/MC/MCInst.h" +#include "X86ATTAsmPrinter.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +// Include the auto-generated portion of the assembly writer. +#define MachineInstr MCInst +#define NO_ASM_WRITER_BOILERPLATE +#include "X86GenAsmWriter.inc" +#undef MachineInstr + +void X86ATTAsmPrinter::printSSECC(const MCInst *MI, unsigned Op) { + switch (MI->getOperand(Op).getImm()) { + default: assert(0 && "Invalid ssecc argument!"); + 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 X86ATTAsmPrinter::printPICLabel(const MCInst *MI, unsigned Op) { + assert(0 && + "This is only used for MOVPC32r, should lower before asm printing!"); +} + + +/// 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 X86ATTAsmPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) { + const MCOperand &Op = MI->getOperand(OpNo); + + if (Op.isImm()) + O << Op.getImm(); + else if (Op.isMBBLabel()) + // FIXME: Keep in sync with printBasicBlockLabel. printBasicBlockLabel + // should eventually call into this code, not the other way around. + O << TAI->getPrivateGlobalPrefix() << "BB" << Op.getMBBLabelFunction() + << '_' << Op.getMBBLabelBlock(); + else + assert(0 && "Unknown pcrel immediate operand"); +} + + +void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo, + const char *Modifier, bool NotRIPRel) { + assert(Modifier == 0 && "Modifiers should not be used"); + + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + O << '%'; + unsigned Reg = Op.getReg(); +#if 0 + if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { + MVT 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); + } +#endif + O << TRI->getAsmName(Reg); + return; + } else if (Op.isImm()) { + //if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem"))) + O << '$'; + O << Op.getImm(); + return; + } + + O << "<<UNKNOWN OPERAND KIND>>"; +} + +void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) { + bool NotRIPRel = false; + + const MCOperand &BaseReg = MI->getOperand(Op); + const MCOperand &IndexReg = MI->getOperand(Op+2); + const MCOperand &DispSpec = MI->getOperand(Op+3); + + NotRIPRel |= IndexReg.getReg() || BaseReg.getReg(); + if (DispSpec.isImm()) { + int64_t DispVal = DispSpec.getImm(); + if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) + O << DispVal; + } else { + abort(); + //assert(DispSpec.isGlobal() || DispSpec.isCPI() || + // DispSpec.isJTI() || DispSpec.isSymbol()); + //printOperand(MI, Op+3, "mem", NotRIPRel); + } + + if (IndexReg.getReg() || BaseReg.getReg()) { + // There are cases where we can end up with ESP/RSP in the indexreg slot. + // If this happens, swap the base/index register to support assemblers that + // don't work when the index is *SP. + // FIXME: REMOVE THIS. + assert(IndexReg.getReg() != X86::ESP && IndexReg.getReg() != X86::RSP); + + O << '('; + if (BaseReg.getReg()) + printOperand(MI, Op); + + if (IndexReg.getReg()) { + O << ','; + printOperand(MI, Op+2); + unsigned ScaleVal = MI->getOperand(Op+1).getImm(); + if (ScaleVal != 1) + O << ',' << ScaleVal; + } + O << ')'; + } +} + +void X86ATTAsmPrinter::printMemReference(const MCInst *MI, unsigned Op) { + const MCOperand &Segment = MI->getOperand(Op+4); + if (Segment.getReg()) { + printOperand(MI, Op+4); + O << ':'; + } + printLeaMemReference(MI, Op); +} diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index c874849..a39203b 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -29,13 +29,11 @@ FunctionPass *llvm::createX86CodePrinterPass(raw_ostream &o, bool verbose) { const X86Subtarget *Subtarget = &tm.getSubtarget<X86Subtarget>(); - if (Subtarget->isFlavorIntel()) { + if (Subtarget->isFlavorIntel()) return new X86IntelAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose); - } else { - return new X86ATTAsmPrinter(o, tm, tm.getTargetAsmInfo(), - OptLevel, verbose); - } + return new X86ATTAsmPrinter(o, tm, tm.getTargetAsmInfo(), + OptLevel, verbose); } namespace { @@ -48,3 +46,9 @@ namespace { extern "C" int X86AsmPrinterForceLink; int X86AsmPrinterForceLink = 0; + +// Force static initialization when called from +// llvm/InitializeAllAsmPrinters.h +namespace llvm { + void InitializeX86AsmPrinter() { } +} diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp index 6599349..ceae7be 100644 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp @@ -223,9 +223,6 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, case MachineOperand::MO_Immediate: O << MO.getImm(); return; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; case MachineOperand::MO_JumpTableIndex: { bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp) O << "OFFSET "; @@ -243,14 +240,13 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, return; } case MachineOperand::MO_GlobalAddress: { - bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); decorateName(Name, GV); - if (!isMemOp && !isCallOp) O << "OFFSET "; + if (!isMemOp) O << "OFFSET "; if (GV->hasDLLImportLinkage()) { // FIXME: This should be fixed with full support of stdcall & fastcall // CC's @@ -261,8 +257,6 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, return; } case MachineOperand::MO_ExternalSymbol: { - bool isCallOp = Modifier && !strcmp(Modifier, "call"); - if (!isCallOp) O << "OFFSET "; O << TAI->getGlobalPrefix() << MO.getSymbolName(); return; } @@ -271,6 +265,39 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, } } +void X86IntelAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo){ + const MachineOperand &MO = MI->getOperand(OpNo); + switch (MO.getType()) { + default: assert(0 && "Unknown pcrel immediate operand"); + case MachineOperand::MO_Immediate: + O << MO.getImm(); + return; + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMBB()); + return; + + case MachineOperand::MO_GlobalAddress: { + GlobalValue *GV = MO.getGlobal(); + std::string Name = Mang->getValueName(GV); + decorateName(Name, GV); + + if (GV->hasDLLImportLinkage()) { + // FIXME: This should be fixed with full support of stdcall & fastcall + // CC's + O << "__imp_"; + } + O << Name; + printOffset(MO.getOffset()); + return; + } + + case MachineOperand::MO_ExternalSymbol: + O << TAI->getGlobalPrefix() << MO.getSymbolName(); + return; + } +} + + void X86IntelAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, const char *Modifier) { @@ -339,8 +366,8 @@ void X86IntelAsmPrinter::printPICJumpTableSetLabel(unsigned uid, } void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) { - O << "\"L" << getFunctionNumber() << "$pb\"\n"; - O << "\"L" << getFunctionNumber() << "$pb\":"; + O << "L" << getFunctionNumber() << "$pb\n"; + O << "L" << getFunctionNumber() << "$pb:"; } bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, @@ -362,7 +389,7 @@ bool X86IntelAsmPrinter::printAsmMRegister(const MachineOperand &MO, break; } - O << '%' << TRI->getName(Reg); + O << TRI->getName(Reg); return false; } @@ -414,7 +441,7 @@ bool X86IntelAsmPrinter::doInitialization(Module &M) { Mang->markCharUnacceptable('.'); - O << "\t.686\n\t.model flat\n\n"; + O << "\t.686\n\t.MMX\n\t.XMM\n\t.model flat\n\n"; // Emit declarations for external functions. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) @@ -422,7 +449,7 @@ bool X86IntelAsmPrinter::doInitialization(Module &M) { std::string Name = Mang->getValueName(I); decorateName(Name, I); - O << "\textern " ; + O << "\tEXTERN " ; if (I->hasDLLImportLinkage()) { O << "__imp_"; } @@ -436,7 +463,7 @@ bool X86IntelAsmPrinter::doInitialization(Module &M) { if (I->isDeclaration()) { std::string Name = Mang->getValueName(I); - O << "\textern " ; + O << "\tEXTERN " ; if (I->hasDLLImportLinkage()) { O << "__imp_"; } @@ -471,14 +498,14 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: SwitchToDataSection(""); - O << name << "?\tsegment common 'COMMON'\n"; + O << name << "?\tSEGEMNT PARA common 'COMMON'\n"; bCustomSegment = true; // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 // are also available. break; case GlobalValue::AppendingLinkage: SwitchToDataSection(""); - O << name << "?\tsegment public 'DATA'\n"; + O << name << "?\tSEGMENT PARA public 'DATA'\n"; bCustomSegment = true; // FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256 // are also available. diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h index 9520d98..04f2595 100644 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h +++ b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.h @@ -52,6 +52,9 @@ struct VISIBILITY_HIDDEN X86IntelAsmPrinter : public AsmPrinter { printOp(MO, Modifier); } } + + void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo); + void printi8mem(const MachineInstr *MI, unsigned OpNo) { O << "BYTE PTR "; diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index 3796aac..4464878 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -1858,8 +1858,23 @@ Ideal output: setne %al ret -We could do this transformation in instcombine, but it's only clearly -beneficial on platforms with a test instruction. +This should definitely be done in instcombine, canonicalizing the range +condition into a != condition. We get this IR: + +define i32 @a(i32 %x) nounwind readnone { +entry: + %0 = and i32 %x, 127 ; <i32> [#uses=1] + %1 = icmp ugt i32 %0, 31 ; <i1> [#uses=1] + %2 = zext i1 %1 to i32 ; <i32> [#uses=1] + ret i32 %2 +} + +Instcombine prefers to strength reduce relational comparisons to equality +comparisons when possible, this should be another case of that. This could +be handled pretty easily in InstCombiner::visitICmpInstWithInstAndIntCst, but it +looks like InstCombiner::visitICmpInstWithInstAndIntCst should really already +be redesigned to use ComputeMaskedBits and friends. + //===---------------------------------------------------------------------===// Testcase: @@ -1880,20 +1895,40 @@ Ideal output: Testcase: int x(int a) { return (a & 0x80) ? 0x100 : 0; } +int y(int a) { return (a & 0x80) *2; } -Current output: +Current: testl $128, 4(%esp) setne %al movzbl %al, %eax shll $8, %eax ret -Ideal output: +Better: movl 4(%esp), %eax addl %eax, %eax andl $256, %eax ret -We generally want to fold shifted tests of a single bit into a shift+and on x86. +This is another general instcombine transformation that is profitable on all +targets. In LLVM IR, these functions look like this: + +define i32 @x(i32 %a) nounwind readnone { +entry: + %0 = and i32 %a, 128 + %1 = icmp eq i32 %0, 0 + %iftmp.0.0 = select i1 %1, i32 0, i32 256 + ret i32 %iftmp.0.0 +} + +define i32 @y(i32 %a) nounwind readnone { +entry: + %0 = shl i32 %a, 1 + %1 = and i32 %0, 256 + ret i32 %1 +} + +Replacing an icmp+select with a shift should always be considered profitable in +instcombine. //===---------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 0f2fbcc..ed4eb44 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -991,8 +991,13 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &I) { case X86::FpSET_ST0_32: case X86::FpSET_ST0_64: case X86::FpSET_ST0_80: - assert((StackTop == 1 || StackTop == 2) - && "Stack should have one or two element on it to return!"); + // FpSET_ST0_80 is generated by copyRegToReg for both function return + // and inline assembly with the "st" constrain. In the latter case, + // it is possible for FP0 to be alive after this instruction. + if (!MI->killsRegister(X86::FP0)) { + // Duplicate ST0 + duplicateToTop(0, 0, I); + } --StackTop; // "Forget" we have something on the top of stack! break; case X86::FpSET_ST1_32: diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index b003efd..9cedafc 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -167,6 +167,8 @@ namespace { SDValue &Segment); bool SelectLEAAddr(SDValue Op, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp); + bool SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base, + SDValue &Scale, SDValue &Index, SDValue &Disp); bool SelectScalarSSELoad(SDValue Op, SDValue Pred, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, @@ -1293,6 +1295,32 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDValue Op, SDValue N, return false; } +/// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes. +bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base, + SDValue &Scale, SDValue &Index, + SDValue &Disp) { + assert(Op.getOpcode() == X86ISD::TLSADDR); + assert(N.getOpcode() == ISD::TargetGlobalTLSAddress); + const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N); + + X86ISelAddressMode AM; + AM.GV = GA->getGlobal(); + AM.Disp += GA->getOffset(); + AM.Base.Reg = CurDAG->getRegister(0, N.getValueType()); + + if (N.getValueType() == MVT::i32) { + AM.Scale = 1; + AM.IndexReg = CurDAG->getRegister(X86::EBX, MVT::i32); + } else { + AM.IndexReg = CurDAG->getRegister(0, MVT::i64); + } + + SDValue Segment; + getAddressOperands(AM, Base, Scale, Index, Disp, Segment); + return true; +} + + bool X86DAGToDAGISel::TryFoldLoad(SDValue P, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 36e3ab2..8d0ea66 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -788,8 +788,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setOperationAction(ISD::USUBO, MVT::i64, Custom); setOperationAction(ISD::SMULO, MVT::i32, Custom); setOperationAction(ISD::SMULO, MVT::i64, Custom); - setOperationAction(ISD::UMULO, MVT::i32, Custom); - setOperationAction(ISD::UMULO, MVT::i64, Custom); if (!Subtarget->is64Bit()) { // These libcalls are not available in 32-bit. @@ -4439,9 +4437,8 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG, // emit "addl x@ntpoff,%eax" (local exec) or "addl x@indntpoff,%eax" (initial // exec) - SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), - GA->getValueType(0), - GA->getOffset()); + SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), + GA->getOffset()); SDValue Offset = DAG.getNode(X86ISD::Wrapper, dl, PtrVT, TGA); if (model == TLSModel::InitialExec) @@ -8474,6 +8471,14 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op, } } return; + case 'K': + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { + if ((int8_t)C->getSExtValue() == C->getSExtValue()) { + Result = DAG.getTargetConstant(C->getZExtValue(), Op.getValueType()); + break; + } + } + return; case 'N': if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) { if (C->getZExtValue() <= 255) { diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index dc15e4a..063913f 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -19,6 +19,14 @@ // 64-bits but only 32 bits are significant. def i64i32imm : Operand<i64>; + +// 64-bits but only 32 bits are significant, and those bits are treated as being +// pc relative. +def i64i32imm_pcrel : Operand<i64> { + let PrintMethod = "print_pcrel_imm"; +} + + // 64-bits but only 8 bits are significant. def i64i8imm : Operand<i64>; @@ -29,6 +37,7 @@ def lea64mem : Operand<i64> { def lea64_32mem : Operand<i32> { let PrintMethod = "printlea64_32mem"; + let AsmOperandLowerMethod = "lower_lea64_32mem"; let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm); } @@ -39,6 +48,9 @@ def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr", [add, mul, X86mul_imm, shl, or, frameindex, X86Wrapper], []>; +def tls64addr : ComplexPattern<i64, 4, "SelectTLSADDRAddr", + [tglobaltlsaddr], []>; + //===----------------------------------------------------------------------===// // Pattern fragments. // @@ -113,9 +125,9 @@ let isCall = 1 in // NOTE: this pattern doesn't match "X86call imm", because we do not know // that the offset between an arbitrary immediate and the call will fit in // the 32-bit pcrel field that we have. - def CALL64pcrel32 : I<0xE8, RawFrm, - (outs), (ins i64i32imm:$dst, variable_ops), - "call\t${dst:call}", []>, + def CALL64pcrel32 : Ii32<0xE8, RawFrm, + (outs), (ins i64i32imm_pcrel:$dst, variable_ops), + "call\t$dst", []>, Requires<[In64BitMode]>; def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops), "call\t{*}$dst", [(X86call GR64:$dst)]>; @@ -177,6 +189,15 @@ def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>; } +let Defs = [RSP], Uses = [RSP], neverHasSideEffects = 1, mayStore = 1 in { +def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i8imm:$imm), + "push{q}\t$imm", []>; +def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), + "push{q}\t$imm", []>; +def PUSH64i32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), + "push{q}\t$imm", []>; +} + let Defs = [RSP, EFLAGS], Uses = [RSP], mayLoad = 1 in def POPFQ : I<0x9D, RawFrm, (outs), (ins), "popf", []>, REX_W; let Defs = [RSP], Uses = [RSP, EFLAGS], mayStore = 1 in @@ -1312,13 +1333,13 @@ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], Uses = [RSP] in -def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym), +def TLS_addr64 : I<0, Pseudo, (outs), (ins lea64mem:$sym), ".byte\t0x66; " - "leaq\t${sym:mem}(%rip), %rdi; " + "leaq\t$sym(%rip), %rdi; " ".word\t0x6666; " "rex64; " "call\t__tls_get_addr@PLT", - [(X86tlsaddr tglobaltlsaddr:$sym)]>, + [(X86tlsaddr tls64addr:$sym)]>, Requires<[In64BitMode]>; let AddedComplexity = 5 in diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 50ae417..2d8f55f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -163,6 +163,11 @@ def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; // X86 Operand Definitions. // +def i32imm_pcrel : Operand<i32> { + let PrintMethod = "print_pcrel_imm"; +} + + // *mem - Operand definitions for the funky X86 addressing mode operands. // class X86MemOperand<string printMethod> : Operand<iPTR> { @@ -206,8 +211,10 @@ def i16i8imm : Operand<i16>; // 32-bits but only 8 bits are significant. def i32i8imm : Operand<i32>; -// Branch targets have OtherVT type. -def brtarget : Operand<OtherVT>; +// Branch targets have OtherVT type and print as pc-relative values. +def brtarget : Operand<OtherVT> { + let PrintMethod = "print_pcrel_imm"; +} //===----------------------------------------------------------------------===// // X86 Complex Pattern Definitions. @@ -217,6 +224,8 @@ def brtarget : Operand<OtherVT>; def addr : ComplexPattern<iPTR, 5, "SelectAddr", [], []>; def lea32addr : ComplexPattern<i32, 4, "SelectLEAAddr", [add, sub, mul, shl, or, frameindex], []>; +def tls32addr : ComplexPattern<i32, 4, "SelectTLSADDRAddr", + [tglobaltlsaddr], []>; //===----------------------------------------------------------------------===// // X86 Instruction Predicate Definitions. @@ -561,8 +570,9 @@ let isCall = 1 in XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], Uses = [ESP] in { - def CALLpcrel32 : Ii32<0xE8, RawFrm, (outs), (ins i32imm:$dst,variable_ops), - "call\t${dst:call}", []>; + def CALLpcrel32 : Ii32<0xE8, RawFrm, + (outs), (ins i32imm_pcrel:$dst,variable_ops), + "call\t$dst", []>; def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops), "call\t{*}$dst", [(X86call GR32:$dst)]>; def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops), @@ -587,7 +597,7 @@ def TCRETURNri : I<0, Pseudo, (outs), (ins GR32:$dst, i32imm:$offset, variable_o let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in - def TAILJMPd : IBr<0xE9, (ins i32imm:$dst), "jmp\t${dst:call} # TAILCALL", + def TAILJMPd : IBr<0xE9, (ins i32imm_pcrel:$dst), "jmp\t$dst # TAILCALL", []>; let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst # TAILCALL", @@ -611,6 +621,15 @@ let mayStore = 1 in def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>; } +let Defs = [ESP], Uses = [ESP], neverHasSideEffects = 1, mayStore = 1 in { +def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i8imm:$imm), + "push{l}\t$imm", []>; +def PUSH32i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), + "push{l}\t$imm", []>; +def PUSH32i32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), + "push{l}\t$imm", []>; +} + let Defs = [ESP, EFLAGS], Uses = [ESP], mayLoad = 1, neverHasSideEffects=1 in def POPFD : I<0x9D, RawFrm, (outs), (ins), "popf", []>; let Defs = [ESP], Uses = [ESP, EFLAGS], mayStore = 1, neverHasSideEffects=1 in @@ -1726,13 +1745,13 @@ let isTwoAddress = 0 in { let Defs = [EFLAGS] in { let Uses = [CL] in { def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src), - "shl{b}\t{%cl, $dst|$dst, %CL}", + "shl{b}\t{%cl, $dst|$dst, CL}", [(set GR8:$dst, (shl GR8:$src, CL))]>; def SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src), - "shl{w}\t{%cl, $dst|$dst, %CL}", + "shl{w}\t{%cl, $dst|$dst, CL}", [(set GR16:$dst, (shl GR16:$src, CL))]>, OpSize; def SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src), - "shl{l}\t{%cl, $dst|$dst, %CL}", + "shl{l}\t{%cl, $dst|$dst, CL}", [(set GR32:$dst, (shl GR32:$src, CL))]>; } // Uses = [CL] @@ -1753,13 +1772,13 @@ def SHL32ri : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2), let isTwoAddress = 0 in { let Uses = [CL] in { def SHL8mCL : I<0xD2, MRM4m, (outs), (ins i8mem :$dst), - "shl{b}\t{%cl, $dst|$dst, %CL}", + "shl{b}\t{%cl, $dst|$dst, CL}", [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>; def SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst), - "shl{w}\t{%cl, $dst|$dst, %CL}", + "shl{w}\t{%cl, $dst|$dst, CL}", [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize; def SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst), - "shl{l}\t{%cl, $dst|$dst, %CL}", + "shl{l}\t{%cl, $dst|$dst, CL}", [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>; } def SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, i8imm:$src), @@ -1788,13 +1807,13 @@ let isTwoAddress = 0 in { let Uses = [CL] in { def SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src), - "shr{b}\t{%cl, $dst|$dst, %CL}", + "shr{b}\t{%cl, $dst|$dst, CL}", [(set GR8:$dst, (srl GR8:$src, CL))]>; def SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src), - "shr{w}\t{%cl, $dst|$dst, %CL}", + "shr{w}\t{%cl, $dst|$dst, CL}", [(set GR16:$dst, (srl GR16:$src, CL))]>, OpSize; def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src), - "shr{l}\t{%cl, $dst|$dst, %CL}", + "shr{l}\t{%cl, $dst|$dst, CL}", [(set GR32:$dst, (srl GR32:$src, CL))]>; } @@ -1822,14 +1841,14 @@ def SHR32r1 : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1), let isTwoAddress = 0 in { let Uses = [CL] in { def SHR8mCL : I<0xD2, MRM5m, (outs), (ins i8mem :$dst), - "shr{b}\t{%cl, $dst|$dst, %CL}", + "shr{b}\t{%cl, $dst|$dst, CL}", [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>; def SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst), - "shr{w}\t{%cl, $dst|$dst, %CL}", + "shr{w}\t{%cl, $dst|$dst, CL}", [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize; def SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst), - "shr{l}\t{%cl, $dst|$dst, %CL}", + "shr{l}\t{%cl, $dst|$dst, CL}", [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>; } def SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, i8imm:$src), @@ -1857,13 +1876,13 @@ let isTwoAddress = 0 in { let Uses = [CL] in { def SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src), - "sar{b}\t{%cl, $dst|$dst, %CL}", + "sar{b}\t{%cl, $dst|$dst, CL}", [(set GR8:$dst, (sra GR8:$src, CL))]>; def SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src), - "sar{w}\t{%cl, $dst|$dst, %CL}", + "sar{w}\t{%cl, $dst|$dst, CL}", [(set GR16:$dst, (sra GR16:$src, CL))]>, OpSize; def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src), - "sar{l}\t{%cl, $dst|$dst, %CL}", + "sar{l}\t{%cl, $dst|$dst, CL}", [(set GR32:$dst, (sra GR32:$src, CL))]>; } @@ -1892,13 +1911,13 @@ def SAR32r1 : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1), let isTwoAddress = 0 in { let Uses = [CL] in { def SAR8mCL : I<0xD2, MRM7m, (outs), (ins i8mem :$dst), - "sar{b}\t{%cl, $dst|$dst, %CL}", + "sar{b}\t{%cl, $dst|$dst, CL}", [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>; def SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst), - "sar{w}\t{%cl, $dst|$dst, %CL}", + "sar{w}\t{%cl, $dst|$dst, CL}", [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize; def SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst), - "sar{l}\t{%cl, $dst|$dst, %CL}", + "sar{l}\t{%cl, $dst|$dst, CL}", [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>; } def SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, i8imm:$src), @@ -1929,13 +1948,13 @@ let isTwoAddress = 0 in { // FIXME: provide shorter instructions when imm8 == 1 let Uses = [CL] in { def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src), - "rol{b}\t{%cl, $dst|$dst, %CL}", + "rol{b}\t{%cl, $dst|$dst, CL}", [(set GR8:$dst, (rotl GR8:$src, CL))]>; def ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src), - "rol{w}\t{%cl, $dst|$dst, %CL}", + "rol{w}\t{%cl, $dst|$dst, CL}", [(set GR16:$dst, (rotl GR16:$src, CL))]>, OpSize; def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src), - "rol{l}\t{%cl, $dst|$dst, %CL}", + "rol{l}\t{%cl, $dst|$dst, CL}", [(set GR32:$dst, (rotl GR32:$src, CL))]>; } @@ -1963,13 +1982,13 @@ def ROL32r1 : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1), let isTwoAddress = 0 in { let Uses = [CL] in { def ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst), - "rol{b}\t{%cl, $dst|$dst, %CL}", + "rol{b}\t{%cl, $dst|$dst, CL}", [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>; def ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst), - "rol{w}\t{%cl, $dst|$dst, %CL}", + "rol{w}\t{%cl, $dst|$dst, CL}", [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize; def ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst), - "rol{l}\t{%cl, $dst|$dst, %CL}", + "rol{l}\t{%cl, $dst|$dst, CL}", [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>; } def ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, i8imm:$src), @@ -1998,13 +2017,13 @@ let isTwoAddress = 0 in { let Uses = [CL] in { def ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src), - "ror{b}\t{%cl, $dst|$dst, %CL}", + "ror{b}\t{%cl, $dst|$dst, CL}", [(set GR8:$dst, (rotr GR8:$src, CL))]>; def ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src), - "ror{w}\t{%cl, $dst|$dst, %CL}", + "ror{w}\t{%cl, $dst|$dst, CL}", [(set GR16:$dst, (rotr GR16:$src, CL))]>, OpSize; def ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src), - "ror{l}\t{%cl, $dst|$dst, %CL}", + "ror{l}\t{%cl, $dst|$dst, CL}", [(set GR32:$dst, (rotr GR32:$src, CL))]>; } @@ -2032,13 +2051,13 @@ def ROR32r1 : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1), let isTwoAddress = 0 in { let Uses = [CL] in { def ROR8mCL : I<0xD2, MRM1m, (outs), (ins i8mem :$dst), - "ror{b}\t{%cl, $dst|$dst, %CL}", + "ror{b}\t{%cl, $dst|$dst, CL}", [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>; def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst), - "ror{w}\t{%cl, $dst|$dst, %CL}", + "ror{w}\t{%cl, $dst|$dst, CL}", [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize; def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst), - "ror{l}\t{%cl, $dst|$dst, %CL}", + "ror{l}\t{%cl, $dst|$dst, CL}", [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>; } def ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, i8imm:$src), @@ -2070,17 +2089,17 @@ let isTwoAddress = 0 in { // Double shift instructions (generalizations of rotate) let Uses = [CL] in { def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), - "shld{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shld{l}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))]>, TB; def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), - "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))]>, TB; def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), - "shld{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shld{w}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))]>, TB, OpSize; def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), - "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))]>, TB, OpSize; } @@ -2115,11 +2134,11 @@ def SHRD16rri8 : Ii8<0xAC, MRMDestReg, let isTwoAddress = 0 in { let Uses = [CL] in { def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), - "shld{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shld{l}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL), addr:$dst)]>, TB; def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), - "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL), addr:$dst)]>, TB; } @@ -2138,11 +2157,11 @@ let isTwoAddress = 0 in { let Uses = [CL] in { def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), - "shld{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shld{w}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL), addr:$dst)]>, TB, OpSize; def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), - "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}", + "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, CL}", [(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL), addr:$dst)]>, TB, OpSize; } @@ -3095,11 +3114,11 @@ let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], - Uses = [ESP, EBX] in -def TLS_addr32 : I<0, Pseudo, (outs), (ins i32imm:$sym), - "leal\t${sym:mem}(,%ebx,1), %eax; " + Uses = [ESP] in +def TLS_addr32 : I<0, Pseudo, (outs), (ins lea32mem:$sym), + "leal\t$sym, %eax; " "call\t___tls_get_addr@PLT", - [(X86tlsaddr tglobaltlsaddr:$sym)]>, + [(X86tlsaddr tls32addr:$sym)]>, Requires<[In32BitMode]>; let AddedComplexity = 5 in diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index b44c7a6..5d6ef36 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -3027,6 +3027,12 @@ def : Pat<(v4i32 (movlp VR128:$src1, VR128:$src2)), (MOVLPDrr VR128:$src1, VR128:$src2)>, Requires<[HasSSE2]>; } +// vector_shuffle v1, v2 <4, 5, 2, 3> using SHUFPSrri (we prefer movsd, but +// fall back to this for SSE1) +def : Pat<(v4f32 (movlp:$src3 VR128:$src1, (v4f32 VR128:$src2))), + (SHUFPSrri VR128:$src2, VR128:$src1, + (SHUFFLE_get_shuf_imm VR128:$src3))>, Requires<[HasSSE1]>; + // Set lowest element and zero upper elements. let AddedComplexity = 15 in def : Pat<(v2f64 (movl immAllZerosV_bc, VR128:$src)), diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 6c0074e..a2f319f 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -662,6 +662,10 @@ void X86RegisterInfo::emitFrameMoves(MachineFunction &MF, TargetFrameInfo::StackGrowsUp ? TD->getPointerSize() : -TD->getPointerSize()); + MachineLocation FPDst(hasFP(MF) ? FramePtr : StackPtr); + MachineLocation FPSrc(MachineLocation::VirtualFP); + Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); + if (StackSize) { // Show update of SP. if (hasFP(MF)) { @@ -676,7 +680,7 @@ void X86RegisterInfo::emitFrameMoves(MachineFunction &MF, Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); } } else { - //FIXME: Verify & implement for FP + // FIXME: Verify & implement for FP MachineLocation SPDst(StackPtr); MachineLocation SPSrc(StackPtr, stackGrowth); Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); @@ -711,10 +715,6 @@ void X86RegisterInfo::emitFrameMoves(MachineFunction &MF, MachineLocation FPSrc(FramePtr); Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); } - - MachineLocation FPDst(hasFP(MF) ? FramePtr : StackPtr); - MachineLocation FPSrc(MachineLocation::VirtualFP); - Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); } @@ -729,8 +729,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) || !Fn->doesNotThrow() || UnwindTablesMandatory; - DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : - DebugLoc::getUnknownLoc()); + DebugLoc DL; // Prepare for frame info. unsigned FrameLabelId = 0; @@ -822,13 +821,6 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); } - unsigned ReadyLabelId = 0; - if (needsFrameMoves) { - // Mark effective beginning of when frame pointer is ready. - ReadyLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(ReadyLabelId); - } - // Skip the callee-saved push instructions. while (MBBI != MBB.end() && (MBBI->getOpcode() == X86::PUSH32r || @@ -891,8 +883,13 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII); } - if (needsFrameMoves) + if (needsFrameMoves) { + unsigned ReadyLabelId = 0; + // Mark effective beginning of when frame pointer is ready. + ReadyLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(ReadyLabelId); emitFrameMoves(MF, FrameLabelId, ReadyLabelId); + } } void X86RegisterInfo::emitEpilogue(MachineFunction &MF, diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 46476f2..694b0eb 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -173,7 +173,7 @@ public: bool isPICStyleGOT() const { return PICStyle == PICStyles::GOT; } bool isPICStyleStub() const { return PICStyle == PICStyles::Stub; } bool isPICStyleRIPRel() const { return PICStyle == PICStyles::RIPRel; } - bool isPICStyleWinPIC() const { return PICStyle == PICStyles:: WinPIC; } + bool isPICStyleWinPIC() const { return PICStyle == PICStyles::WinPIC; } /// getDarwinVers - Return the darwin version number, 8 = tiger, 9 = leopard. unsigned getDarwinVers() const { return DarwinVers; } diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 5dda5f4..f49ca15 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -44,40 +44,25 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): AlignmentIsInBytes = false; TextAlignFillValue = 0x90; - GlobalPrefix = "_"; + + if (!is64Bit) Data64bitsDirective = 0; // we can't emit a 64-bit unit ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. - PrivateGlobalPrefix = "L"; // Marker for constant pool idxs - LessPrivateGlobalPrefix = "l"; // Marker for some ObjC metadata - BSSSection = 0; // no BSS section. ZeroFillDirective = "\t.zerofill\t"; // Uses .zerofill if (TM.getRelocationModel() != Reloc::Static) ConstantPoolSection = "\t.const_data"; else ConstantPoolSection = "\t.const\n"; - JumpTableDataSection = "\t.const\n"; - CStringSection = "\t.cstring"; - // FIXME: Why don't always use this section? - if (is64Bit) { + // FIXME: Why don't we always use this section? + if (is64Bit) SixteenByteConstantSection = getUnnamedSection("\t.literal16\n", SectionFlags::Mergeable); - } LCOMMDirective = "\t.lcomm\t"; - SwitchToSectionDirective = "\t.section "; - StringConstantPrefix = "\1LC"; // Leopard and above support aligned common symbols. COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9); HasDotTypeDotSizeDirective = false; - HasSingleParameterDotFile = false; NonLocalEHFrameLabel = true; - if (TM.getRelocationModel() == Reloc::Static) { - StaticCtorsSection = ".constructor"; - StaticDtorsSection = ".destructor"; - } else { - StaticCtorsSection = ".mod_init_func"; - StaticDtorsSection = ".mod_term_func"; - } if (is64Bit) { PersonalityPrefix = ""; PersonalitySuffix = "+4@GOTPCREL"; @@ -85,40 +70,18 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): PersonalityPrefix = "L"; PersonalitySuffix = "$non_lazy_ptr"; } - NeedsIndirectEncoding = true; InlineAsmStart = "## InlineAsm Start"; InlineAsmEnd = "## InlineAsm End"; CommentString = "##"; SetDirective = "\t.set"; PCSymbol = "."; UsedDirective = "\t.no_dead_strip\t"; - WeakDefDirective = "\t.weak_definition "; - WeakRefDirective = "\t.weak_reference "; - HiddenDirective = "\t.private_extern "; ProtectedDirective = "\t.globl\t"; - // In non-PIC modes, emit a special label before jump tables so that the - // linker can perform more accurate dead code stripping. - if (TM.getRelocationModel() != Reloc::PIC_) { - // Emit a local label that is preserved until the linker runs. - JumpTableSpecialLabelPrefix = "l"; - } - SupportsDebugInformation = true; - NeedsSet = true; - DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; - DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; - DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; - DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; - DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; - DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; + DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug"; DwarfUsesInlineInfoSection = true; - DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; - DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; - DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; - DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; - DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; // Exceptions handling SupportsExceptionHandling = true; @@ -176,7 +139,7 @@ X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM): DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; - DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; + DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; // Exceptions handling SupportsExceptionHandling = true; @@ -259,7 +222,7 @@ X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM): DwarfLocSection = "\t.section\t.debug_loc,\"dr\""; DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\""; DwarfRangesSection = "\t.section\t.debug_ranges,\"dr\""; - DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\""; + DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\""; } unsigned @@ -340,8 +303,11 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM): GlobalPrefix = "_"; CommentString = ";"; + InlineAsmStart = "; InlineAsm Start"; + InlineAsmEnd = "; InlineAsm End"; + PrivateGlobalPrefix = "$"; - AlignDirective = "\talign\t"; + AlignDirective = "\tALIGN\t"; ZeroDirective = "\tdb\t"; ZeroDirectiveSuffix = " dup(0)"; AsciiDirective = "\tdb\t"; @@ -353,13 +319,15 @@ X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM): HasDotTypeDotSizeDirective = false; HasSingleParameterDotFile = false; + AlignmentIsInBytes = true; + TextSection = getUnnamedSection("_text", SectionFlags::Code); DataSection = getUnnamedSection("_data", SectionFlags::Writeable); JumpTableDataSection = NULL; SwitchToSectionDirective = ""; - TextSectionStartSuffix = "\tsegment 'CODE'"; - DataSectionStartSuffix = "\tsegment 'DATA'"; + TextSectionStartSuffix = "\tSEGMENT PARA 'CODE'"; + DataSectionStartSuffix = "\tSEGMENT PARA 'DATA'"; SectionEndDirectiveSuffix = "\tends\n"; } diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index dfb055f..53c46c3 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -36,6 +36,11 @@ X("x86", "32-bit X86: Pentium-Pro and above"); static RegisterTarget<X86_64TargetMachine> Y("x86-64", "64-bit X86: EM64T and AMD64"); +// Force static initialization when called from llvm/InitializeAllTargets.h +namespace llvm { + void InitializeX86Target() { } +} + // No assembler printer by default X86TargetMachine::AsmPrinterCtorFn X86TargetMachine::AsmPrinterCtor = 0; |