diff options
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/AsmPrinter/X86MCInstLower.cpp | 4 | ||||
-rw-r--r-- | lib/Target/X86/README.txt | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86CodeEmitter.cpp | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86FloatingPoint.cpp | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86FloatingPointRegKill.cpp | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 23 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 32 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 15 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 31 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFPStack.td | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.h | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 43 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrMMX.td | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrSSE.td | 64 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.cpp | 3 |
16 files changed, 166 insertions, 82 deletions
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp index d498c57f4c97..24787a8c8404 100644 --- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp @@ -329,6 +329,10 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { case MachineOperand::MO_ConstantPoolIndex: MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); break; + case MachineOperand::MO_BlockAddress: + MCOp = LowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol( + MO.getBlockAddress())); + break; } OutMI.addOperand(MCOp); diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index 046d35ce5b69..9b7aab801eb6 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -1952,3 +1952,5 @@ fact these instructions are identical to the non-lock versions. We need a way to add target specific information to target nodes and have this information carried over to machine instructions. Asm printer (or JIT) can use this information to add the "lock" prefix. + +//===---------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index f942f3f85107..a0bded3aea5e 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -19,6 +19,7 @@ #include "X86TargetMachine.h" #include "X86Relocations.h" #include "X86.h" +#include "llvm/LLVMContext.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/JITCodeEmitter.h" @@ -32,7 +33,6 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -43,7 +43,7 @@ STATISTIC(NumEmitted, "Number of machine instructions emitted"); namespace { template<class CodeEmitter> - class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass { + class Emitter : public MachineFunctionPass { const X86InstrInfo *II; const TargetData *TD; X86TargetMachine &TM; diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index d9a05a83b9e5..a2fe9b095de4 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -40,7 +40,6 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -53,7 +52,7 @@ STATISTIC(NumFXCH, "Number of fxch instructions inserted"); STATISTIC(NumFP , "Number of floating point instructions"); namespace { - struct VISIBILITY_HIDDEN FPS : public MachineFunctionPass { + struct FPS : public MachineFunctionPass { static char ID; FPS() : MachineFunctionPass(&ID) {} diff --git a/lib/Target/X86/X86FloatingPointRegKill.cpp b/lib/Target/X86/X86FloatingPointRegKill.cpp index 3e0385c79c19..34a004534493 100644 --- a/lib/Target/X86/X86FloatingPointRegKill.cpp +++ b/lib/Target/X86/X86FloatingPointRegKill.cpp @@ -22,7 +22,6 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/CFG.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -30,7 +29,7 @@ using namespace llvm; STATISTIC(NumFPKill, "Number of FP_REG_KILL instructions added"); namespace { - struct VISIBILITY_HIDDEN FPRegKiller : public MachineFunctionPass { + struct FPRegKiller : public MachineFunctionPass { static char ID; FPRegKiller() : MachineFunctionPass(&ID) {} diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 5b678fb602dc..122f515249ff 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -33,7 +33,6 @@ #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -72,6 +71,7 @@ namespace { SDValue Segment; GlobalValue *GV; Constant *CP; + BlockAddress *BlockAddr; const char *ES; int JT; unsigned Align; // CP alignment. @@ -79,12 +79,12 @@ namespace { X86ISelAddressMode() : BaseType(RegBase), Scale(1), IndexReg(), Disp(0), - Segment(), GV(0), CP(0), ES(0), JT(-1), Align(0), + Segment(), GV(0), CP(0), BlockAddr(0), ES(0), JT(-1), Align(0), SymbolFlags(X86II::MO_NO_FLAG) { } bool hasSymbolicDisplacement() const { - return GV != 0 || CP != 0 || ES != 0 || JT != -1; + return GV != 0 || CP != 0 || ES != 0 || JT != -1 || BlockAddr != 0; } bool hasBaseOrIndexReg() const { @@ -147,7 +147,7 @@ namespace { /// ISel - X86 specific code to select X86 machine instructions for /// SelectionDAG operations. /// - class VISIBILITY_HIDDEN X86DAGToDAGISel : public SelectionDAGISel { + class X86DAGToDAGISel : public SelectionDAGISel { /// X86Lowering - This object fully describes how to lower LLVM code to an /// X86-specific SelectionDAG. X86TargetLowering &X86Lowering; @@ -242,6 +242,9 @@ namespace { Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags); else if (AM.JT != -1) Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags); + else if (AM.BlockAddr) + Disp = CurDAG->getBlockAddress(AM.BlockAddr, DebugLoc()/*MVT::i32*/, + true /*AM.SymbolFlags*/); else Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32); @@ -761,10 +764,12 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) { } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { AM.ES = S->getSymbol(); AM.SymbolFlags = S->getTargetFlags(); - } else { - JumpTableSDNode *J = cast<JumpTableSDNode>(N0); + } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { AM.JT = J->getIndex(); AM.SymbolFlags = J->getTargetFlags(); + } else { + AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); + //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); } if (N.getOpcode() == X86ISD::WrapperRIP) @@ -790,10 +795,12 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) { } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { AM.ES = S->getSymbol(); AM.SymbolFlags = S->getTargetFlags(); - } else { - JumpTableSDNode *J = cast<JumpTableSDNode>(N0); + } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { AM.JT = J->getIndex(); AM.SymbolFlags = J->getTargetFlags(); + } else { + AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); + //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); } return false; } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e5e7bc8bb757..86ec9f2f17a6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -328,11 +328,13 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) if (Subtarget->is64Bit()) setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom); setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom); + setOperationAction(ISD::BlockAddress , MVT::i32 , Custom); if (Subtarget->is64Bit()) { setOperationAction(ISD::ConstantPool , MVT::i64 , Custom); setOperationAction(ISD::JumpTable , MVT::i64 , Custom); setOperationAction(ISD::GlobalAddress , MVT::i64 , Custom); setOperationAction(ISD::ExternalSymbol, MVT::i64 , Custom); + setOperationAction(ISD::BlockAddress , MVT::i64 , Custom); } // 64-bit addm sub, shl, sra, srl (iff 32-bit x86) setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom); @@ -2310,6 +2312,17 @@ static bool hasFPCMov(unsigned X86CC) { } } +/// isFPImmLegal - Returns true if the target can instruction select the +/// specified FP immediate natively. If false, the legalizer will +/// materialize the FP immediate as a load from a constant pool. +bool X86TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { + for (unsigned i = 0, e = LegalFPImmediates.size(); i != e; ++i) { + if (Imm.bitwiseIsEqual(LegalFPImmediates[i])) + return true; + } + return false; +} + /// isUndefOrInRange - Return true if Val is undef or if its value falls within /// the specified range (L, H]. static bool isUndefOrInRange(int Val, int Low, int Hi) { @@ -4682,6 +4695,24 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) { } SDValue +X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) { + unsigned WrapperKind = X86ISD::Wrapper; + CodeModel::Model M = getTargetMachine().getCodeModel(); + if (Subtarget->isPICStyleRIPRel() && + (M == CodeModel::Small || M == CodeModel::Kernel)) + WrapperKind = X86ISD::WrapperRIP; + + DebugLoc DL = Op.getDebugLoc(); + + BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); + SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); + + Result = DAG.getNode(WrapperKind, DL, getPointerTy(), Result); + + return Result; +} + +SDValue X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl, int64_t Offset, SelectionDAG &DAG) const { @@ -7008,6 +7039,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); + case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::SHL_PARTS: case ISD::SRA_PARTS: case ISD::SRL_PARTS: return LowerShift(Op, DAG); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 66a9107f945c..7b59b81f81a1 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -499,6 +499,11 @@ namespace llvm { /// from i32 to i8 but not from i32 to i16. virtual bool isNarrowingProfitable(EVT VT1, EVT VT2) const; + /// isFPImmLegal - Returns true if the target can instruction select the + /// specified FP immediate natively. If false, the legalizer will + /// materialize the FP immediate as a load from a constant pool. + virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask @@ -584,6 +589,15 @@ namespace llvm { bool X86ScalarSSEf32; bool X86ScalarSSEf64; + /// LegalFPImmediates - A list of legal fp immediates. + std::vector<APFloat> LegalFPImmediates; + + /// addLegalFPImmediate - Indicate that this x86 target can instruction + /// select the specified FP immediate natively. + void addLegalFPImmediate(const APFloat& Imm) { + LegalFPImmediates.push_back(Imm); + } + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, @@ -621,6 +635,7 @@ namespace llvm { SDValue LowerINSERT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG); SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG); SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG); + SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl, int64_t Offset, SelectionDAG &DAG) const; SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index c1b7b8f827ef..3edced7b43e8 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -1541,7 +1541,7 @@ def LOCK_DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), } // Atomic exchange, and, or, xor let Constraints = "$val = $dst", Defs = [EFLAGS], - usesCustomDAGSchedInserter = 1 in { + usesCustomInserter = 1 in { def ATOMAND64 : I<0, Pseudo, (outs GR64:$dst),(ins i64mem:$ptr, GR64:$val), "#ATOMAND64 PSEUDO!", [(set GR64:$dst, (atomic_load_and_64 addr:$ptr, GR64:$val))]>; @@ -1595,6 +1595,8 @@ def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>; def : Pat<(i64 (X86Wrapper texternalsym:$dst)), (MOV64ri texternalsym:$dst)>, Requires<[FarData]>; +def : Pat<(i64 (X86Wrapper tblockaddress:$dst)), + (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>; // In static codegen with small code model, we can get the address of a label // into a register with 'movl'. FIXME: This is a hack, the 'imm' predicate of @@ -1607,6 +1609,8 @@ def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), (MOV64ri64i32 tglobaladdr :$dst)>, Requires<[SmallCode]>; def : Pat<(i64 (X86Wrapper texternalsym:$dst)), (MOV64ri64i32 texternalsym:$dst)>, Requires<[SmallCode]>; +def : Pat<(i64 (X86Wrapper tblockaddress:$dst)), + (MOV64ri64i32 tblockaddress:$dst)>, Requires<[SmallCode]>; // In kernel code model, we can get the address of a label // into a register with 'movq'. FIXME: This is a hack, the 'imm' predicate of @@ -1619,6 +1623,8 @@ def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>; def : Pat<(i64 (X86Wrapper texternalsym:$dst)), (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>; +def : Pat<(i64 (X86Wrapper tblockaddress:$dst)), + (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>; // If we have small model and -static mode, it is safe to store global addresses // directly as immediates. FIXME: This is really a hack, the 'imm' predicate @@ -1635,6 +1641,9 @@ def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst), def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst), (MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[NearData, IsStatic]>; +def : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst), + (MOV64mi32 addr:$dst, tblockaddress:$src)>, + Requires<[NearData, IsStatic]>; // Calls // Direct PC relative function call for small code model. 32-bit displacement @@ -1799,43 +1808,43 @@ def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)), (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD), + (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), x86_subreg_8bit_hi)), x86_subreg_32bit)>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(srl_su GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi)), x86_subreg_16bit)>, Requires<[In64BitMode]>; def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))), (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi)), x86_subreg_32bit)>; def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))), (SUBREG_TO_REG (i64 0), (MOVZX32_NOREXrr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi)), x86_subreg_32bit)>; @@ -1843,18 +1852,18 @@ def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))), def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR64:$src, GR64_ABCD), + (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), x86_subreg_8bit_hi))>; def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), (MOV8mr_NOREX addr:$dst, - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi))>, Requires<[In64BitMode]>; diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td index 7e373730b30a..b0b0409ad2a5 100644 --- a/lib/Target/X86/X86InstrFPStack.td +++ b/lib/Target/X86/X86InstrFPStack.td @@ -69,7 +69,7 @@ def fpimmneg1 : PatLeaf<(fpimm), [{ }]>; // Some 'special' instructions -let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. +let usesCustomInserter = 1 in { // Expanded after instruction selection. def FP32_TO_INT16_IN_MEM : I<0, Pseudo, (outs), (ins i16mem:$dst, RFP32:$src), "##FP32_TO_INT16_IN_MEM PSEUDO!", diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index e8a39d11040a..87bc10d9fe0c 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -2621,7 +2621,8 @@ X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, } unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc, - bool UnfoldLoad, bool UnfoldStore) const { + bool UnfoldLoad, bool UnfoldStore, + unsigned *LoadRegIndex) const { DenseMap<unsigned*, std::pair<unsigned,unsigned> >::iterator I = MemOp2RegOpTable.find((unsigned*)Opc); if (I == MemOp2RegOpTable.end()) @@ -2632,6 +2633,8 @@ unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc, return 0; if (UnfoldStore && !FoldedStore) return 0; + if (LoadRegIndex) + *LoadRegIndex = I->second.second & 0xf; return I->second.first; } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 2237c8be517a..6eb07d55eb30 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -560,9 +560,12 @@ public: /// getOpcodeAfterMemoryUnfold - Returns the opcode of the would be new /// instruction after load / store are unfolded from an instruction of the /// specified opcode. It returns zero if the specified unfolding is not - /// possible. + /// possible. If LoadRegIndex is non-null, it is filled in with the operand + /// index of the operand which will hold the register holding the loaded + /// value. virtual unsigned getOpcodeAfterMemoryUnfold(unsigned Opc, - bool UnfoldLoad, bool UnfoldStore) const; + bool UnfoldLoad, bool UnfoldStore, + unsigned *LoadRegIndex = 0) const; virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; virtual diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 16b2af71f98c..9b82e1e55686 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -524,7 +524,7 @@ def ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), } // x86-64 va_start lowering magic. -let usesCustomDAGSchedInserter = 1 in +let usesCustomInserter = 1 in def VASTART_SAVE_XMM_REGS : I<0, Pseudo, (outs), (ins GR8:$al, @@ -1129,13 +1129,13 @@ let isTwoAddress = 1 in { // Conditional moves let Uses = [EFLAGS] in { -// X86 doesn't have 8-bit conditional moves. Use a customDAGSchedInserter to +// X86 doesn't have 8-bit conditional moves. Use a customInserter to // emit control flow. An alternative to this is to mark i8 SELECT as Promote, // however that requires promoting the operands, and can induce additional // i8 register pressure. Note that CMOV_GR8 is conservatively considered to // clobber EFLAGS, because if one of the operands is zero, the expansion // could involve an xor. -let usesCustomDAGSchedInserter = 1, isTwoAddress = 0, Defs = [EFLAGS] in +let usesCustomInserter = 1, isTwoAddress = 0, Defs = [EFLAGS] in def CMOV_GR8 : I<0, Pseudo, (outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cond), "#CMOV_GR8 PSEUDO!", @@ -3667,7 +3667,7 @@ def LOCK_DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), // Atomic exchange, and, or, xor let Constraints = "$val = $dst", Defs = [EFLAGS], - usesCustomDAGSchedInserter = 1 in { + usesCustomInserter = 1 in { def ATOMAND32 : I<0, Pseudo, (outs GR32:$dst),(ins i32mem:$ptr, GR32:$val), "#ATOMAND32 PSEUDO!", [(set GR32:$dst, (atomic_load_and_32 addr:$ptr, GR32:$val))]>; @@ -3736,7 +3736,7 @@ let Constraints = "$val1 = $dst1, $val2 = $dst2", Defs = [EFLAGS, EAX, EBX, ECX, EDX], Uses = [EAX, EBX, ECX, EDX], mayLoad = 1, mayStore = 1, - usesCustomDAGSchedInserter = 1 in { + usesCustomInserter = 1 in { def ATOMAND6432 : I<0, Pseudo, (outs GR32:$dst1, GR32:$dst2), (ins i64mem:$ptr, GR32:$val1, GR32:$val2), "#ATOMAND6432 PSEUDO!", []>; @@ -3789,6 +3789,7 @@ def : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>; def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>; def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>; def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>; +def : Pat<(i32 (X86Wrapper tblockaddress:$dst)), (MOV32ri tblockaddress:$dst)>; def : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)), (ADD32ri GR32:$src1, tconstpool:$src2)>; @@ -3798,11 +3799,15 @@ def : Pat<(add GR32:$src1, (X86Wrapper tglobaladdr :$src2)), (ADD32ri GR32:$src1, tglobaladdr:$src2)>; def : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)), (ADD32ri GR32:$src1, texternalsym:$src2)>; +def : Pat<(add GR32:$src1, (X86Wrapper tblockaddress:$src2)), + (ADD32ri GR32:$src1, tblockaddress:$src2)>; def : Pat<(store (i32 (X86Wrapper tglobaladdr:$src)), addr:$dst), (MOV32mi addr:$dst, tglobaladdr:$src)>; def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst), (MOV32mi addr:$dst, texternalsym:$src)>; +def : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst), + (MOV32mi addr:$dst, tblockaddress:$src)>; // Calls // tailcall stuff @@ -3964,12 +3969,14 @@ def : Pat<(and GR32:$src1, 0xffff), (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit))>; // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src1, GR32_ABCD), + (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src1, + GR32_ABCD)), x86_subreg_8bit))>, Requires<[In32BitMode]>; // r & (2^8-1) ==> movz def : Pat<(and GR16:$src1, 0xff), - (MOVZX16rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src1, GR16_ABCD), + (MOVZX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src1, + GR16_ABCD)), x86_subreg_8bit))>, Requires<[In32BitMode]>; @@ -3977,11 +3984,13 @@ def : Pat<(and GR16:$src1, 0xff), def : Pat<(sext_inreg GR32:$src, i16), (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit))>; def : Pat<(sext_inreg GR32:$src, i8), - (MOVSX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (MOVSX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, + GR32_ABCD)), x86_subreg_8bit))>, Requires<[In32BitMode]>; def : Pat<(sext_inreg GR16:$src, i8), - (MOVSX16rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (MOVSX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, + GR16_ABCD)), x86_subreg_8bit))>, Requires<[In32BitMode]>; @@ -3989,40 +3998,40 @@ def : Pat<(sext_inreg GR16:$src, i8), def : Pat<(i16 (trunc GR32:$src)), (EXTRACT_SUBREG GR32:$src, x86_subreg_16bit)>; def : Pat<(i8 (trunc GR32:$src)), - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc GR16:$src)), - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit)>, Requires<[In32BitMode]>; // h-register tricks def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))), - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi)>, Requires<[In32BitMode]>; def : Pat<(srl_su GR16:$src, (i8 8)), (EXTRACT_SUBREG (MOVZX32rr8 - (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi)), x86_subreg_16bit)>, Requires<[In32BitMode]>; def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi))>, Requires<[In32BitMode]>; def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR16:$src, GR16_ABCD), + (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), x86_subreg_8bit_hi))>, Requires<[In32BitMode]>; def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), - (MOVZX32rr8 (EXTRACT_SUBREG (COPY_TO_REGCLASS GR32:$src, GR32_ABCD), + (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), x86_subreg_8bit_hi))>, Requires<[In32BitMode]>; diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td index ce76b4e8b11e..500785b99014 100644 --- a/lib/Target/X86/X86InstrMMX.td +++ b/lib/Target/X86/X86InstrMMX.td @@ -706,10 +706,9 @@ def : Pat<(v2i32 (X86pcmpgtd VR64:$src1, VR64:$src2)), def : Pat<(v2i32 (X86pcmpgtd VR64:$src1, (bitconvert (load_mmx addr:$src2)))), (MMX_PCMPGTDrm VR64:$src1, addr:$src2)>; -// CMOV* - Used to implement the SELECT DAG operation. Expanded by the -// scheduler into a branch sequence. -// These are expanded by the scheduler. -let Uses = [EFLAGS], usesCustomDAGSchedInserter = 1 in { +// CMOV* - Used to implement the SELECT DAG operation. Expanded after +// instruction selection into a branch sequence. +let Uses = [EFLAGS], usesCustomInserter = 1 in { def CMOV_V1I64 : I<0, Pseudo, (outs VR64:$dst), (ins VR64:$t, VR64:$f, i8imm:$cond), "#CMOV_V1I64 PSEUDO!", diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index f4e97c9a1714..be242a0e5e54 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -174,7 +174,8 @@ def fp32imm0 : PatLeaf<(f32 fpimm), [{ return N->isExactlyValue(+0.0); }]>; -def PSxLDQ_imm : SDNodeXForm<imm, [{ +// BYTE_imm - Transform bit immediates into byte immediates. +def BYTE_imm : SDNodeXForm<imm, [{ // Transformation function: imm >> 3 return getI32Imm(N->getZExtValue() >> 3); }]>; @@ -298,10 +299,9 @@ def palign : PatFrag<(ops node:$lhs, node:$rhs), // SSE scalar FP Instructions //===----------------------------------------------------------------------===// -// CMOV* - Used to implement the SSE SELECT DAG operation. Expanded by the -// scheduler into a branch sequence. -// These are expanded by the scheduler. -let Uses = [EFLAGS], usesCustomDAGSchedInserter = 1 in { +// CMOV* - Used to implement the SSE SELECT DAG operation. Expanded after +// instruction selection into a branch sequence. +let Uses = [EFLAGS], usesCustomInserter = 1 in { def CMOV_FR32 : I<0, Pseudo, (outs FR32:$dst), (ins FR32:$t, FR32:$f, i8imm:$cond), "#CMOV_FR32 PSEUDO!", @@ -1996,21 +1996,21 @@ let Constraints = "$src1 = $dst", neverHasSideEffects = 1 in { let Predicates = [HasSSE2] in { def : Pat<(int_x86_sse2_psll_dq VR128:$src1, imm:$src2), - (v2i64 (PSLLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2i64 (PSLLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; def : Pat<(int_x86_sse2_psrl_dq VR128:$src1, imm:$src2), - (v2i64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2i64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; def : Pat<(int_x86_sse2_psll_dq_bs VR128:$src1, imm:$src2), (v2i64 (PSLLDQri VR128:$src1, imm:$src2))>; def : Pat<(int_x86_sse2_psrl_dq_bs VR128:$src1, imm:$src2), (v2i64 (PSRLDQri VR128:$src1, imm:$src2))>; def : Pat<(v2f64 (X86fsrl VR128:$src1, i32immSExt8:$src2)), - (v2f64 (PSRLDQri VR128:$src1, (PSxLDQ_imm imm:$src2)))>; + (v2f64 (PSRLDQri VR128:$src1, (BYTE_imm imm:$src2)))>; // Shift up / down and insert zero's. def : Pat<(v2i64 (X86vshl VR128:$src, (i8 imm:$amt))), - (v2i64 (PSLLDQri VR128:$src, (PSxLDQ_imm imm:$amt)))>; + (v2i64 (PSLLDQri VR128:$src, (BYTE_imm imm:$amt)))>; def : Pat<(v2i64 (X86vshr VR128:$src, (i8 imm:$amt))), - (v2i64 (PSRLDQri VR128:$src, (PSxLDQ_imm imm:$amt)))>; + (v2i64 (PSRLDQri VR128:$src, (BYTE_imm imm:$amt)))>; } // Logical @@ -2822,37 +2822,41 @@ let Constraints = "$src1 = $dst" in { def PALIGNR64rr : SS3AI<0x0F, MRMSrcReg, (outs VR64:$dst), (ins VR64:$src1, VR64:$src2, i16imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR64:$dst, - (int_x86_ssse3_palign_r - VR64:$src1, VR64:$src2, - imm:$src3))]>; + []>; def PALIGNR64rm : SS3AI<0x0F, MRMSrcMem, (outs VR64:$dst), (ins VR64:$src1, i64mem:$src2, i16imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR64:$dst, - (int_x86_ssse3_palign_r - VR64:$src1, - (bitconvert (memopv2i32 addr:$src2)), - imm:$src3))]>; + []>; def PALIGNR128rr : SS3AI<0x0F, MRMSrcReg, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i32imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR128:$dst, - (int_x86_ssse3_palign_r_128 - VR128:$src1, VR128:$src2, - imm:$src3))]>, OpSize; + []>, OpSize; def PALIGNR128rm : SS3AI<0x0F, MRMSrcMem, (outs VR128:$dst), (ins VR128:$src1, i128mem:$src2, i32imm:$src3), "palignr\t{$src3, $src2, $dst|$dst, $src2, $src3}", - [(set VR128:$dst, - (int_x86_ssse3_palign_r_128 - VR128:$src1, - (bitconvert (memopv4i32 addr:$src2)), - imm:$src3))]>, OpSize; + []>, OpSize; } // palignr patterns. +def : Pat<(int_x86_ssse3_palign_r VR64:$src1, VR64:$src2, (i16 imm:$src3)), + (PALIGNR64rr VR64:$src1, VR64:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; +def : Pat<(int_x86_ssse3_palign_r VR64:$src1, + (memop64 addr:$src2), + (i16 imm:$src3)), + (PALIGNR64rm VR64:$src1, addr:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; + +def : Pat<(int_x86_ssse3_palign_r_128 VR128:$src1, VR128:$src2, (i32 imm:$src3)), + (PALIGNR128rr VR128:$src1, VR128:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; +def : Pat<(int_x86_ssse3_palign_r_128 VR128:$src1, + (memopv2i64 addr:$src2), + (i32 imm:$src3)), + (PALIGNR128rm VR128:$src1, addr:$src2, (BYTE_imm imm:$src3))>, + Requires<[HasSSSE3]>; + let AddedComplexity = 5 in { def : Pat<(v4i32 (palign:$src3 VR128:$src1, VR128:$src2)), (PALIGNR128rr VR128:$src2, VR128:$src1, @@ -3802,7 +3806,7 @@ let Constraints = "$src1 = $dst" in { } // String/text processing instructions. -let Defs = [EFLAGS], usesCustomDAGSchedInserter = 1 in { +let Defs = [EFLAGS], usesCustomInserter = 1 in { def PCMPISTRM128REG : SS42AI<0, Pseudo, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2, i8imm:$src3), "#PCMPISTRM128rr PSEUDO!", @@ -3830,7 +3834,7 @@ def PCMPISTRM128rm : SS42AI<0x62, MRMSrcMem, (outs), } let Defs = [EFLAGS], Uses = [EAX, EDX], - usesCustomDAGSchedInserter = 1 in { + usesCustomInserter = 1 in { def PCMPESTRM128REG : SS42AI<0, Pseudo, (outs VR128:$dst), (ins VR128:$src1, VR128:$src3, i8imm:$src5), "#PCMPESTRM128rr PSEUDO!", diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index f03723ae3098..c5ff525bdb42 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -38,7 +38,6 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -1473,7 +1472,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, EVT VT, bool High) { #include "X86GenRegisterInfo.inc" namespace { - struct VISIBILITY_HIDDEN MSAC : public MachineFunctionPass { + struct MSAC : public MachineFunctionPass { static char ID; MSAC() : MachineFunctionPass(&ID) {} |