- SDValue Vec = Op.getOperand(0);
- EVT VecVT = Vec.getValueType();
- SDValue Width = DAG.getConstant(VecVT.getSizeInBits(), dl, MVT::i64);
- SDValue Shifted = DAG.getNode(ISD::SHL, dl, MVT::i64, Width,
- DAG.getConstant(32, dl, MVT::i64));
- SDValue ConstVal = DAG.getConstant(0, dl, MVT::i64);
-
- ConstantSDNode *W = dyn_cast<ConstantSDNode>(Width);
- ConstantSDNode *S = dyn_cast<ConstantSDNode>(Shifted);
-
- if ((VecVT.getSimpleVT() == MVT::v2i16) && (NElts == 2) && W && S) {
- if ((W->getZExtValue() == 32) && ((S->getZExtValue() >> 32) == 32)) {
- // We are trying to concat two v2i16 to a single v4i16.
- SDValue Vec0 = Op.getOperand(1);
- SDValue Combined = DAG.getNode(HexagonISD::COMBINE, dl, VT, Vec0, Vec);
- return DAG.getNode(ISD::BITCAST, dl, VT, Combined);
+ SDValue Vec0 = Op.getOperand(0);
+ EVT VecVT = Vec0.getValueType();
+ unsigned Width = VecVT.getSizeInBits();
+
+ if (NElts == 2) {
+ MVT ST = VecVT.getSimpleVT();
+ // We are trying to concat two v2i16 to a single v4i16, or two v4i8
+ // into a single v8i8.
+ if (ST == MVT::v2i16 || ST == MVT::v4i8)
+ return DAG.getNode(HexagonISD::COMBINE, dl, VT, Op.getOperand(1), Vec0);
+
+ if (UseHVX) {
+ assert((Width == 64*8 && Subtarget.useHVXSglOps()) ||
+ (Width == 128*8 && Subtarget.useHVXDblOps()));
+ SDValue Vec1 = Op.getOperand(1);
+ MVT OpTy = Subtarget.useHVXSglOps() ? MVT::v16i32 : MVT::v32i32;
+ MVT ReTy = Subtarget.useHVXSglOps() ? MVT::v32i32 : MVT::v64i32;
+ SDValue B0 = DAG.getNode(ISD::BITCAST, dl, OpTy, Vec0);
+ SDValue B1 = DAG.getNode(ISD::BITCAST, dl, OpTy, Vec1);
+ SDValue VC = DAG.getNode(HexagonISD::VCOMBINE, dl, ReTy, B1, B0);
+ return DAG.getNode(ISD::BITCAST, dl, VT, VC);