From d6d1cbd692dd519263e30d97d6c4c9e453b5c5d5 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 11 Apr 2006 00:19:04 +0000 Subject: [PATCH] Added support for _mm_move_ss and _mm_move_sd. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27575 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 29 +++++++++++++++++++++++++++-- lib/Target/X86/X86ISelLowering.h | 4 ++++ lib/Target/X86/X86InstrSSE.td | 15 +++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 3daad28b6e7..725dd166a7f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1684,6 +1684,26 @@ bool X86::isUNPCKL_v_undef_Mask(SDNode *N) { return true; } +/// isMOVSMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVS{S|D}. +bool X86::isMOVSMask(SDNode *N) { + assert(N->getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N->getNumOperands(); + if (NumElems != 2 && NumElems != 4) + return false; + + if (!isUndefOrEqual(N->getOperand(0), NumElems)) + return false; + + for (unsigned i = 1; i < NumElems; ++i) { + SDOperand Arg = N->getOperand(i); + if (!isUndefOrEqual(Arg, i)) + return false; + } + + return true; +} /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. @@ -2680,6 +2700,10 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { if (NumElems == 2) return Op; + if (X86::isMOVSMask(PermMask.Val)) + // Leave the VECTOR_SHUFFLE alone. It matches MOVS{S|D}. + return Op; + if (X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKL_v_undef_Mask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) @@ -3106,10 +3130,11 @@ X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { // Only do shuffles on 128-bit vector types for now. if (MVT::getSizeInBits(VT) == 64) return false; return (Mask.Val->getNumOperands() == 2 || - X86::isSplatMask(Mask.Val) || + X86::isSplatMask(Mask.Val) || + X86::isMOVSMask(Mask.Val) || X86::isPSHUFDMask(Mask.Val) || isPSHUFHW_PSHUFLWMask(Mask.Val) || - X86::isSHUFPMask(Mask.Val) || + X86::isSHUFPMask(Mask.Val) || X86::isUNPCKLMask(Mask.Val) || X86::isUNPCKL_v_undef_Mask(Mask.Val) || X86::isUNPCKHMask(Mask.Val)); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 46cb2c8cfdd..e9cf0282ada 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -233,6 +233,10 @@ namespace llvm { /// <0, 0, 1, 1> bool isUNPCKL_v_undef_Mask(SDNode *N); + /// isMOVSMask - Return true if the specified VECTOR_SHUFFLE operand + /// specifies a shuffle of elements that is suitable for input to MOVS{S|D}. + bool isMOVSMask(SDNode *N); + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 6347e627f1a..8a0f567d6a0 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -104,6 +104,10 @@ def MOVLP_shuffle_mask : PatLeaf<(build_vector), [{ return X86::isMOVLPMask(N); }]>; +def MOVS_shuffle_mask : PatLeaf<(build_vector), [{ + return X86::isMOVSMask(N); +}]>; + def UNPCKL_shuffle_mask : PatLeaf<(build_vector), [{ return X86::isUNPCKLMask(N); }]>; @@ -1641,6 +1645,17 @@ def MOVLSD2PDrr : SDI<0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src1, FR64:$src2) "movsd {$src2, $dst|$dst, $src2}", []>; def MOVLDI2PDIrr : PDI<0x6E, MRMSrcReg, (ops VR128:$dst, VR128:$src1, R32:$src2), "movd {$src2, $dst|$dst, $src2}", []>; + +def MOVLPSrr : SSI<0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2), + "movss {$src2, $dst|$dst, $src2}", + [(set VR128:$dst, + (v4f32 (vector_shuffle VR128:$src1, VR128:$src2, + MOVS_shuffle_mask)))]>; +def MOVLPDrr : SDI<0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2), + "movsd {$src2, $dst|$dst, $src2}", + [(set VR128:$dst, + (v2f64 (vector_shuffle VR128:$src1, VR128:$src2, + MOVS_shuffle_mask)))]>; } // Move to lower bits of a VR128 and zeroing upper bits.