@@ -5519,127 +5519,13 @@ APFloat::opStatus DoubleAPFloat::next(bool nextDown) {
5519
5519
return opOK;
5520
5520
}
5521
5521
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
-
5618
5522
APFloat::opStatus
5619
5523
DoubleAPFloat::convertToInteger (MutableArrayRef<integerPart> Input,
5620
5524
unsigned int Width, bool IsSigned,
5621
5525
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);
5643
5529
}
5644
5530
5645
5531
APFloat::opStatus DoubleAPFloat::convertFromAPInt (const APInt &Input,
@@ -5740,31 +5626,14 @@ bool DoubleAPFloat::getExactInverse(APFloat *inv) const {
5740
5626
return Ret;
5741
5627
}
5742
5628
5629
+ int DoubleAPFloat::getExactLog2 () const {
5630
+ // TODO: Implement me
5631
+ return INT_MIN;
5632
+ }
5633
+
5743
5634
int 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;
5768
5637
}
5769
5638
5770
5639
DoubleAPFloat scalbn (const DoubleAPFloat &Arg, int Exp,
@@ -5880,6 +5749,10 @@ void APFloat::Profile(FoldingSetNodeID &NID) const {
5880
5749
NID.Add (bitcastToAPInt ());
5881
5750
}
5882
5751
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
+ */
5883
5756
APFloat::opStatus APFloat::convertToInteger (APSInt &result,
5884
5757
roundingMode rounding_mode,
5885
5758
bool *isExact) const {
0 commit comments