- State.IntValue = DAG.getNode(ISD::BITCAST, DL, IVT, Value);
- State.SignMask = APInt::getSignBit(NumBits);
- return;
- }
-
- auto &DataLayout = DAG.getDataLayout();
- // Store the float to memory, then load the sign part out as an integer.
- MVT LoadTy = TLI.getPointerTy(DataLayout);
- // First create a temporary that is aligned for both the load and store.
- SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy);
- int FI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
- // Then store the float to it.
- State.FloatPtr = StackPtr;
- State.FloatPointerInfo = MachinePointerInfo::getFixedStack(FI);
- State.Chain = DAG.getStore(DAG.getEntryNode(), DL, Value, State.FloatPtr,
- State.FloatPointerInfo, false, false, 0);
-
- if (DataLayout.isBigEndian()) {
- assert(FloatVT.isByteSized() && "Unsupported floating point type!");
- // Load out a legal integer with the same sign bit as the float.
- State.IntPtr = StackPtr;
- State.IntPointerInfo = State.FloatPointerInfo;
- State.IntValue = DAG.getLoad(LoadTy, DL, State.Chain, StackPtr,
- State.IntPointerInfo, false, false, false, 0);
- State.SignMask = APInt::getSignBit(LoadTy.getSizeInBits());
- } else { // Little endian
- // The float may be wider than the integer we are going to load. Advance
- // the pointer so that the loaded integer will contain the sign bit.
- unsigned Strides = (FloatVT.getSizeInBits()-1)/LoadTy.getSizeInBits();
- unsigned ByteOffset = (Strides * LoadTy.getSizeInBits()) / 8;
- SDValue LoadPtr
- = DAG.getNode(ISD::ADD, DL, StackPtr.getValueType(), StackPtr,
- DAG.getConstant(ByteOffset, DL, StackPtr.getValueType()));
- // Load a legal integer containing the sign bit.
- State.IntPtr = LoadPtr;
- State.IntPointerInfo = MachinePointerInfo::getFixedStack(FI, ByteOffset);
- State.IntValue = DAG.getLoad(LoadTy, DL, State.Chain, LoadPtr,
- State.IntPointerInfo, false, false, false, 0);
- unsigned NumBits = LoadTy.getSizeInBits();
- unsigned SignBit = (FloatVT.getSizeInBits()-1) - 8*ByteOffset;
- State.SignMask = APInt::getOneBitSet(NumBits, SignBit);
- }
-}
-
-/// Replace the integer value produced by getSignAsIntValue() with a new value
-/// and cast the result back to a floatingpoint type.
-SDValue SelectionDAGLegalize::modifySignAsInt(const FloatSignAsInt &State,
- SDLoc DL, SDValue NewIntValue) const {
- if (!State.Chain) {
- return DAG.getNode(ISD::BITCAST, DL, State.FloatVT, NewIntValue);
- }
-
- // Override the part containing the sign bit in the value stored on the stack.
- SDValue Chain = DAG.getStore(State.Chain, DL, NewIntValue, State.IntPtr,
- State.IntPointerInfo, false, false, 0);
- return DAG.getLoad(State.FloatVT, DL, Chain, State.FloatPtr,
- State.FloatPointerInfo, false, false, false, 0);
-}
-
-SDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode *Node) const {
- SDLoc DL(Node);
- SDValue Mag = Node->getOperand(0);
- SDValue Sign = Node->getOperand(1);
-
- // Get sign bit into an integer value.
- FloatSignAsInt SignAsInt;
- getSignAsIntValue(SignAsInt, DL, Sign);
-
- EVT IntVT = SignAsInt.IntValue.getValueType();
- SDValue SignMask = DAG.getConstant(SignAsInt.SignMask, DL, IntVT);
- SDValue SignBit = DAG.getNode(ISD::AND, DL, IntVT, SignAsInt.IntValue,
- SignMask);
-
- // Transform FCOPYSIGN(x, y) => sign(x) ? -FABS(x) : FABS(X) if FABS is legal.
- EVT FloatVT = Mag.getValueType();
- if (TLI.isOperationLegalOrCustom(ISD::FABS, FloatVT) &&
- TLI.isOperationLegalOrCustom(ISD::FNEG, FloatVT)) {
- SDValue AbsValue = DAG.getNode(ISD::FABS, DL, FloatVT, Mag);
- SDValue NegValue = DAG.getNode(ISD::FNEG, DL, FloatVT, AbsValue);
- SDValue Cond = DAG.getSetCC(DL, getSetCCResultType(IntVT), SignBit,
- DAG.getConstant(0, DL, IntVT), ISD::SETNE);
- return DAG.getSelect(DL, FloatVT, Cond, NegValue, AbsValue);
- }
-
- // Transform values to integer, copy the sign bit and transform back.
- FloatSignAsInt MagAsInt;
- getSignAsIntValue(MagAsInt, DL, Mag);
- assert(SignAsInt.SignMask == MagAsInt.SignMask);
- SDValue ClearSignMask = DAG.getConstant(~SignAsInt.SignMask, DL, IntVT);
- SDValue ClearedSign = DAG.getNode(ISD::AND, DL, IntVT, MagAsInt.IntValue,
- ClearSignMask);
- SDValue CopiedSign = DAG.getNode(ISD::OR, DL, IntVT, ClearedSign, SignBit);
-
- return modifySignAsInt(MagAsInt, DL, CopiedSign);
-}
-
-SDValue SelectionDAGLegalize::ExpandFABS(SDNode *Node) const {
- SDLoc DL(Node);
- SDValue Value = Node->getOperand(0);
-
- // Transform FABS(x) => FCOPYSIGN(x, 0.0) if FCOPYSIGN is legal.
- EVT FloatVT = Value.getValueType();
- if (TLI.isOperationLegalOrCustom(ISD::FCOPYSIGN, FloatVT)) {
- SDValue Zero = DAG.getConstantFP(0.0, DL, FloatVT);
- return DAG.getNode(ISD::FCOPYSIGN, DL, FloatVT, Value, Zero);
+ // Convert to an integer with the same sign bit.
+ SignBit = DAG.getNode(ISD::BITCAST, dl, IVT, Tmp2);
+ } else {
+ auto &DL = DAG.getDataLayout();
+ // Store the float to memory, then load the sign part out as an integer.
+ MVT LoadTy = TLI.getPointerTy(DL);
+ // First create a temporary that is aligned for both the load and store.
+ SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy);
+ // Then store the float to it.
+ SDValue Ch =
+ DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StackPtr, MachinePointerInfo(),
+ false, false, 0);
+ if (DL.isBigEndian()) {
+ assert(FloatVT.isByteSized() && "Unsupported floating point type!");
+ // Load out a legal integer with the same sign bit as the float.
+ SignBit = DAG.getLoad(LoadTy, dl, Ch, StackPtr, MachinePointerInfo(),
+ false, false, false, 0);
+ } else { // Little endian
+ SDValue LoadPtr = StackPtr;
+ // The float may be wider than the integer we are going to load. Advance
+ // the pointer so that the loaded integer will contain the sign bit.
+ unsigned Strides = (FloatVT.getSizeInBits()-1)/LoadTy.getSizeInBits();
+ unsigned ByteOffset = (Strides * LoadTy.getSizeInBits()) / 8;
+ LoadPtr = DAG.getNode(ISD::ADD, dl, LoadPtr.getValueType(), LoadPtr,
+ DAG.getConstant(ByteOffset, dl,
+ LoadPtr.getValueType()));
+ // Load a legal integer containing the sign bit.
+ SignBit = DAG.getLoad(LoadTy, dl, Ch, LoadPtr, MachinePointerInfo(),
+ false, false, false, 0);
+ // Move the sign bit to the top bit of the loaded integer.
+ unsigned BitShift = LoadTy.getSizeInBits() -
+ (FloatVT.getSizeInBits() - 8 * ByteOffset);
+ assert(BitShift < LoadTy.getSizeInBits() && "Pointer advanced wrong?");
+ if (BitShift)
+ SignBit = DAG.getNode(
+ ISD::SHL, dl, LoadTy, SignBit,
+ DAG.getConstant(BitShift, dl,
+ TLI.getShiftAmountTy(SignBit.getValueType(), DL)));
+ }