diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2020-12-14 15:58:49 +0100 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2021-04-29 04:00:44 -0400 |
commit | a5f38dd83e88a6f2325798cd46a1b5ed5107e2ce (patch) | |
tree | 509101f8a922aaa9e91060cd7d3def81cc26e9c8 /gcc | |
parent | 4345c9e79ec17c066b4d2d46dd547adbe8fa5e1d (diff) | |
download | gcc-a5f38dd83e88a6f2325798cd46a1b5ed5107e2ce.zip gcc-a5f38dd83e88a6f2325798cd46a1b5ed5107e2ce.tar.gz gcc-a5f38dd83e88a6f2325798cd46a1b5ed5107e2ce.tar.bz2 |
[Ada] Fix static computation of 'Succ for floating point without denormals
gcc/ada/
* eval_fat.adb (Succ): Add a special case for zero if the type does
not support denormalized numbers. Always use the canonical formula
in other cases and add commentary throughout the function.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/eval_fat.adb | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb index 8160cba..69ba742 100644 --- a/gcc/ada/eval_fat.adb +++ b/gcc/ada/eval_fat.adb @@ -729,22 +729,30 @@ package body Eval_Fat is New_Frac : T; begin + -- Treat zero as a regular denormalized number if they are supported, + -- otherwise return the smallest normalized number. + if UR_Is_Zero (X) then - Exp := Emin; + if Has_Denormals (RT) then + Exp := Emin; + else + return Scaling (RT, Ureal_1, Emin - 1); + end if; end if; - -- Set exponent such that the radix point will be directly following the - -- mantissa after scaling. - - if Has_Denormals (RT) or Exp /= Emin then - Exp := Exp - Mantissa; - else - Exp := Exp - 1; - end if; + -- Multiply the number by 2.0**(Mantissa-Exp) so that the radix point + -- will be directly following the mantissa after scaling. + Exp := Exp - Mantissa; Frac := Scaling (RT, X, -Exp); + + -- Round to the neareast integer towards +Inf + New_Frac := Ceiling (RT, Frac); + -- If the rounding was a NOP, add one, except for -2.0**(Mantissa-1) + -- because the exponent is going to be reduced. + if New_Frac = Frac then if New_Frac = Scaling (RT, -Ureal_1, Mantissa - 1) then New_Frac := New_Frac + Scaling (RT, Ureal_1, Uint_Minus_1); @@ -753,6 +761,8 @@ package body Eval_Fat is end if; end if; + -- Divide back by 2.0**(Mantissa-Exp) to get the final result + return Scaling (RT, New_Frac, Exp); end Succ; |