- case ISD::VECTOR_SHUFFLE: {
- Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the input vectors,
- Tmp2 = LegalizeOp(Node->getOperand(1)); // but not the shuffle mask.
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
- MVT VT = Result.getValueType();
-
- // Copy the Mask to a local SmallVector for use with isShuffleMaskLegal.
- SmallVector<int, 8> Mask;
- cast<ShuffleVectorSDNode>(Result)->getMask(Mask);
-
- // Allow targets to custom lower the SHUFFLEs they support.
- switch (TLI.getOperationAction(ISD::VECTOR_SHUFFLE, VT)) {
- default: assert(0 && "Unknown operation action!");
- case TargetLowering::Legal:
- assert(TLI.isShuffleMaskLegal(Mask, VT) &&
- "vector shuffle should not be created if not legal!");
- break;
- case TargetLowering::Custom:
- Tmp3 = TLI.LowerOperation(Result, DAG);
- if (Tmp3.getNode()) {
- Result = Tmp3;
- break;
- }
- // FALLTHROUGH
- case TargetLowering::Expand: {
- MVT EltVT = VT.getVectorElementType();
- unsigned NumElems = VT.getVectorNumElements();
- SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0; i != NumElems; ++i) {
- if (Mask[i] < 0) {
- Ops.push_back(DAG.getUNDEF(EltVT));
- continue;
- }
- unsigned Idx = Mask[i];
- if (Idx < NumElems)
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp1,
- DAG.getIntPtrConstant(Idx)));
- else
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp2,
- DAG.getIntPtrConstant(Idx - NumElems)));
- }
- Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size());
- break;
- }
- case TargetLowering::Promote: {
- // Change base type to a different vector type.
- MVT OVT = Node->getValueType(0);
- MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
-
- // Cast the two input vectors.
- Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1);
- Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2);
-
- // Convert the shuffle mask to the right # elements.
- Result = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask);
- Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result);
- break;
- }
- }
- break;
- }
- case ISD::CONCAT_VECTORS: {
- // Legalize the operands.
- SmallVector<SDValue, 8> Ops;
- for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
- Ops.push_back(LegalizeOp(Node->getOperand(i)));
- Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
-
- switch (TLI.getOperationAction(ISD::CONCAT_VECTORS,
- Node->getValueType(0))) {
- default: assert(0 && "Unknown operation action!");
- case TargetLowering::Legal:
- break;
- case TargetLowering::Custom:
- Tmp3 = TLI.LowerOperation(Result, DAG);
- if (Tmp3.getNode()) {
- Result = Tmp3;
- break;
- }
- // FALLTHROUGH
- case TargetLowering::Expand: {
- // Use extract/insert/build vector for now. We might try to be
- // more clever later.
- MVT PtrVT = TLI.getPointerTy();
- SmallVector<SDValue, 8> Ops;
- unsigned NumOperands = Node->getNumOperands();
- for (unsigned i=0; i < NumOperands; ++i) {
- SDValue SubOp = Node->getOperand(i);
- MVT VVT = SubOp.getNode()->getValueType(0);
- MVT EltVT = VVT.getVectorElementType();
- unsigned NumSubElem = VVT.getVectorNumElements();
- for (unsigned j=0; j < NumSubElem; ++j) {
- Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, SubOp,
- DAG.getConstant(j, PtrVT)));
- }
- }
- return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl,
- Node->getValueType(0),
- &Ops[0], Ops.size()));
- }
- }
- break;
- }
-