+SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
+ SDOperand InOp = N->getOperand(0);
+ MVT::ValueType InVT = InOp.getValueType();
+ MVT::ValueType NInVT = TLI.getTypeToTransformTo(InVT);
+ MVT::ValueType OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+ switch (getTypeAction(InVT)) {
+ default:
+ assert(false && "Unknown type action!");
+ break;
+ case Legal:
+ break;
+ case Promote:
+ if (MVT::getSizeInBits(OutVT) == MVT::getSizeInBits(NInVT))
+ // The input promotes to the same size. Convert the promoted value.
+ return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedOp(InOp));
+ break;
+ case Expand:
+ break;
+ case Scalarize:
+ // Convert the element to an integer and promote it by hand.
+ InOp = DAG.getNode(ISD::BIT_CONVERT,
+ MVT::getIntegerType(MVT::getSizeInBits(InVT)),
+ GetScalarizedOp(InOp));
+ InOp = DAG.getNode(ISD::ANY_EXTEND,
+ MVT::getIntegerType(MVT::getSizeInBits(OutVT)), InOp);
+ return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
+ case Split:
+ // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split
+ // pieces of the input into integers and reassemble in the final type.
+ SDOperand Lo, Hi;
+ GetSplitOp(N->getOperand(0), Lo, Hi);
+
+ unsigned LoBits = MVT::getSizeInBits(Lo.getValueType());
+ Lo = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(LoBits), Lo);
+
+ unsigned HiBits = MVT::getSizeInBits(Hi.getValueType());
+ Hi = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(HiBits), Hi);
+
+ if (TLI.isBigEndian())
+ std::swap(Lo, Hi);
+
+ MVT::ValueType TargetTy = MVT::getIntegerType(MVT::getSizeInBits(OutVT));
+ Hi = DAG.getNode(ISD::ANY_EXTEND, TargetTy, Hi);
+ Hi = DAG.getNode(ISD::SHL, TargetTy, Hi,
+ DAG.getConstant(MVT::getSizeInBits(Lo.getValueType()),
+ TLI.getShiftAmountTy()));
+ Lo = DAG.getNode(ISD::ZERO_EXTEND, TargetTy, Lo);
+
+ return DAG.getNode(ISD::BIT_CONVERT, OutVT,
+ DAG.getNode(ISD::OR, TargetTy, Lo, Hi));
+ }
+
+ // Otherwise, lower the bit-convert to a store/load from the stack, then
+ // promote the load.
+ SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
+ return PromoteResult_LOAD(cast<LoadSDNode>(Op.Val));
+}
+