From b067a1e7e68c4446d3512c25d3a5ac55c6dd76f8 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 31 Mar 2006 19:22:53 +0000 Subject: [PATCH] Add support to use pextrw and pinsrw to extract and insert a word element from a 128-bit vector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27304 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 38 ++++++++++++++++++++++++++++-- lib/Target/X86/X86ISelLowering.h | 4 ++++ lib/Target/X86/X86InstrSSE.td | 31 ++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8036066d0f4..cfc6af84ca9 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -255,9 +255,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand); setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand); setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand); - setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); - setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); + setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); } if (Subtarget->hasMMX()) { @@ -316,6 +316,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM) setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v8i16, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4i32, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Custom); + setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v8i16, Custom); + setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Custom); } computeRegisterProperties(); @@ -2657,6 +2659,37 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } + case ISD::EXTRACT_VECTOR_ELT: { + // Transform it so it match pextrw which produces a 32-bit result. + MVT::ValueType VT = Op.getValueType(); + if (MVT::getSizeInBits(VT) == 16) { + MVT::ValueType EVT = (MVT::ValueType)(VT+1); + SDOperand Extract = DAG.getNode(X86ISD::PEXTRW, EVT, + Op.getOperand(0), Op.getOperand(1)); + SDOperand Assert = DAG.getNode(ISD::AssertZext, EVT, Extract, + DAG.getValueType(VT)); + return DAG.getNode(ISD::TRUNCATE, VT, Assert); + } + + return SDOperand(); + } + case ISD::INSERT_VECTOR_ELT: { + // Transform it so it match pinsrw which expects a 16-bit value in a R32 + // as its second argument. + MVT::ValueType VT = Op.getValueType(); + MVT::ValueType BaseVT = MVT::getVectorBaseType(VT); + if (MVT::getSizeInBits(BaseVT) == 16) { + SDOperand N1 = Op.getOperand(1); + SDOperand N2 = Op.getOperand(2); + if (N1.getValueType() != MVT::i32) + N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1); + if (N2.getValueType() != MVT::i32) + N2 = DAG.getConstant(cast(N2)->getValue(), MVT::i32); + return DAG.getNode(ISD::INSERT_VECTOR_ELT, VT, Op.getOperand(0), N1, N2); + } + + return SDOperand(); + } } } @@ -2692,6 +2725,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::Wrapper: return "X86ISD::Wrapper"; case X86ISD::S2VEC: return "X86ISD::S2VEC"; case X86ISD::ZEXT_S2VEC: return "X86ISD::ZEXT_S2VEC"; + case X86ISD::PEXTRW: return "X86ISD::PEXTRW"; } } diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 3bd2b88c6cc..3f8ec844f4d 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -153,6 +153,10 @@ namespace llvm { /// ZEXT_S2VEC - SCALAR_TO_VECTOR with zero extension. The destination base /// does not have to match the operand type. ZEXT_S2VEC, + + /// PEXTRW - Extract a 16-bit value from a vector and zero extend it to + /// i32, corresponds to X86::PINSRW. + PEXTRW, }; // X86 specific condition code. These correspond to X86_*_COND in diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 2245a2218fa..38158a24f4b 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -28,8 +28,8 @@ def X86s2vec : SDNode<"X86ISD::S2VEC", def X86zexts2vec : SDNode<"X86ISD::ZEXT_S2VEC", SDTypeProfile<1, 1, []>, []>; -def SDTUnpckl : SDTypeProfile<1, 2, - [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; +def X86pextrw : SDNode<"X86ISD::PEXTRW", + SDTypeProfile<1, 2, []>, []>; //===----------------------------------------------------------------------===// // SSE pattern fragments @@ -1409,6 +1409,33 @@ def PUNPCKHQDQrm : PDI<0x6D, MRMSrcMem, UNPCKH_shuffle_mask)))]>; } +// Extract / Insert +def PEXTRWrr : PDIi8<0xC5, MRMSrcReg, + (ops R32:$dst, VR128:$src1, i32i8imm:$src2), + "pextrw {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R32:$dst, (X86pextrw (v8i16 VR128:$src1), + (i32 imm:$src2)))]>; +def PEXTRWrm : PDIi8<0xC5, MRMSrcMem, + (ops R32:$dst, i128mem:$src1, i32i8imm:$src2), + "pextrw {$src2, $src1, $dst|$dst, $src1, $src2}", + [(set R32:$dst, (X86pextrw (loadv8i16 addr:$src1), + (i32 imm:$src2)))]>; + +let isTwoAddress = 1 in { +def PINSRWrr : PDIi8<0xC4, MRMSrcReg, + (ops VR128:$dst, VR128:$src1, R32:$src2, i32i8imm:$src3), + "pinsrw {$src3, $src2, $dst|$dst, $src2, $src3}", + [(set VR128:$dst, (v8i16 (vector_insert (v8i16 VR128:$src1), + R32:$src2, (i32 imm:$src3))))]>; +def PINSRWrm : PDIi8<0xC4, MRMSrcMem, + (ops VR128:$dst, VR128:$src1, i16mem:$src2, i32i8imm:$src3), + "pinsrw {$src3, $src2, $dst|$dst, $src2, $src3}", + [(set VR128:$dst, + (v8i16 (vector_insert (v8i16 VR128:$src1), + (i32 (anyext (loadi16 addr:$src2))), + (i32 imm:$src3))))]>; +} + //===----------------------------------------------------------------------===// // Miscellaneous Instructions //===----------------------------------------------------------------------===//