Daily bump.
[official-gcc.git] / libgfortran / config / fpu-aix.h
blobdb96e7aaf1b03919edf37996236bd7101acacfbc
1 /* AIX FPU-related code.
2 Copyright (C) 2005-2024 Free Software Foundation, Inc.
3 Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
5 This file is part of the GNU Fortran runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 /* FPU-related code for AIX. */
28 #ifdef HAVE_FPTRAP_H
29 #include <fptrap.h>
30 #endif
32 #ifdef HAVE_FPXCP_H
33 #include <fpxcp.h>
34 #endif
36 #ifdef HAVE_FENV_H
37 #include <fenv.h>
38 #endif
41 /* Check we can actually store the FPU state in the allocated size. */
42 _Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
43 "GFC_FPE_STATE_BUFFER_SIZE is too small");
46 void
47 set_fpu_trap_exceptions (int trap, int notrap)
49 fptrap_t mode_set = 0, mode_clr = 0;
51 #ifdef TRP_INVALID
52 if (trap & GFC_FPE_INVALID)
53 mode_set |= TRP_INVALID;
54 if (notrap & GFC_FPE_INVALID)
55 mode_clr |= TRP_INVALID;
56 #endif
58 #ifdef TRP_DIV_BY_ZERO
59 if (trap & GFC_FPE_ZERO)
60 mode_set |= TRP_DIV_BY_ZERO;
61 if (notrap & GFC_FPE_ZERO)
62 mode_clr |= TRP_DIV_BY_ZERO;
63 #endif
65 #ifdef TRP_OVERFLOW
66 if (trap & GFC_FPE_OVERFLOW)
67 mode_set |= TRP_OVERFLOW;
68 if (notrap & GFC_FPE_OVERFLOW)
69 mode_clr |= TRP_OVERFLOW;
70 #endif
72 #ifdef TRP_UNDERFLOW
73 if (trap & GFC_FPE_UNDERFLOW)
74 mode_set |= TRP_UNDERFLOW;
75 if (notrap & GFC_FPE_UNDERFLOW)
76 mode_clr |= TRP_UNDERFLOW;
77 #endif
79 #ifdef TRP_INEXACT
80 if (trap & GFC_FPE_INEXACT)
81 mode_set |= TRP_INEXACT;
82 if (notrap & GFC_FPE_INEXACT)
83 mode_clr |= TRP_INEXACT;
84 #endif
86 fp_trap (FP_TRAP_SYNC);
87 fp_enable (mode_set);
88 fp_disable (mode_clr);
92 int
93 get_fpu_trap_exceptions (void)
95 int res = 0;
97 #ifdef TRP_INVALID
98 if (fp_is_enabled (TRP_INVALID))
99 res |= GFC_FPE_INVALID;
100 #endif
102 #ifdef TRP_DIV_BY_ZERO
103 if (fp_is_enabled (TRP_DIV_BY_ZERO))
104 res |= GFC_FPE_ZERO;
105 #endif
107 #ifdef TRP_OVERFLOW
108 if (fp_is_enabled (TRP_OVERFLOW))
109 res |= GFC_FPE_OVERFLOW;
110 #endif
112 #ifdef TRP_UNDERFLOW
113 if (fp_is_enabled (TRP_UNDERFLOW))
114 res |= GFC_FPE_UNDERFLOW;
115 #endif
117 #ifdef TRP_INEXACT
118 if (fp_is_enabled (TRP_INEXACT))
119 res |= GFC_FPE_INEXACT;
120 #endif
122 return res;
127 support_fpu_trap (int flag)
129 return support_fpu_flag (flag);
133 void
134 set_fpu (void)
136 #ifndef TRP_INVALID
137 if (options.fpe & GFC_FPE_INVALID)
138 estr_write ("Fortran runtime warning: IEEE 'invalid operation' "
139 "exception not supported.\n");
140 #endif
142 if (options.fpe & GFC_FPE_DENORMAL)
143 estr_write ("Fortran runtime warning: Floating point 'denormal operand' "
144 "exception not supported.\n");
146 #ifndef TRP_DIV_BY_ZERO
147 if (options.fpe & GFC_FPE_ZERO)
148 estr_write ("Fortran runtime warning: IEEE 'division by zero' "
149 "exception not supported.\n");
150 #endif
152 #ifndef TRP_OVERFLOW
153 if (options.fpe & GFC_FPE_OVERFLOW)
154 estr_write ("Fortran runtime warning: IEEE 'overflow' "
155 "exception not supported.\n");
156 #endif
158 #ifndef TRP_UNDERFLOW
159 if (options.fpe & GFC_FPE_UNDERFLOW)
160 estr_write ("Fortran runtime warning: IEEE 'underflow' "
161 "exception not supported.\n");
162 #endif
164 #ifndef TRP_INEXACT
165 if (options.fpe & GFC_FPE_INEXACT)
166 estr_write ("Fortran runtime warning: IEEE 'inexact' "
167 "exception not supported.\n");
168 #endif
170 set_fpu_trap_exceptions (options.fpe, 0);
174 get_fpu_except_flags (void)
176 int result, set_excepts;
178 result = 0;
180 #ifdef HAVE_FPXCP_H
181 if (!fp_any_xcp ())
182 return 0;
184 if (fp_invalid_op ())
185 result |= GFC_FPE_INVALID;
187 if (fp_divbyzero ())
188 result |= GFC_FPE_ZERO;
190 if (fp_overflow ())
191 result |= GFC_FPE_OVERFLOW;
193 if (fp_underflow ())
194 result |= GFC_FPE_UNDERFLOW;
196 if (fp_inexact ())
197 result |= GFC_FPE_INEXACT;
198 #endif
200 return result;
204 void
205 set_fpu_except_flags (int set, int clear)
207 int exc_set = 0, exc_clr = 0;
209 #ifdef FP_INVALID
210 if (set & GFC_FPE_INVALID)
211 exc_set |= FP_INVALID;
212 else if (clear & GFC_FPE_INVALID)
213 exc_clr |= FP_INVALID;
214 #endif
216 #ifdef FP_DIV_BY_ZERO
217 if (set & GFC_FPE_ZERO)
218 exc_set |= FP_DIV_BY_ZERO;
219 else if (clear & GFC_FPE_ZERO)
220 exc_clr |= FP_DIV_BY_ZERO;
221 #endif
223 #ifdef FP_OVERFLOW
224 if (set & GFC_FPE_OVERFLOW)
225 exc_set |= FP_OVERFLOW;
226 else if (clear & GFC_FPE_OVERFLOW)
227 exc_clr |= FP_OVERFLOW;
228 #endif
230 #ifdef FP_UNDERFLOW
231 if (set & GFC_FPE_UNDERFLOW)
232 exc_set |= FP_UNDERFLOW;
233 else if (clear & GFC_FPE_UNDERFLOW)
234 exc_clr |= FP_UNDERFLOW;
235 #endif
237 /* AIX does not have FP_DENORMAL. */
239 #ifdef FP_INEXACT
240 if (set & GFC_FPE_INEXACT)
241 exc_set |= FP_INEXACT;
242 else if (clear & GFC_FPE_INEXACT)
243 exc_clr |= FP_INEXACT;
244 #endif
246 fp_clr_flag (exc_clr);
247 fp_set_flag (exc_set);
252 support_fpu_flag (int flag)
254 if (flag & GFC_FPE_INVALID)
256 #ifndef FP_INVALID
257 return 0;
258 #endif
260 else if (flag & GFC_FPE_ZERO)
262 #ifndef FP_DIV_BY_ZERO
263 return 0;
264 #endif
266 else if (flag & GFC_FPE_OVERFLOW)
268 #ifndef FP_OVERFLOW
269 return 0;
270 #endif
272 else if (flag & GFC_FPE_UNDERFLOW)
274 #ifndef FP_UNDERFLOW
275 return 0;
276 #endif
278 else if (flag & GFC_FPE_DENORMAL)
280 /* AIX does not support denormal flag. */
281 return 0;
283 else if (flag & GFC_FPE_INEXACT)
285 #ifndef FP_INEXACT
286 return 0;
287 #endif
290 return 1;
295 get_fpu_rounding_mode (void)
297 int rnd_mode;
299 rnd_mode = fegetround ();
301 switch (rnd_mode)
303 #ifdef FE_TONEAREST
304 case FE_TONEAREST:
305 return GFC_FPE_TONEAREST;
306 #endif
308 #ifdef FE_UPWARD
309 case FE_UPWARD:
310 return GFC_FPE_UPWARD;
311 #endif
313 #ifdef FE_DOWNWARD
314 case FE_DOWNWARD:
315 return GFC_FPE_DOWNWARD;
316 #endif
318 #ifdef FE_TOWARDZERO
319 case FE_TOWARDZERO:
320 return GFC_FPE_TOWARDZERO;
321 #endif
323 #ifdef FE_TONEARESTFROMZERO
324 case FE_TONEARESTFROMZERO:
325 return GFC_FPE_AWAY;
326 #endif
328 default:
329 return 0; /* Should be unreachable. */
334 void
335 set_fpu_rounding_mode (int mode)
337 int rnd_mode;
339 switch (mode)
341 #ifdef FE_TONEAREST
342 case GFC_FPE_TONEAREST:
343 rnd_mode = FE_TONEAREST;
344 break;
345 #endif
347 #ifdef FE_UPWARD
348 case GFC_FPE_UPWARD:
349 rnd_mode = FE_UPWARD;
350 break;
351 #endif
353 #ifdef FE_DOWNWARD
354 case GFC_FPE_DOWNWARD:
355 rnd_mode = FE_DOWNWARD;
356 break;
357 #endif
359 #ifdef FE_TOWARDZERO
360 case GFC_FPE_TOWARDZERO:
361 rnd_mode = FE_TOWARDZERO;
362 break;
363 #endif
365 #ifdef FE_TONEARESTFROMZERO
366 case GFC_FPE_AWAY:
367 rnd_mode = FE_TONEARESTFROMZERO;
368 break;
369 #endif
371 default:
372 return;
375 fesetround (rnd_mode);
380 support_fpu_rounding_mode (int mode)
382 switch (mode)
384 case GFC_FPE_TONEAREST:
385 #ifdef FE_TONEAREST
386 return 1;
387 #else
388 return 0;
389 #endif
391 case GFC_FPE_UPWARD:
392 #ifdef FE_UPWARD
393 return 1;
394 #else
395 return 0;
396 #endif
398 case GFC_FPE_DOWNWARD:
399 #ifdef FE_DOWNWARD
400 return 1;
401 #else
402 return 0;
403 #endif
405 case GFC_FPE_TOWARDZERO:
406 #ifdef FE_TOWARDZERO
407 return 1;
408 #else
409 return 0;
410 #endif
412 case GFC_FPE_AWAY:
413 #ifdef FE_TONEARESTFROMZERO
414 return 1;
415 #else
416 return 0;
417 #endif
419 default:
420 return 0;
426 void
427 get_fpu_state (void *state)
429 fegetenv (state);
432 void
433 set_fpu_state (void *state)
435 fesetenv (state);
440 support_fpu_underflow_control (int kind __attribute__((unused)))
442 return 0;
447 get_fpu_underflow_mode (void)
449 return 0;
453 void
454 set_fpu_underflow_mode (int gradual __attribute__((unused)))