OSDN Git Service

2004-08-09 Thomas Quinot <quinot@act-europe.fr>
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-fatgen.adb
index 7fb8160..50b5e63 100644 (file)
@@ -6,9 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision: 1.19 $
---                                                                          --
---          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2004 Free Software Foundation, Inc.          --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -29,7 +27,7 @@
 -- covered by the  GNU Public License.                                      --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
 --  specialized appropriately, or better still, its generic instantiations
 --  should be replaced by efficient machine-specific code.
 
-with Ada.Unchecked_Conversion; use Ada;
+with Ada.Unchecked_Conversion;
 with System;
 package body System.Fat_Gen is
 
    Float_Radix        : constant T := T (T'Machine_Radix);
-   Float_Radix_Inv    : constant T := 1.0 / Float_Radix;
    Radix_To_M_Minus_1 : constant T := Float_Radix ** (T'Machine_Mantissa - 1);
 
    pragma Assert (T'Machine_Radix = 2);
@@ -165,7 +162,7 @@ package body System.Fat_Gen is
    ---------------
 
    procedure Decompose (XX : T; Frac : out T; Expo : out UI) is
-      X : T := T'Machine (XX);
+      X : constant T := T'Machine (XX);
 
    begin
       if X = 0.0 then
@@ -174,7 +171,7 @@ package body System.Fat_Gen is
 
          --  More useful would be defining Expo to be T'Machine_Emin - 1 or
          --  T'Machine_Emin - T'Machine_Mantissa, which would preserve
-         --  monotonicity of the exponent fuction ???
+         --  monotonicity of the exponent function ???
 
       --  Check for infinities, transfinites, whatnot.
 
@@ -305,12 +302,12 @@ package body System.Fat_Gen is
       Ex : UI := Adjustment;
 
    begin
-      if Adjustment < T'Machine_Emin then
+      if Adjustment < T'Machine_Emin - 1 then
          Y  := 2.0 ** T'Machine_Emin;
          Y1 := Y;
          Ex := Ex - T'Machine_Emin;
 
-         while Ex <= 0 loop
+         while Ex < 0 loop
             Y := T'Machine (Y / 2.0);
 
             if Y = 0.0 then
@@ -340,6 +337,9 @@ package body System.Fat_Gen is
       if Radix_Digits >= T'Machine_Mantissa then
          return X;
 
+      elsif Radix_Digits <= 0 then
+         raise Constraint_Error;
+
       else
          L := Exponent (X) - Radix_Digits;
          Y := Truncation (Scaling (X, -L));
@@ -436,6 +436,10 @@ package body System.Fat_Gen is
       P_Even   : Boolean;
 
    begin
+      if Y = 0.0 then
+         raise Constraint_Error;
+      end if;
+
       if X > 0.0 then
          Sign_X :=  1.0;
          Arg := X;
@@ -740,7 +744,11 @@ package body System.Fat_Gen is
 
       --  The Float_Rep type is an array of Float_Word elements. This
       --  representation is chosen to make it possible to size the
-      --  type based on a generic parameter.
+      --  type based on a generic parameter. Since the array size is
+      --  known at compile-time, efficient code can still be generated.
+      --  The size of Float_Word elements should be large enough to allow
+      --  accessing the exponent in one read, but small enough so that all
+      --  floating point object sizes are a multiple of the Float_Word'Size.
 
       --  The following conditions must be met for all possible
       --  instantiations of the attributes package:
@@ -754,13 +762,20 @@ package body System.Fat_Gen is
       --      and the exponent is in the following bits.
       --      Unused bits (if any) are in the least significant part.
 
-      type Float_Word is mod 2**32;
+      type Float_Word is mod 2**Positive'Min (System.Word_Size, 32);
       type Rep_Index is range 0 .. 7;
 
       Rep_Last : constant Rep_Index := (T'Size - 1) / Float_Word'Size;
 
       type Float_Rep is array (Rep_Index range 0 .. Rep_Last) of Float_Word;
 
+      pragma Suppress_Initialization (Float_Rep);
+      --  This pragma supresses the generation of an initialization procedure
+      --  for type Float_Rep when operating in Initialize/Normalize_Scalars
+      --  mode. This is not just a matter of efficiency, but of functionality,
+      --  since Valid has a pragma Inline_Always, which is not permitted if
+      --  there are nested subprograms present.
+
       Most_Significant_Word : constant Rep_Index :=
                                 Rep_Last * Standard'Default_Bit_Order;
       --  Finding the location of the Exponent_Word is a bit tricky.
@@ -784,11 +799,11 @@ package body System.Fat_Gen is
       --  This assumes that the range IEEE_Emin - 1 .. IEEE_Emax + 1
       --  contains 2**N values, for some N in Natural.
 
-      function To_Float is new Unchecked_Conversion (Float_Rep, T);
+      function To_Float is new Ada.Unchecked_Conversion (Float_Rep, T);
 
       type Float_Access is access all T;
       function To_Address is
-         new Unchecked_Conversion (Float_Access, System.Address);
+         new Ada.Unchecked_Conversion (Float_Access, System.Address);
 
       XA : constant System.Address := To_Address (Float_Access (X));
 
@@ -833,4 +848,21 @@ package body System.Fat_Gen is
          ((E = IEEE_Emin - 1) and then abs To_Float (SR) = 1.0);
    end Valid;
 
+   ---------------------
+   -- Unaligned_Valid --
+   ---------------------
+
+   function Unaligned_Valid (A : System.Address) return Boolean is
+      subtype FS is String (1 .. T'Size / Character'Size);
+      type FSP is access FS;
+
+      function To_FSP is new Ada.Unchecked_Conversion (Address, FSP);
+
+      Local_T : aliased T;
+
+   begin
+      To_FSP (Local_T'Address).all := To_FSP (A).all;
+      return Valid (Local_T'Access);
+   end Unaligned_Valid;
+
 end System.Fat_Gen;