move a bunch of code, no other change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25739 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index da35aad..a7f488e 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -152,332 +152,6 @@
"Too many value types for ValueTypeActions to hold!");
}
-/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
-/// INT_TO_FP operation of the specified operand when the target requests that
-/// we expand it. At this point, we know that the result and operand types are
-/// legal for the target.
-SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
- SDOperand Op0,
- MVT::ValueType DestVT) {
- if (Op0.getValueType() == MVT::i32) {
- // simple 32-bit [signed|unsigned] integer to float/double expansion
-
- // get the stack frame index of a 8 byte buffer
- MachineFunction &MF = DAG.getMachineFunction();
- int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
- // get address of 8 byte buffer
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
- // word offset constant for Hi/Lo address computation
- SDOperand WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
- // set up Hi and Lo (into buffer) address based on endian
- SDOperand Hi, Lo;
- if (TLI.isLittleEndian()) {
- Hi = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
- Lo = StackSlot;
- } else {
- Hi = StackSlot;
- Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
- }
- // if signed map to unsigned space
- SDOperand Op0Mapped;
- if (isSigned) {
- // constant used to invert sign bit (signed to unsigned mapping)
- SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
- Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit);
- } else {
- Op0Mapped = Op0;
- }
- // store the lo of the constructed double - based on integer input
- SDOperand Store1 = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
- Op0Mapped, Lo, DAG.getSrcValue(NULL));
- // initial hi portion of constructed double
- SDOperand InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
- // store the hi of the constructed double - biased exponent
- SDOperand Store2 = DAG.getNode(ISD::STORE, MVT::Other, Store1,
- InitialHi, Hi, DAG.getSrcValue(NULL));
- // load the constructed double
- SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot,
- DAG.getSrcValue(NULL));
- // FP constant to bias correct the final result
- SDOperand Bias = DAG.getConstantFP(isSigned ?
- BitsToDouble(0x4330000080000000ULL)
- : BitsToDouble(0x4330000000000000ULL),
- MVT::f64);
- // subtract the bias
- SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
- // final result
- SDOperand Result;
- // handle final rounding
- if (DestVT == MVT::f64) {
- // do nothing
- Result = Sub;
- } else {
- // if f32 then cast to f32
- Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
- }
- return Result;
- }
- assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
- SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
-
- SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
- DAG.getConstant(0, Op0.getValueType()),
- ISD::SETLT);
- SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
- SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
- SignSet, Four, Zero);
-
- // If the sign bit of the integer is set, the large number will be treated
- // as a negative number. To counteract this, the dynamic code adds an
- // offset depending on the data type.
- uint64_t FF;
- switch (Op0.getValueType()) {
- default: assert(0 && "Unsupported integer type!");
- case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float)
- case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float)
- case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float)
- case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float)
- }
- if (TLI.isLittleEndian()) FF <<= 32;
- static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
-
- SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
- CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
- SDOperand FudgeInReg;
- if (DestVT == MVT::f32)
- FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
- DAG.getSrcValue(NULL));
- else {
- assert(DestVT == MVT::f64 && "Unexpected conversion");
- FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
- DAG.getEntryNode(), CPIdx,
- DAG.getSrcValue(NULL), MVT::f32));
- }
-
- return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg);
-}
-
-/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
-/// *INT_TO_FP operation of the specified operand when the target requests that
-/// we promote it. At this point, we know that the result and operand types are
-/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
-/// operation that takes a larger input.
-SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
- MVT::ValueType DestVT,
- bool isSigned) {
- // First step, figure out the appropriate *INT_TO_FP operation to use.
- MVT::ValueType NewInTy = LegalOp.getValueType();
-
- unsigned OpToUse = 0;
-
- // Scan for the appropriate larger type to use.
- while (1) {
- NewInTy = (MVT::ValueType)(NewInTy+1);
- assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
-
- // If the target supports SINT_TO_FP of this type, use it.
- switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
- default: break;
- case TargetLowering::Legal:
- if (!TLI.isTypeLegal(NewInTy))
- break; // Can't use this datatype.
- // FALL THROUGH.
- case TargetLowering::Custom:
- OpToUse = ISD::SINT_TO_FP;
- break;
- }
- if (OpToUse) break;
- if (isSigned) continue;
-
- // If the target supports UINT_TO_FP of this type, use it.
- switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
- default: break;
- case TargetLowering::Legal:
- if (!TLI.isTypeLegal(NewInTy))
- break; // Can't use this datatype.
- // FALL THROUGH.
- case TargetLowering::Custom:
- OpToUse = ISD::UINT_TO_FP;
- break;
- }
- if (OpToUse) break;
-
- // Otherwise, try a larger type.
- }
-
- // Okay, we found the operation and type to use. Zero extend our input to the
- // desired type then run the operation on it.
- return DAG.getNode(OpToUse, DestVT,
- DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
- NewInTy, LegalOp));
-}
-
-/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a
-/// FP_TO_*INT operation of the specified operand when the target requests that
-/// we promote it. At this point, we know that the result and operand types are
-/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT
-/// operation that returns a larger result.
-SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
- MVT::ValueType DestVT,
- bool isSigned) {
- // First step, figure out the appropriate FP_TO*INT operation to use.
- MVT::ValueType NewOutTy = DestVT;
-
- unsigned OpToUse = 0;
-
- // Scan for the appropriate larger type to use.
- while (1) {
- NewOutTy = (MVT::ValueType)(NewOutTy+1);
- assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!");
-
- // If the target supports FP_TO_SINT returning this type, use it.
- switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) {
- default: break;
- case TargetLowering::Legal:
- if (!TLI.isTypeLegal(NewOutTy))
- break; // Can't use this datatype.
- // FALL THROUGH.
- case TargetLowering::Custom:
- OpToUse = ISD::FP_TO_SINT;
- break;
- }
- if (OpToUse) break;
-
- // If the target supports FP_TO_UINT of this type, use it.
- switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) {
- default: break;
- case TargetLowering::Legal:
- if (!TLI.isTypeLegal(NewOutTy))
- break; // Can't use this datatype.
- // FALL THROUGH.
- case TargetLowering::Custom:
- OpToUse = ISD::FP_TO_UINT;
- break;
- }
- if (OpToUse) break;
-
- // Otherwise, try a larger type.
- }
-
- // Okay, we found the operation and type to use. Truncate the result of the
- // extended FP_TO_*INT operation to the desired size.
- return DAG.getNode(ISD::TRUNCATE, DestVT,
- DAG.getNode(OpToUse, NewOutTy, LegalOp));
-}
-
-/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation.
-///
-SDOperand SelectionDAGLegalize::ExpandBSWAP(SDOperand Op) {
- MVT::ValueType VT = Op.getValueType();
- MVT::ValueType SHVT = TLI.getShiftAmountTy();
- SDOperand Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
- switch (VT) {
- default: assert(0 && "Unhandled Expand type in BSWAP!"); abort();
- case MVT::i16:
- Tmp2 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- return DAG.getNode(ISD::OR, VT, Tmp1, Tmp2);
- case MVT::i32:
- Tmp4 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp3 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
- Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT));
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
- Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
- return DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
- case MVT::i64:
- Tmp8 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(56, SHVT));
- Tmp7 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(40, SHVT));
- Tmp6 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp5 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp4 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
- Tmp3 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
- Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(40, SHVT));
- Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(56, SHVT));
- Tmp7 = DAG.getNode(ISD::AND, VT, Tmp7, DAG.getConstant(255ULL<<48, VT));
- Tmp6 = DAG.getNode(ISD::AND, VT, Tmp6, DAG.getConstant(255ULL<<40, VT));
- Tmp5 = DAG.getNode(ISD::AND, VT, Tmp5, DAG.getConstant(255ULL<<32, VT));
- Tmp4 = DAG.getNode(ISD::AND, VT, Tmp4, DAG.getConstant(255ULL<<24, VT));
- Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(255ULL<<16, VT));
- Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT));
- Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp7);
- Tmp6 = DAG.getNode(ISD::OR, VT, Tmp6, Tmp5);
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
- Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
- Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp6);
- Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
- return DAG.getNode(ISD::OR, VT, Tmp8, Tmp4);
- }
-}
-
-/// ExpandBitCount - Expand the specified bitcount instruction into operations.
-///
-SDOperand SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDOperand Op) {
- switch (Opc) {
- default: assert(0 && "Cannot expand this yet!");
- case ISD::CTPOP: {
- static const uint64_t mask[6] = {
- 0x5555555555555555ULL, 0x3333333333333333ULL,
- 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
- 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
- };
- MVT::ValueType VT = Op.getValueType();
- MVT::ValueType ShVT = TLI.getShiftAmountTy();
- unsigned len = getSizeInBits(VT);
- for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
- //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
- SDOperand Tmp2 = DAG.getConstant(mask[i], VT);
- SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
- Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
- DAG.getNode(ISD::AND, VT,
- DAG.getNode(ISD::SRL, VT, Op, Tmp3),Tmp2));
- }
- return Op;
- }
- case ISD::CTLZ: {
- // for now, we do this:
- // x = x | (x >> 1);
- // x = x | (x >> 2);
- // ...
- // x = x | (x >>16);
- // x = x | (x >>32); // for 64-bit input
- // return popcount(~x);
- //
- // but see also: http://www.hackersdelight.org/HDcode/nlz.cc
- MVT::ValueType VT = Op.getValueType();
- MVT::ValueType ShVT = TLI.getShiftAmountTy();
- unsigned len = getSizeInBits(VT);
- for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
- SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
- Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3));
- }
- Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT));
- return DAG.getNode(ISD::CTPOP, VT, Op);
- }
- case ISD::CTTZ: {
- // for now, we use: { return popcount(~x & (x - 1)); }
- // unless the target has ctlz but not ctpop, in which case we use:
- // { return 32 - nlz(~x & (x-1)); }
- // see also http://www.hackersdelight.org/HDcode/ntz.cc
- MVT::ValueType VT = Op.getValueType();
- SDOperand Tmp2 = DAG.getConstant(~0ULL, VT);
- SDOperand Tmp3 = DAG.getNode(ISD::AND, VT,
- DAG.getNode(ISD::XOR, VT, Op, Tmp2),
- DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT)));
- // If ISD::CTLZ is legal and CTPOP isn't, then do that instead.
- if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
- TLI.isOperationLegal(ISD::CTLZ, VT))
- return DAG.getNode(ISD::SUB, VT,
- DAG.getConstant(getSizeInBits(VT), VT),
- DAG.getNode(ISD::CTLZ, VT, Tmp3));
- return DAG.getNode(ISD::CTPOP, VT, Tmp3);
- }
- }
-}
-
-
/// ComputeTopDownOrdering - Add the specified node to the Order list if it has
/// not been visited yet and if all of its operands have already been visited.
static void ComputeTopDownOrdering(SDNode *N, std::vector<SDNode*> &Order,
@@ -3521,6 +3195,330 @@
return CallResult.first;
}
+/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
+/// INT_TO_FP operation of the specified operand when the target requests that
+/// we expand it. At this point, we know that the result and operand types are
+/// legal for the target.
+SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
+ SDOperand Op0,
+ MVT::ValueType DestVT) {
+ if (Op0.getValueType() == MVT::i32) {
+ // simple 32-bit [signed|unsigned] integer to float/double expansion
+
+ // get the stack frame index of a 8 byte buffer
+ MachineFunction &MF = DAG.getMachineFunction();
+ int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+ // get address of 8 byte buffer
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+ // word offset constant for Hi/Lo address computation
+ SDOperand WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
+ // set up Hi and Lo (into buffer) address based on endian
+ SDOperand Hi, Lo;
+ if (TLI.isLittleEndian()) {
+ Hi = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
+ Lo = StackSlot;
+ } else {
+ Hi = StackSlot;
+ Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
+ }
+ // if signed map to unsigned space
+ SDOperand Op0Mapped;
+ if (isSigned) {
+ // constant used to invert sign bit (signed to unsigned mapping)
+ SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
+ Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit);
+ } else {
+ Op0Mapped = Op0;
+ }
+ // store the lo of the constructed double - based on integer input
+ SDOperand Store1 = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+ Op0Mapped, Lo, DAG.getSrcValue(NULL));
+ // initial hi portion of constructed double
+ SDOperand InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
+ // store the hi of the constructed double - biased exponent
+ SDOperand Store2 = DAG.getNode(ISD::STORE, MVT::Other, Store1,
+ InitialHi, Hi, DAG.getSrcValue(NULL));
+ // load the constructed double
+ SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot,
+ DAG.getSrcValue(NULL));
+ // FP constant to bias correct the final result
+ SDOperand Bias = DAG.getConstantFP(isSigned ?
+ BitsToDouble(0x4330000080000000ULL)
+ : BitsToDouble(0x4330000000000000ULL),
+ MVT::f64);
+ // subtract the bias
+ SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
+ // final result
+ SDOperand Result;
+ // handle final rounding
+ if (DestVT == MVT::f64) {
+ // do nothing
+ Result = Sub;
+ } else {
+ // if f32 then cast to f32
+ Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
+ }
+ return Result;
+ }
+ assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
+ SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
+
+ SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
+ DAG.getConstant(0, Op0.getValueType()),
+ ISD::SETLT);
+ SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+ SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+ SignSet, Four, Zero);
+
+ // If the sign bit of the integer is set, the large number will be treated
+ // as a negative number. To counteract this, the dynamic code adds an
+ // offset depending on the data type.
+ uint64_t FF;
+ switch (Op0.getValueType()) {
+ default: assert(0 && "Unsupported integer type!");
+ case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float)
+ case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float)
+ case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float)
+ case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float)
+ }
+ if (TLI.isLittleEndian()) FF <<= 32;
+ static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
+
+ SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
+ CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+ SDOperand FudgeInReg;
+ if (DestVT == MVT::f32)
+ FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL));
+ else {
+ assert(DestVT == MVT::f64 && "Unexpected conversion");
+ FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
+ DAG.getEntryNode(), CPIdx,
+ DAG.getSrcValue(NULL), MVT::f32));
+ }
+
+ return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg);
+}
+
+/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
+/// *INT_TO_FP operation of the specified operand when the target requests that
+/// we promote it. At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
+/// operation that takes a larger input.
+SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
+ MVT::ValueType DestVT,
+ bool isSigned) {
+ // First step, figure out the appropriate *INT_TO_FP operation to use.
+ MVT::ValueType NewInTy = LegalOp.getValueType();
+
+ unsigned OpToUse = 0;
+
+ // Scan for the appropriate larger type to use.
+ while (1) {
+ NewInTy = (MVT::ValueType)(NewInTy+1);
+ assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
+
+ // If the target supports SINT_TO_FP of this type, use it.
+ switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.isTypeLegal(NewInTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::SINT_TO_FP;
+ break;
+ }
+ if (OpToUse) break;
+ if (isSigned) continue;
+
+ // If the target supports UINT_TO_FP of this type, use it.
+ switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.isTypeLegal(NewInTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::UINT_TO_FP;
+ break;
+ }
+ if (OpToUse) break;
+
+ // Otherwise, try a larger type.
+ }
+
+ // Okay, we found the operation and type to use. Zero extend our input to the
+ // desired type then run the operation on it.
+ return DAG.getNode(OpToUse, DestVT,
+ DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+ NewInTy, LegalOp));
+}
+
+/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a
+/// FP_TO_*INT operation of the specified operand when the target requests that
+/// we promote it. At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT
+/// operation that returns a larger result.
+SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
+ MVT::ValueType DestVT,
+ bool isSigned) {
+ // First step, figure out the appropriate FP_TO*INT operation to use.
+ MVT::ValueType NewOutTy = DestVT;
+
+ unsigned OpToUse = 0;
+
+ // Scan for the appropriate larger type to use.
+ while (1) {
+ NewOutTy = (MVT::ValueType)(NewOutTy+1);
+ assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!");
+
+ // If the target supports FP_TO_SINT returning this type, use it.
+ switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.isTypeLegal(NewOutTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::FP_TO_SINT;
+ break;
+ }
+ if (OpToUse) break;
+
+ // If the target supports FP_TO_UINT of this type, use it.
+ switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) {
+ default: break;
+ case TargetLowering::Legal:
+ if (!TLI.isTypeLegal(NewOutTy))
+ break; // Can't use this datatype.
+ // FALL THROUGH.
+ case TargetLowering::Custom:
+ OpToUse = ISD::FP_TO_UINT;
+ break;
+ }
+ if (OpToUse) break;
+
+ // Otherwise, try a larger type.
+ }
+
+ // Okay, we found the operation and type to use. Truncate the result of the
+ // extended FP_TO_*INT operation to the desired size.
+ return DAG.getNode(ISD::TRUNCATE, DestVT,
+ DAG.getNode(OpToUse, NewOutTy, LegalOp));
+}
+
+/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation.
+///
+SDOperand SelectionDAGLegalize::ExpandBSWAP(SDOperand Op) {
+ MVT::ValueType VT = Op.getValueType();
+ MVT::ValueType SHVT = TLI.getShiftAmountTy();
+ SDOperand Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
+ switch (VT) {
+ default: assert(0 && "Unhandled Expand type in BSWAP!"); abort();
+ case MVT::i16:
+ Tmp2 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+ return DAG.getNode(ISD::OR, VT, Tmp1, Tmp2);
+ case MVT::i32:
+ Tmp4 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp3 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
+ Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT));
+ Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
+ Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
+ return DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
+ case MVT::i64:
+ Tmp8 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(56, SHVT));
+ Tmp7 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(40, SHVT));
+ Tmp6 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp5 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp4 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+ Tmp3 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
+ Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(40, SHVT));
+ Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(56, SHVT));
+ Tmp7 = DAG.getNode(ISD::AND, VT, Tmp7, DAG.getConstant(255ULL<<48, VT));
+ Tmp6 = DAG.getNode(ISD::AND, VT, Tmp6, DAG.getConstant(255ULL<<40, VT));
+ Tmp5 = DAG.getNode(ISD::AND, VT, Tmp5, DAG.getConstant(255ULL<<32, VT));
+ Tmp4 = DAG.getNode(ISD::AND, VT, Tmp4, DAG.getConstant(255ULL<<24, VT));
+ Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(255ULL<<16, VT));
+ Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT));
+ Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp7);
+ Tmp6 = DAG.getNode(ISD::OR, VT, Tmp6, Tmp5);
+ Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
+ Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
+ Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp6);
+ Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
+ return DAG.getNode(ISD::OR, VT, Tmp8, Tmp4);
+ }
+}
+
+/// ExpandBitCount - Expand the specified bitcount instruction into operations.
+///
+SDOperand SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDOperand Op) {
+ switch (Opc) {
+ default: assert(0 && "Cannot expand this yet!");
+ case ISD::CTPOP: {
+ static const uint64_t mask[6] = {
+ 0x5555555555555555ULL, 0x3333333333333333ULL,
+ 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
+ 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
+ };
+ MVT::ValueType VT = Op.getValueType();
+ MVT::ValueType ShVT = TLI.getShiftAmountTy();
+ unsigned len = getSizeInBits(VT);
+ for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
+ //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
+ SDOperand Tmp2 = DAG.getConstant(mask[i], VT);
+ SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
+ Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
+ DAG.getNode(ISD::AND, VT,
+ DAG.getNode(ISD::SRL, VT, Op, Tmp3),Tmp2));
+ }
+ return Op;
+ }
+ case ISD::CTLZ: {
+ // for now, we do this:
+ // x = x | (x >> 1);
+ // x = x | (x >> 2);
+ // ...
+ // x = x | (x >>16);
+ // x = x | (x >>32); // for 64-bit input
+ // return popcount(~x);
+ //
+ // but see also: http://www.hackersdelight.org/HDcode/nlz.cc
+ MVT::ValueType VT = Op.getValueType();
+ MVT::ValueType ShVT = TLI.getShiftAmountTy();
+ unsigned len = getSizeInBits(VT);
+ for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
+ SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
+ Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3));
+ }
+ Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT));
+ return DAG.getNode(ISD::CTPOP, VT, Op);
+ }
+ case ISD::CTTZ: {
+ // for now, we use: { return popcount(~x & (x - 1)); }
+ // unless the target has ctlz but not ctpop, in which case we use:
+ // { return 32 - nlz(~x & (x-1)); }
+ // see also http://www.hackersdelight.org/HDcode/ntz.cc
+ MVT::ValueType VT = Op.getValueType();
+ SDOperand Tmp2 = DAG.getConstant(~0ULL, VT);
+ SDOperand Tmp3 = DAG.getNode(ISD::AND, VT,
+ DAG.getNode(ISD::XOR, VT, Op, Tmp2),
+ DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT)));
+ // If ISD::CTLZ is legal and CTPOP isn't, then do that instead.
+ if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
+ TLI.isOperationLegal(ISD::CTLZ, VT))
+ return DAG.getNode(ISD::SUB, VT,
+ DAG.getConstant(getSizeInBits(VT), VT),
+ DAG.getNode(ISD::CTLZ, VT, Tmp3));
+ return DAG.getNode(ISD::CTPOP, VT, Tmp3);
+ }
+ }
+}
/// ExpandOp - Expand the specified SDOperand into its two component pieces