@@ -5519,127 +5519,13 @@ APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
55195519 return opOK;
55205520}
55215521
5522- APFloat::opStatus DoubleAPFloat::convertToSignExtendedInteger (
5523- MutableArrayRef<integerPart> Input, unsigned int Width, bool IsSigned,
5524- roundingMode RM, bool *IsExact) const {
5525- assert (Semantics == &semPPCDoubleDouble && " Unexpected Semantics" );
5526-
5527- // If Hi is not finite, or Lo is zero, the value is entirely represented
5528- // by Hi. Delegate to the simpler single-APFloat conversion.
5529- if (!getFirst ().isFiniteNonZero () || getSecond ().isZero ())
5530- return getFirst ().convertToInteger (Input, Width, IsSigned, RM, IsExact);
5531-
5532- // First, round the full double-double value to an integral value. This
5533- // simplifies the rest of the function, as we no longer need to consider
5534- // fractional parts.
5535- *IsExact = false ;
5536- DoubleAPFloat Integral = *this ;
5537- const opStatus RoundStatus = Integral.roundToIntegral (RM);
5538- if (RoundStatus == opInvalidOp)
5539- return RoundStatus;
5540- const APFloat &IntegralHi = Integral.getFirst ();
5541- const APFloat &IntegralLo = Integral.getSecond ();
5542-
5543- // If rounding results in either component being zero, the sum is trivial.
5544- // Delegate to the simpler single-APFloat conversion.
5545- bool HiIsExact;
5546- if (IntegralHi.isZero () || IntegralLo.isZero ()) {
5547- const opStatus HiStatus =
5548- IntegralHi.convertToInteger (Input, Width, IsSigned, RM, &HiIsExact);
5549- // The conversion from an integer-valued float to an APInt may fail if the
5550- // result would be out of range. Regardless, taking this path is only
5551- // possible if rounding occured during the initial `roundToIntegral`.
5552- return HiStatus == opOK ? opInexact : HiStatus;
5553- }
5554-
5555- // A negative number cannot be represented by an unsigned integer.
5556- // Since a double-double is canonical, if Hi is negative, the sum is negative.
5557- if (!IsSigned && IntegralHi.isNegative ())
5558- return opInvalidOp;
5559-
5560- // Handle the special boundary case where |Hi| is exactly the power of two
5561- // that marks the edge of the integer's range (e.g., 2^63 for int64_t). In
5562- // this situation, Hi itself won't fit, but the sum Hi + Lo might.
5563- // `PositiveOverflowWidth` is the bit number for this boundary (N-1 for
5564- // signed, N for unsigned).
5565- bool LoIsExact;
5566- const int HiExactLog2 = IntegralHi.getExactLog2Abs ();
5567- const unsigned PositiveOverflowWidth = IsSigned ? Width - 1 : Width;
5568- if (HiExactLog2 >= 0 &&
5569- static_cast <unsigned >(HiExactLog2) == PositiveOverflowWidth) {
5570- // If Hi and Lo have the same sign, |Hi + Lo| > |Hi|, so the sum is
5571- // guaranteed to overflow. E.g., for uint128_t, (2^128, 1) overflows.
5572- if (IntegralHi.isNegative () == IntegralLo.isNegative ())
5573- return opInvalidOp;
5574-
5575- // If the signs differ, the sum will fit. We can compute the result using
5576- // properties of two's complement arithmetic without a wide intermediate
5577- // integer. E.g., for uint128_t, (2^128, -1) should be 2^128 - 1.
5578- [[maybe_unused]] opStatus LoStatus = IntegralLo.convertToInteger (
5579- Input, Width, /* IsSigned=*/ true , RM, &LoIsExact);
5580- assert (LoStatus == opOK && " Unexpected failure" );
5581-
5582- // Adjust the bit pattern of Lo to account for Hi's value:
5583- // - For unsigned (Hi=2^Width): `2^Width + Lo` in `Width`-bit
5584- // arithmetic is equivalent to just `Lo`. The conversion of `Lo` above
5585- // already produced the correct final bit pattern.
5586- // - For signed (Hi=2^(Width-1)): The sum `2^(Width-1) + Lo` (where Lo<0)
5587- // can be computed by taking the two's complement pattern for `Lo` and
5588- // clearing the sign bit.
5589- if (IsSigned && !IntegralHi.isNegative ())
5590- APInt::tcClearBit (Input.data (), PositiveOverflowWidth);
5591- *IsExact = RoundStatus == opOK;
5592- return RoundStatus;
5593- }
5594-
5595- // General case: Hi is not a power-of-two boundary, so we know it fits.
5596- // Since we already rounded the full value, we now just need to convert the
5597- // components to integers. The rounding mode should not matter.
5598- [[maybe_unused]] opStatus HiStatus = IntegralHi.convertToInteger (
5599- Input, Width, IsSigned, rmTowardZero, &HiIsExact);
5600- assert (HiStatus == opOK && " Unexpected failure" );
5601-
5602- // Convert Lo into a temporary integer of the same width.
5603- APSInt LoResult{Width, /* isUnsigned=*/ !IsSigned};
5604- [[maybe_unused]] opStatus LoStatus =
5605- IntegralLo.convertToInteger (LoResult, rmTowardZero, &LoIsExact);
5606- assert (LoStatus == opOK && " Unexpected failure" );
5607-
5608- // Add Lo to Hi. This addition is guaranteed not to overflow because of the
5609- // double-double canonicalization rule (`|Lo| <= ulp(Hi)/2`). The only case
5610- // where the sum could cross the integer type's boundary is when Hi is a
5611- // power of two, which is handled by the special case block above.
5612- APInt::tcAdd (Input.data (), LoResult.getRawData (), /* carry=*/ 0 , Input.size ());
5613-
5614- *IsExact = RoundStatus == opOK;
5615- return RoundStatus;
5616- }
5617-
56185522APFloat::opStatus
56195523DoubleAPFloat::convertToInteger (MutableArrayRef<integerPart> Input,
56205524 unsigned int Width, bool IsSigned,
56215525 roundingMode RM, bool *IsExact) const {
5622- opStatus FS =
5623- convertToSignExtendedInteger (Input, Width, IsSigned, RM, IsExact);
5624-
5625- if (FS == opInvalidOp) {
5626- const unsigned DstPartsCount = partCountForBits (Width);
5627- assert (DstPartsCount <= Parts.size () && " Integer too big" );
5628-
5629- unsigned Bits;
5630- if (getCategory () == fcNaN)
5631- Bits = 0 ;
5632- else if (isNegative ())
5633- Bits = IsSigned;
5634- else
5635- Bits = Width - IsSigned;
5636-
5637- tcSetLeastSignificantBits (Input.data (), DstPartsCount, Bits);
5638- if (isNegative () && IsSigned)
5639- APInt::tcShiftLeft (Input.data (), DstPartsCount, Width - 1 );
5640- }
5641-
5642- return FS;
5526+ assert (Semantics == &semPPCDoubleDouble && " Unexpected Semantics" );
5527+ return APFloat (semPPCDoubleDoubleLegacy, bitcastToAPInt ())
5528+ .convertToInteger (Input, Width, IsSigned, RM, IsExact);
56435529}
56445530
56455531APFloat::opStatus DoubleAPFloat::convertFromAPInt (const APInt &Input,
@@ -5740,31 +5626,14 @@ bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
57405626 return Ret;
57415627}
57425628
5629+ int DoubleAPFloat::getExactLog2 () const {
5630+ // TODO: Implement me
5631+ return INT_MIN;
5632+ }
5633+
57435634int DoubleAPFloat::getExactLog2Abs () const {
5744- // In order for Hi + Lo to be a power of two, the following must be true:
5745- // 1. Hi must be a power of two.
5746- // 2. Lo must be zero.
5747- if (getSecond ().isNonZero ())
5748- return INT_MIN;
5749- return getFirst ().getExactLog2Abs ();
5750- }
5751-
5752- int ilogb (const DoubleAPFloat& Arg) {
5753- const APFloat& Hi = Arg.getFirst ();
5754- const APFloat& Lo = Arg.getSecond ();
5755- int IlogbResult = ilogb (Hi);
5756- // Zero and non-finite values can delegate to ilogb(Hi).
5757- if (Arg.getCategory () != fcNormal)
5758- return IlogbResult;
5759- // If Lo can't change the binade, we can delegate to ilogb(Hi).
5760- if (Lo.isZero () ||
5761- Hi.isNegative () == Lo.isNegative ())
5762- return IlogbResult;
5763- if (Hi.getExactLog2Abs () == INT_MIN)
5764- return IlogbResult;
5765- // Numbers of the form 2^a - 2^b or -2^a + 2^b are almost powers of two but
5766- // get nudged out of the binade by the low component.
5767- return IlogbResult - 1 ;
5635+ // TODO: Implement me
5636+ return INT_MIN;
57685637}
57695638
57705639DoubleAPFloat scalbn (const DoubleAPFloat &Arg, int Exp,
@@ -5880,6 +5749,10 @@ void APFloat::Profile(FoldingSetNodeID &NID) const {
58805749 NID.Add (bitcastToAPInt ());
58815750}
58825751
5752+ /* Same as convertToInteger(integerPart*, ...), except the result is returned in
5753+ an APSInt, whose initial bit-width and signed-ness are used to determine the
5754+ precision of the conversion.
5755+ */
58835756APFloat::opStatus APFloat::convertToInteger (APSInt &result,
58845757 roundingMode rounding_mode,
58855758 bool *isExact) const {
0 commit comments