diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2020-11-04 17:27:17 +0100 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2020-11-27 04:15:58 -0500 |
commit | 9884fc7e79e0753299169a5045ba054520896ac6 (patch) | |
tree | 700ea05e06eb8c75aac2379d41aa6f0d4b61eeb3 /gcc | |
parent | 7d4ee5f8e2ab894fdeaa67824eb32103cda947f8 (diff) | |
download | gcc-9884fc7e79e0753299169a5045ba054520896ac6.zip gcc-9884fc7e79e0753299169a5045ba054520896ac6.tar.gz gcc-9884fc7e79e0753299169a5045ba054520896ac6.tar.bz2 |
[Ada] Do not use 128-bit division for 64-bit fixed-point types
gcc/ada/
* exp_fixd.adb (Build_Double_Divide): Only use a 128-bit
division if one of the operands is larger than 64 bits.
(Build_Double_Divide_Code): Likewise.
(Build_Scaled_Divide): Likewise.
(Build_Scaled_Divide_Code): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ada/exp_fixd.adb | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/gcc/ada/exp_fixd.adb b/gcc/ada/exp_fixd.adb index af1db96..a85b6e7 100644 --- a/gcc/ada/exp_fixd.adb +++ b/gcc/ada/exp_fixd.adb @@ -447,15 +447,22 @@ package body Exp_Fixd is (N : Node_Id; X, Y, Z : Node_Id) return Node_Id is + X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X))); Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y))); Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z))); + D_Size : constant Nat := Y_Size + Z_Size; + M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size)); Expr : Node_Id; begin -- If the denominator fits in Max_Integer_Size bits, we can build the - -- operations directly without causing any intermediate overflow. + -- operations directly without causing any intermediate overflow. But + -- for backward compatibility reasons, we use a 128-bit divide only + -- if one of the operands is already larger than 64 bits. - if Y_Size + Z_Size <= System_Max_Integer_Size then + if D_Size <= System_Max_Integer_Size + and then (D_Size <= 64 or else M_Size > 64) + then return Build_Divide (N, X, Build_Multiply (N, Y, Z)); -- Otherwise we use the runtime routine @@ -518,6 +525,7 @@ package body Exp_Fixd is X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X))); Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y))); Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z))); + M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size)); QR_Id : RE_Id; QR_Siz : Nat; @@ -546,17 +554,17 @@ package body Exp_Fixd is QR_Typ := Standard_Integer_64; QR_Id := RE_Null; - elsif QR_Siz <= 128 and then System_Max_Integer_Size = 128 then - QR_Typ := Standard_Integer_128; - QR_Id := RE_Null; - - -- For more than Max_Integer_Size bits, we use the integer defined in - -- Interfaces, so that it can be handled by the runtime routine. + -- For backward compatibility reasons, we use a 128-bit divide only + -- if one of the operands is already larger than 64 bits. - elsif System_Max_Integer_Size < 128 then + elsif System_Max_Integer_Size < 128 or else M_Size <= 64 then QR_Typ := RTE (RE_Integer_64); QR_Id := RE_Double_Divide64; + elsif QR_Siz <= 128 then + QR_Typ := Standard_Integer_128; + QR_Id := RE_Null; + else QR_Typ := RTE (RE_Integer_128); QR_Id := RE_Double_Divide128; @@ -571,9 +579,9 @@ package body Exp_Fixd is Set_Etype (Qnn, QR_Typ); Set_Etype (Rnn, QR_Typ); - -- Case that we can compute the denominator in Max_Integer_Size bits + -- Case where we can compute the denominator in Max_Integer_Size bits - if QR_Siz <= System_Max_Integer_Size then + if QR_Id = RE_Null then -- Create temporaries for numerator and denominator and set Etypes, -- so that New_Occurrence_Of picks them up for Build_xxx calls. @@ -829,13 +837,20 @@ package body Exp_Fixd is is X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X))); Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y))); + Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z))); + N_Size : constant Nat := X_Size + Y_Size; + M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size)); Expr : Node_Id; begin -- If the numerator fits in Max_Integer_Size bits, we can build the - -- operations directly without causing any intermediate overflow. + -- operations directly without causing any intermediate overflow. But + -- for backward compatibility reasons, we use a 128-bit divide only + -- if one of the operands is already larger than 64 bits. - if X_Size + Y_Size <= System_Max_Integer_Size then + if N_Size <= System_Max_Integer_Size + and then (N_Size <= 64 or else M_Size > 64) + then return Build_Divide (N, Build_Multiply (N, X, Y), Z); -- Otherwise we use the runtime routine @@ -895,6 +910,7 @@ package body Exp_Fixd is X_Size : constant Nat := UI_To_Int (RM_Size (Etype (X))); Y_Size : constant Nat := UI_To_Int (RM_Size (Etype (Y))); Z_Size : constant Nat := UI_To_Int (RM_Size (Etype (Z))); + M_Size : constant Nat := Nat'Max (X_Size, Nat'Max (Y_Size, Z_Size)); QR_Id : RE_Id; QR_Siz : Nat; @@ -923,17 +939,17 @@ package body Exp_Fixd is QR_Typ := Standard_Integer_64; QR_Id := RE_Null; - elsif QR_Siz <= 128 and then System_Max_Integer_Size = 128 then - QR_Typ := Standard_Integer_128; - QR_Id := RE_Null; - - -- For more than Max_Integer_Size bits, we use the integer defined in - -- Interfaces, so that it can be handled by the runtime routine. + -- For backward compatibility reasons, we use a 128-bit divide only + -- if one of the operands is already larger than 64 bits. - elsif System_Max_Integer_Size < 128 then + elsif System_Max_Integer_Size < 128 or else M_Size <= 64 then QR_Typ := RTE (RE_Integer_64); QR_Id := RE_Scaled_Divide64; + elsif QR_Siz <= 128 then + QR_Typ := Standard_Integer_128; + QR_Id := RE_Null; + else QR_Typ := RTE (RE_Integer_128); QR_Id := RE_Scaled_Divide128; @@ -948,9 +964,9 @@ package body Exp_Fixd is Set_Etype (Qnn, QR_Typ); Set_Etype (Rnn, QR_Typ); - -- Case that we can compute the numerator in Max_Integer_Size bits + -- Case where we can compute the numerator in Max_Integer_Size bits - if QR_Siz <= System_Max_Integer_Size then + if QR_Id = RE_Null then Nnn := Make_Temporary (Loc, 'N'); Dnn := Make_Temporary (Loc, 'D'); |