* gcc.c-torture/execute/20020307-1.c: New test.
[official-gcc.git] / gcc / ada / s-exngen.adb
blob1054463c55c4086298b673e319f28f5629d55e2d
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUNTIME COMPONENTS --
4 -- --
5 -- S Y S T E M . E X N _ G E N --
6 -- --
7 -- B o d y --
8 -- --
9 -- $Revision: 1.9 $
10 -- --
11 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
12 -- --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
23 -- --
24 -- As a special exception, if other files instantiate generics from this --
25 -- unit, or you link this unit with other files to produce an executable, --
26 -- this unit does not by itself cause the resulting executable to be --
27 -- covered by the GNU General Public License. This exception does not --
28 -- however invalidate any other reasons why the executable file might be --
29 -- covered by the GNU Public License. --
30 -- --
31 -- GNAT was originally developed by the GNAT team at New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
33 -- --
34 ------------------------------------------------------------------------------
36 package body System.Exn_Gen is
38 --------------------
39 -- Exn_Float_Type --
40 --------------------
42 function Exn_Float_Type
43 (Left : Type_Of_Base;
44 Right : Integer)
45 return Type_Of_Base
47 pragma Suppress (Division_Check);
48 pragma Suppress (Overflow_Check);
49 pragma Suppress (Range_Check);
51 Result : Type_Of_Base := 1.0;
52 Factor : Type_Of_Base := Left;
53 Exp : Integer := Right;
55 begin
56 -- We use the standard logarithmic approach, Exp gets shifted right
57 -- testing successive low order bits and Factor is the value of the
58 -- base raised to the next power of 2. For positive exponents we
59 -- multiply the result by this factor, for negative exponents, we
60 -- Division by this factor.
62 if Exp >= 0 then
63 loop
64 if Exp rem 2 /= 0 then
65 Result := Result * Factor;
66 end if;
68 Exp := Exp / 2;
69 exit when Exp = 0;
70 Factor := Factor * Factor;
71 end loop;
73 return Result;
75 -- Negative exponent. For a zero base, we should arguably return an
76 -- infinity of the right sign, but it is not clear that there is
77 -- proper authorization to do so, so for now raise Constraint_Error???
79 elsif Factor = 0.0 then
80 raise Constraint_Error;
82 -- Here we have a non-zero base and a negative exponent
84 else
85 -- For the negative exponent case, a constraint error during this
86 -- calculation happens if Factor gets too large, and the proper
87 -- response is to return 0.0, since what we essentially have is
88 -- 1.0 / infinity, and the closest model number will be zero.
90 begin
91 loop
92 if Exp rem 2 /= 0 then
93 Result := Result * Factor;
94 end if;
96 Exp := Exp / 2;
97 exit when Exp = 0;
98 Factor := Factor * Factor;
99 end loop;
101 return 1.0 / Result;
103 exception
105 when Constraint_Error =>
106 return 0.0;
107 end;
108 end if;
109 end Exn_Float_Type;
111 ----------------------
112 -- Exn_Integer_Type --
113 ----------------------
115 -- Note that negative exponents get a constraint error because the
116 -- subtype of the Right argument (the exponent) is Natural.
118 function Exn_Integer_Type
119 (Left : Type_Of_Base;
120 Right : Natural)
121 return Type_Of_Base
123 pragma Suppress (Division_Check);
124 pragma Suppress (Overflow_Check);
126 Result : Type_Of_Base := 1;
127 Factor : Type_Of_Base := Left;
128 Exp : Natural := Right;
130 begin
131 -- We use the standard logarithmic approach, Exp gets shifted right
132 -- testing successive low order bits and Factor is the value of the
133 -- base raised to the next power of 2.
135 -- Note: it is not worth special casing the cases of base values -1,0,+1
136 -- since the expander does this when the base is a literal, and other
137 -- cases will be extremely rare.
139 if Exp /= 0 then
140 loop
141 if Exp rem 2 /= 0 then
142 Result := Result * Factor;
143 end if;
145 Exp := Exp / 2;
146 exit when Exp = 0;
147 Factor := Factor * Factor;
148 end loop;
149 end if;
151 return Result;
152 end Exn_Integer_Type;
154 end System.Exn_Gen;