aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2020-12-14 15:58:49 +0100
committerPierre-Marie de Rodat <derodat@adacore.com>2021-04-29 04:00:44 -0400
commita5f38dd83e88a6f2325798cd46a1b5ed5107e2ce (patch)
tree509101f8a922aaa9e91060cd7d3def81cc26e9c8 /gcc
parent4345c9e79ec17c066b4d2d46dd547adbe8fa5e1d (diff)
downloadgcc-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.adb28
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;