aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp79
-rw-r--r--lib/Target/X86/X86InstrMMX.td2
2 files changed, 78 insertions, 3 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 0f27c3062d..a9ebd0daca 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -370,6 +370,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4i16, Custom);
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i32, Custom);
setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v1i64, Custom);
+
+ setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i8, Custom);
+ setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom);
}
if (Subtarget->hasSSE1()) {
@@ -2283,6 +2286,78 @@ static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
}
+/// LowerBuildVectorv8i8 - Custom lower build_vector of v8i8.
+///
+static SDOperand LowerBuildVectorv8i8(SDOperand Op, unsigned NonZeros,
+ unsigned NumNonZero, unsigned NumZero,
+ SelectionDAG &DAG, TargetLowering &TLI) {
+ if (NumNonZero > 8)
+ return SDOperand();
+
+ SDOperand V(0, 0);
+ bool First = true;
+ for (unsigned i = 0; i < 8; ++i) {
+ bool ThisIsNonZero = (NonZeros & (1 << i)) != 0;
+ if (ThisIsNonZero && First) {
+ if (NumZero)
+ V = getZeroVector(MVT::v4i16, DAG);
+ else
+ V = DAG.getNode(ISD::UNDEF, MVT::v4i16);
+ First = false;
+ }
+
+ if ((i & 1) != 0) {
+ SDOperand ThisElt(0, 0), LastElt(0, 0);
+ bool LastIsNonZero = (NonZeros & (1 << (i-1))) != 0;
+ if (LastIsNonZero) {
+ LastElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i-1));
+ }
+ if (ThisIsNonZero) {
+ ThisElt = DAG.getNode(ISD::ZERO_EXTEND, MVT::i16, Op.getOperand(i));
+ ThisElt = DAG.getNode(ISD::SHL, MVT::i16,
+ ThisElt, DAG.getConstant(8, MVT::i8));
+ if (LastIsNonZero)
+ ThisElt = DAG.getNode(ISD::OR, MVT::i16, ThisElt, LastElt);
+ } else
+ ThisElt = LastElt;
+
+ if (ThisElt.Val)
+ V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v4i16, V, ThisElt,
+ DAG.getConstant(i/2, TLI.getPointerTy()));
+ }
+ }
+
+ return DAG.getNode(ISD::BIT_CONVERT, MVT::v8i8, V);
+}
+
+/// LowerBuildVectorv4i16 - Custom lower build_vector of v4i16.
+///
+static SDOperand LowerBuildVectorv4i16(SDOperand Op, unsigned NonZeros,
+ unsigned NumNonZero, unsigned NumZero,
+ SelectionDAG &DAG, TargetLowering &TLI) {
+ if (NumNonZero > 4)
+ return SDOperand();
+
+ SDOperand V(0, 0);
+ bool First = true;
+ for (unsigned i = 0; i < 4; ++i) {
+ bool isNonZero = (NonZeros & (1 << i)) != 0;
+ if (isNonZero) {
+ if (First) {
+ if (NumZero)
+ V = getZeroVector(MVT::v4i16, DAG);
+ else
+ V = DAG.getNode(ISD::UNDEF, MVT::v4i16);
+ First = false;
+ }
+ V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v4i16, V, Op.getOperand(i),
+ DAG.getConstant(i, TLI.getPointerTy()));
+ }
+ }
+
+ return V;
+}
+
/// LowerBuildVectorv16i8 - Custom lower build_vector of v16i8.
///
static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
@@ -2426,13 +2501,13 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
return SDOperand();
// If element VT is < 32 bits, convert it to inserts into a zero vector.
- if (EVTBits == 8) {
+ if (EVTBits == 8 && NumElems == 16) {
SDOperand V = LowerBuildVectorv16i8(Op, NonZeros,NumNonZero,NumZero, DAG,
*this);
if (V.Val) return V;
}
- if (EVTBits == 16) {
+ if (EVTBits == 16 && NumElems == 8) {
SDOperand V = LowerBuildVectorv8i16(Op, NonZeros,NumNonZero,NumZero, DAG,
*this);
if (V.Val) return V;
diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td
index b6ea54ebf9..214ef115e0 100644
--- a/lib/Target/X86/X86InstrMMX.td
+++ b/lib/Target/X86/X86InstrMMX.td
@@ -2,7 +2,7 @@
//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the Evan Cheng and is distributed under the
+// This file was developed by Evan Cheng and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//