mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Add support to use pextrw and pinsrw to extract and insert a word element
from a 128-bit vector. llvm-svn: 27304
This commit is contained in:
parent
5da48f30bb
commit
7b9a0c6d7a
@ -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<ConstantSDNode>(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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user