[committed][RISC-V] Fix test expectations after recent late-combine changes
[official-gcc.git] / gcc / ada / libgnat / a-ztfiio.adb
blob011dc903d7b11d5ea347485207a69d4cc25b7b35
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . W I D E _ W I D E _ T E X T _ I O . F I X E D _ I O --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2024, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
32 with Interfaces;
33 with Ada.Wide_Wide_Text_IO.Fixed_Aux;
34 with Ada.Wide_Wide_Text_IO.Float_Aux;
35 with System.Img_Fixed_32; use System.Img_Fixed_32;
36 with System.Img_Fixed_64; use System.Img_Fixed_64;
37 with System.Img_LFlt; use System.Img_LFlt;
38 with System.Val_Fixed_32; use System.Val_Fixed_32;
39 with System.Val_Fixed_64; use System.Val_Fixed_64;
40 with System.Val_LFlt; use System.Val_LFlt;
41 with System.WCh_Con; use System.WCh_Con;
42 with System.WCh_WtS; use System.WCh_WtS;
44 package body Ada.Wide_Wide_Text_IO.Fixed_IO is
46 -- Note: we still use the floating-point I/O routines for types whose small
47 -- is not the ratio of two sufficiently small integers. This will result in
48 -- inaccuracies for fixed point types that require more precision than is
49 -- available in Long_Float.
51 subtype Int32 is Interfaces.Integer_32; use type Int32;
52 subtype Int64 is Interfaces.Integer_64; use type Int64;
54 package Aux32 is new
55 Ada.Wide_Wide_Text_IO.Fixed_Aux (Int32, Scan_Fixed32, Set_Image_Fixed32);
57 package Aux64 is new
58 Ada.Wide_Wide_Text_IO.Fixed_Aux (Int64, Scan_Fixed64, Set_Image_Fixed64);
60 package Aux_Long_Float is new
61 Ada.Wide_Wide_Text_IO.Float_Aux
62 (Long_Float, Scan_Long_Float, Set_Image_Long_Float);
64 -- Throughout this generic body, we distinguish between the case where type
65 -- Int32 is OK and where type Int64 is OK. These boolean constants are used
66 -- to test for this, such that only code for the relevant case is included
67 -- in the instance; that's why the computation of their value must be fully
68 -- static (although it is not a static expressions in the RM sense).
70 OK_Get_32 : constant Boolean :=
71 Num'Base'Object_Size <= 32
72 and then
73 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
74 or else
75 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
76 or else
77 (Num'Small_Numerator <= 2**27
78 and then Num'Small_Denominator <= 2**27));
79 -- These conditions are derived from the prerequisites of System.Value_F
81 OK_Put_32 : constant Boolean :=
82 Num'Base'Object_Size <= 32
83 and then
84 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**31)
85 or else
86 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**31)
87 or else
88 (Num'Small_Numerator < Num'Small_Denominator
89 and then Num'Small_Denominator <= 2**27)
90 or else
91 (Num'Small_Denominator < Num'Small_Numerator
92 and then Num'Small_Numerator <= 2**25));
93 -- These conditions are derived from the prerequisites of System.Image_F
95 OK_Get_64 : constant Boolean :=
96 Num'Base'Object_Size <= 64
97 and then
98 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
99 or else
100 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
101 or else
102 (Num'Small_Numerator <= 2**59
103 and then Num'Small_Denominator <= 2**59));
104 -- These conditions are derived from the prerequisites of System.Value_F
106 OK_Put_64 : constant Boolean :=
107 Num'Base'Object_Size <= 64
108 and then
109 ((Num'Small_Numerator = 1 and then Num'Small_Denominator <= 2**63)
110 or else
111 (Num'Small_Denominator = 1 and then Num'Small_Numerator <= 2**63)
112 or else
113 (Num'Small_Numerator < Num'Small_Denominator
114 and then Num'Small_Denominator <= 2**59)
115 or else
116 (Num'Small_Denominator < Num'Small_Numerator
117 and then Num'Small_Numerator <= 2**53));
118 -- These conditions are derived from the prerequisites of System.Image_F
120 E : constant Natural := 63 - 32 * Boolean'Pos (OK_Put_32);
121 -- T'Size - 1 for the selected Int{32,64}
123 F0 : constant Natural := 0;
124 F1 : constant Natural :=
125 F0 + 18 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F0) >= 1.0E+18);
126 F2 : constant Natural :=
127 F1 + 9 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F1) >= 1.0E+9);
128 F3 : constant Natural :=
129 F2 + 5 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F2) >= 1.0E+5);
130 F4 : constant Natural :=
131 F3 + 3 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F3) >= 1.0E+3);
132 F5 : constant Natural :=
133 F4 + 2 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F4) >= 1.0E+2);
134 F6 : constant Natural :=
135 F5 + 1 * Boolean'Pos (2.0**E * Num'Small * 10.0**(-F5) >= 1.0E+1);
136 -- Binary search for the number of digits - 1 before the decimal point of
137 -- the product 2.0**E * Num'Small.
139 For0 : constant Natural := 2 + F6;
140 -- Fore value for the fixed point type whose mantissa is Int{32,64} and
141 -- whose small is Num'Small.
143 ---------
144 -- Get --
145 ---------
147 procedure Get
148 (File : File_Type;
149 Item : out Num;
150 Width : Field := 0)
152 pragma Unsuppress (Range_Check);
154 begin
155 if OK_Get_32 then
156 Item := Num'Fixed_Value
157 (Aux32.Get (File, Width,
158 -Num'Small_Numerator,
159 -Num'Small_Denominator));
160 elsif OK_Get_64 then
161 Item := Num'Fixed_Value
162 (Aux64.Get (File, Width,
163 -Num'Small_Numerator,
164 -Num'Small_Denominator));
165 else
166 Aux_Long_Float.Get (File, Long_Float (Item), Width);
167 end if;
169 exception
170 when Constraint_Error => raise Data_Error;
171 end Get;
173 procedure Get
174 (Item : out Num;
175 Width : Field := 0)
177 begin
178 Get (Current_In, Item, Width);
179 end Get;
181 procedure Get
182 (From : Wide_Wide_String;
183 Item : out Num;
184 Last : out Positive)
186 pragma Unsuppress (Range_Check);
188 S : constant String := Wide_Wide_String_To_String (From, WCEM_Upper);
189 -- String on which we do the actual conversion. Note that the method
190 -- used for wide character encoding is irrelevant, since if there is
191 -- a character outside the Standard.Character range then the call to
192 -- Aux.Gets will raise Data_Error in any case.
194 begin
195 if OK_Get_32 then
196 Item := Num'Fixed_Value
197 (Aux32.Gets (S, Last,
198 -Num'Small_Numerator,
199 -Num'Small_Denominator));
200 elsif OK_Get_64 then
201 Item := Num'Fixed_Value
202 (Aux64.Gets (S, Last,
203 -Num'Small_Numerator,
204 -Num'Small_Denominator));
205 else
206 Aux_Long_Float.Gets (S, Long_Float (Item), Last);
207 end if;
209 exception
210 when Constraint_Error => raise Data_Error;
211 end Get;
213 ---------
214 -- Put --
215 ---------
217 procedure Put
218 (File : File_Type;
219 Item : Num;
220 Fore : Field := Default_Fore;
221 Aft : Field := Default_Aft;
222 Exp : Field := Default_Exp)
224 begin
225 if OK_Put_32 then
226 Aux32.Put (File, Int32'Integer_Value (Item), Fore, Aft, Exp,
227 -Num'Small_Numerator, -Num'Small_Denominator,
228 For0, Num'Aft);
229 elsif OK_Put_64 then
230 Aux64.Put (File, Int64'Integer_Value (Item), Fore, Aft, Exp,
231 -Num'Small_Numerator, -Num'Small_Denominator,
232 For0, Num'Aft);
233 else
234 Aux_Long_Float.Put (File, Long_Float (Item), Fore, Aft, Exp);
235 end if;
236 end Put;
238 procedure Put
239 (Item : Num;
240 Fore : Field := Default_Fore;
241 Aft : Field := Default_Aft;
242 Exp : Field := Default_Exp)
244 begin
245 Put (Current_Out, Item, Fore, Aft, Exp);
246 end Put;
248 procedure Put
249 (To : out Wide_Wide_String;
250 Item : Num;
251 Aft : Field := Default_Aft;
252 Exp : Field := Default_Exp)
254 S : String (To'First .. To'Last);
256 begin
257 if OK_Put_32 then
258 Aux32.Puts (S, Int32'Integer_Value (Item), Aft, Exp,
259 -Num'Small_Numerator, -Num'Small_Denominator,
260 For0, Num'Aft);
261 elsif OK_Put_64 then
262 Aux64.Puts (S, Int64'Integer_Value (Item), Aft, Exp,
263 -Num'Small_Numerator, -Num'Small_Denominator,
264 For0, Num'Aft);
265 else
266 Aux_Long_Float.Puts (S, Long_Float (Item), Aft, Exp);
267 end if;
269 for J in S'Range loop
270 To (J) := Wide_Wide_Character'Val (Character'Pos (S (J)));
271 end loop;
272 end Put;
274 end Ada.Wide_Wide_Text_IO.Fixed_IO;