1 ! Implementation of the IEEE_ARITHMETIC standard intrinsic module
2 ! Copyright (C) 2013-2022 Free Software Foundation, Inc.
3 ! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
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/>. */
28 #include "c99_protos.inc"
29 #include "fpu-target.inc"
31 module IEEE_ARITHMETIC
37 ! Every public symbol from IEEE_EXCEPTIONS must be made public here
38 public :: IEEE_FLAG_TYPE, IEEE_INVALID, IEEE_OVERFLOW, &
39 IEEE_DIVIDE_BY_ZERO, IEEE_UNDERFLOW, IEEE_INEXACT, IEEE_USUAL, &
40 IEEE_ALL, IEEE_STATUS_TYPE, IEEE_GET_FLAG, IEEE_GET_HALTING_MODE, &
41 IEEE_GET_STATUS, IEEE_SET_FLAG, IEEE_SET_HALTING_MODE, &
42 IEEE_SET_STATUS, IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING
44 ! Derived types and named constants
46 type, public :: IEEE_CLASS_TYPE
51 type(IEEE_CLASS_TYPE), parameter, public :: &
52 IEEE_OTHER_VALUE = IEEE_CLASS_TYPE(0), &
53 IEEE_SIGNALING_NAN = IEEE_CLASS_TYPE(1), &
54 IEEE_QUIET_NAN = IEEE_CLASS_TYPE(2), &
55 IEEE_NEGATIVE_INF = IEEE_CLASS_TYPE(3), &
56 IEEE_NEGATIVE_NORMAL = IEEE_CLASS_TYPE(4), &
57 IEEE_NEGATIVE_DENORMAL = IEEE_CLASS_TYPE(5), &
58 IEEE_NEGATIVE_SUBNORMAL= IEEE_CLASS_TYPE(5), &
59 IEEE_NEGATIVE_ZERO = IEEE_CLASS_TYPE(6), &
60 IEEE_POSITIVE_ZERO = IEEE_CLASS_TYPE(7), &
61 IEEE_POSITIVE_DENORMAL = IEEE_CLASS_TYPE(8), &
62 IEEE_POSITIVE_SUBNORMAL= IEEE_CLASS_TYPE(8), &
63 IEEE_POSITIVE_NORMAL = IEEE_CLASS_TYPE(9), &
64 IEEE_POSITIVE_INF = IEEE_CLASS_TYPE(10)
66 type, public :: IEEE_ROUND_TYPE
71 type(IEEE_ROUND_TYPE), parameter, public :: &
72 IEEE_NEAREST = IEEE_ROUND_TYPE(GFC_FPE_TONEAREST), &
73 IEEE_TO_ZERO = IEEE_ROUND_TYPE(GFC_FPE_TOWARDZERO), &
74 IEEE_UP = IEEE_ROUND_TYPE(GFC_FPE_UPWARD), &
75 IEEE_DOWN = IEEE_ROUND_TYPE(GFC_FPE_DOWNWARD), &
76 IEEE_OTHER = IEEE_ROUND_TYPE(0)
79 ! Equality operators on the derived types
80 ! Note, the FE overloads .eq. to == and .ne. to /=
81 interface operator (.eq.)
82 module procedure IEEE_CLASS_TYPE_EQ, IEEE_ROUND_TYPE_EQ
84 public :: operator(.eq.)
86 interface operator (.ne.)
87 module procedure IEEE_CLASS_TYPE_NE, IEEE_ROUND_TYPE_NE
89 public :: operator (.ne.)
95 elemental logical function _gfortran_ieee_is_finite_4(X)
96 real(kind=4), intent(in) :: X
98 elemental logical function _gfortran_ieee_is_finite_8(X)
99 real(kind=8), intent(in) :: X
101 #ifdef HAVE_GFC_REAL_10
102 elemental logical function _gfortran_ieee_is_finite_10(X)
103 real(kind=10), intent(in) :: X
106 #ifdef HAVE_GFC_REAL_16
107 elemental logical function _gfortran_ieee_is_finite_16(X)
108 real(kind=16), intent(in) :: X
113 interface IEEE_IS_FINITE
115 #ifdef HAVE_GFC_REAL_16
116 _gfortran_ieee_is_finite_16, &
118 #ifdef HAVE_GFC_REAL_10
119 _gfortran_ieee_is_finite_10, &
121 _gfortran_ieee_is_finite_8, _gfortran_ieee_is_finite_4
123 public :: IEEE_IS_FINITE
128 elemental logical function _gfortran_ieee_is_nan_4(X)
129 real(kind=4), intent(in) :: X
131 elemental logical function _gfortran_ieee_is_nan_8(X)
132 real(kind=8), intent(in) :: X
134 #ifdef HAVE_GFC_REAL_10
135 elemental logical function _gfortran_ieee_is_nan_10(X)
136 real(kind=10), intent(in) :: X
139 #ifdef HAVE_GFC_REAL_16
140 elemental logical function _gfortran_ieee_is_nan_16(X)
141 real(kind=16), intent(in) :: X
146 interface IEEE_IS_NAN
148 #ifdef HAVE_GFC_REAL_16
149 _gfortran_ieee_is_nan_16, &
151 #ifdef HAVE_GFC_REAL_10
152 _gfortran_ieee_is_nan_10, &
154 _gfortran_ieee_is_nan_8, _gfortran_ieee_is_nan_4
156 public :: IEEE_IS_NAN
161 elemental logical function _gfortran_ieee_is_negative_4(X)
162 real(kind=4), intent(in) :: X
164 elemental logical function _gfortran_ieee_is_negative_8(X)
165 real(kind=8), intent(in) :: X
167 #ifdef HAVE_GFC_REAL_10
168 elemental logical function _gfortran_ieee_is_negative_10(X)
169 real(kind=10), intent(in) :: X
172 #ifdef HAVE_GFC_REAL_16
173 elemental logical function _gfortran_ieee_is_negative_16(X)
174 real(kind=16), intent(in) :: X
179 interface IEEE_IS_NEGATIVE
181 #ifdef HAVE_GFC_REAL_16
182 _gfortran_ieee_is_negative_16, &
184 #ifdef HAVE_GFC_REAL_10
185 _gfortran_ieee_is_negative_10, &
187 _gfortran_ieee_is_negative_8, _gfortran_ieee_is_negative_4
189 public :: IEEE_IS_NEGATIVE
194 elemental logical function _gfortran_ieee_is_normal_4(X)
195 real(kind=4), intent(in) :: X
197 elemental logical function _gfortran_ieee_is_normal_8(X)
198 real(kind=8), intent(in) :: X
200 #ifdef HAVE_GFC_REAL_10
201 elemental logical function _gfortran_ieee_is_normal_10(X)
202 real(kind=10), intent(in) :: X
205 #ifdef HAVE_GFC_REAL_16
206 elemental logical function _gfortran_ieee_is_normal_16(X)
207 real(kind=16), intent(in) :: X
212 interface IEEE_IS_NORMAL
214 #ifdef HAVE_GFC_REAL_16
215 _gfortran_ieee_is_normal_16, &
217 #ifdef HAVE_GFC_REAL_10
218 _gfortran_ieee_is_normal_10, &
220 _gfortran_ieee_is_normal_8, _gfortran_ieee_is_normal_4
222 public :: IEEE_IS_NORMAL
226 #define COPYSIGN_MACRO(A,B) \
227 elemental real(kind = A) function \
228 _gfortran_ieee_copy_sign_/**/A/**/_/**/B (X,Y) ; \
229 real(kind = A), intent(in) :: X ; \
230 real(kind = B), intent(in) :: Y ; \
234 #ifdef HAVE_GFC_REAL_16
235 COPYSIGN_MACRO(16,16)
236 #ifdef HAVE_GFC_REAL_10
237 COPYSIGN_MACRO(16,10)
238 COPYSIGN_MACRO(10,16)
245 #ifdef HAVE_GFC_REAL_10
246 COPYSIGN_MACRO(10,10)
258 interface IEEE_COPY_SIGN
260 #ifdef HAVE_GFC_REAL_16
261 _gfortran_ieee_copy_sign_16_16, &
262 #ifdef HAVE_GFC_REAL_10
263 _gfortran_ieee_copy_sign_16_10, &
264 _gfortran_ieee_copy_sign_10_16, &
266 _gfortran_ieee_copy_sign_16_8, &
267 _gfortran_ieee_copy_sign_16_4, &
268 _gfortran_ieee_copy_sign_8_16, &
269 _gfortran_ieee_copy_sign_4_16, &
271 #ifdef HAVE_GFC_REAL_10
272 _gfortran_ieee_copy_sign_10_10, &
273 _gfortran_ieee_copy_sign_10_8, &
274 _gfortran_ieee_copy_sign_10_4, &
275 _gfortran_ieee_copy_sign_8_10, &
276 _gfortran_ieee_copy_sign_4_10, &
278 _gfortran_ieee_copy_sign_8_8, &
279 _gfortran_ieee_copy_sign_8_4, &
280 _gfortran_ieee_copy_sign_4_8, &
281 _gfortran_ieee_copy_sign_4_4
283 public :: IEEE_COPY_SIGN
287 #define UNORDERED_MACRO(A,B) \
288 elemental logical function \
289 _gfortran_ieee_unordered_/**/A/**/_/**/B (X,Y) ; \
290 real(kind = A), intent(in) :: X ; \
291 real(kind = B), intent(in) :: Y ; \
295 #ifdef HAVE_GFC_REAL_16
296 UNORDERED_MACRO(16,16)
297 #ifdef HAVE_GFC_REAL_10
298 UNORDERED_MACRO(16,10)
299 UNORDERED_MACRO(10,16)
301 UNORDERED_MACRO(16,8)
302 UNORDERED_MACRO(16,4)
303 UNORDERED_MACRO(8,16)
304 UNORDERED_MACRO(4,16)
306 #ifdef HAVE_GFC_REAL_10
307 UNORDERED_MACRO(10,10)
308 UNORDERED_MACRO(10,8)
309 UNORDERED_MACRO(10,4)
310 UNORDERED_MACRO(8,10)
311 UNORDERED_MACRO(4,10)
319 interface IEEE_UNORDERED
321 #ifdef HAVE_GFC_REAL_16
322 _gfortran_ieee_unordered_16_16, &
323 #ifdef HAVE_GFC_REAL_10
324 _gfortran_ieee_unordered_16_10, &
325 _gfortran_ieee_unordered_10_16, &
327 _gfortran_ieee_unordered_16_8, &
328 _gfortran_ieee_unordered_16_4, &
329 _gfortran_ieee_unordered_8_16, &
330 _gfortran_ieee_unordered_4_16, &
332 #ifdef HAVE_GFC_REAL_10
333 _gfortran_ieee_unordered_10_10, &
334 _gfortran_ieee_unordered_10_8, &
335 _gfortran_ieee_unordered_10_4, &
336 _gfortran_ieee_unordered_8_10, &
337 _gfortran_ieee_unordered_4_10, &
339 _gfortran_ieee_unordered_8_8, &
340 _gfortran_ieee_unordered_8_4, &
341 _gfortran_ieee_unordered_4_8, &
342 _gfortran_ieee_unordered_4_4
344 public :: IEEE_UNORDERED
349 elemental real(kind=4) function _gfortran_ieee_logb_4 (X)
350 real(kind=4), intent(in) :: X
352 elemental real(kind=8) function _gfortran_ieee_logb_8 (X)
353 real(kind=8), intent(in) :: X
355 #ifdef HAVE_GFC_REAL_10
356 elemental real(kind=10) function _gfortran_ieee_logb_10 (X)
357 real(kind=10), intent(in) :: X
360 #ifdef HAVE_GFC_REAL_16
361 elemental real(kind=16) function _gfortran_ieee_logb_16 (X)
362 real(kind=16), intent(in) :: X
369 #ifdef HAVE_GFC_REAL_16
370 _gfortran_ieee_logb_16, &
372 #ifdef HAVE_GFC_REAL_10
373 _gfortran_ieee_logb_10, &
375 _gfortran_ieee_logb_8, &
376 _gfortran_ieee_logb_4
382 #define NEXT_AFTER_MACRO(A,B) \
383 elemental real(kind = A) function \
384 _gfortran_ieee_next_after_/**/A/**/_/**/B (X,Y) ; \
385 real(kind = A), intent(in) :: X ; \
386 real(kind = B), intent(in) :: Y ; \
390 #ifdef HAVE_GFC_REAL_16
391 NEXT_AFTER_MACRO(16,16)
392 #ifdef HAVE_GFC_REAL_10
393 NEXT_AFTER_MACRO(16,10)
394 NEXT_AFTER_MACRO(10,16)
396 NEXT_AFTER_MACRO(16,8)
397 NEXT_AFTER_MACRO(16,4)
398 NEXT_AFTER_MACRO(8,16)
399 NEXT_AFTER_MACRO(4,16)
401 #ifdef HAVE_GFC_REAL_10
402 NEXT_AFTER_MACRO(10,10)
403 NEXT_AFTER_MACRO(10,8)
404 NEXT_AFTER_MACRO(10,4)
405 NEXT_AFTER_MACRO(8,10)
406 NEXT_AFTER_MACRO(4,10)
408 NEXT_AFTER_MACRO(8,8)
409 NEXT_AFTER_MACRO(8,4)
410 NEXT_AFTER_MACRO(4,8)
411 NEXT_AFTER_MACRO(4,4)
414 interface IEEE_NEXT_AFTER
416 #ifdef HAVE_GFC_REAL_16
417 _gfortran_ieee_next_after_16_16, &
418 #ifdef HAVE_GFC_REAL_10
419 _gfortran_ieee_next_after_16_10, &
420 _gfortran_ieee_next_after_10_16, &
422 _gfortran_ieee_next_after_16_8, &
423 _gfortran_ieee_next_after_16_4, &
424 _gfortran_ieee_next_after_8_16, &
425 _gfortran_ieee_next_after_4_16, &
427 #ifdef HAVE_GFC_REAL_10
428 _gfortran_ieee_next_after_10_10, &
429 _gfortran_ieee_next_after_10_8, &
430 _gfortran_ieee_next_after_10_4, &
431 _gfortran_ieee_next_after_8_10, &
432 _gfortran_ieee_next_after_4_10, &
434 _gfortran_ieee_next_after_8_8, &
435 _gfortran_ieee_next_after_8_4, &
436 _gfortran_ieee_next_after_4_8, &
437 _gfortran_ieee_next_after_4_4
439 public :: IEEE_NEXT_AFTER
443 #define REM_MACRO(RES,A,B) \
444 elemental real(kind = RES) function \
445 _gfortran_ieee_rem_/**/A/**/_/**/B (X,Y) ; \
446 real(kind = A), intent(in) :: X ; \
447 real(kind = B), intent(in) :: Y ; \
451 #ifdef HAVE_GFC_REAL_16
453 #ifdef HAVE_GFC_REAL_10
462 #ifdef HAVE_GFC_REAL_10
477 #ifdef HAVE_GFC_REAL_16
478 _gfortran_ieee_rem_16_16, &
479 #ifdef HAVE_GFC_REAL_10
480 _gfortran_ieee_rem_16_10, &
481 _gfortran_ieee_rem_10_16, &
483 _gfortran_ieee_rem_16_8, &
484 _gfortran_ieee_rem_16_4, &
485 _gfortran_ieee_rem_8_16, &
486 _gfortran_ieee_rem_4_16, &
488 #ifdef HAVE_GFC_REAL_10
489 _gfortran_ieee_rem_10_10, &
490 _gfortran_ieee_rem_10_8, &
491 _gfortran_ieee_rem_10_4, &
492 _gfortran_ieee_rem_8_10, &
493 _gfortran_ieee_rem_4_10, &
495 _gfortran_ieee_rem_8_8, &
496 _gfortran_ieee_rem_8_4, &
497 _gfortran_ieee_rem_4_8, &
498 _gfortran_ieee_rem_4_4
505 elemental real(kind=4) function _gfortran_ieee_rint_4 (X)
506 real(kind=4), intent(in) :: X
508 elemental real(kind=8) function _gfortran_ieee_rint_8 (X)
509 real(kind=8), intent(in) :: X
511 #ifdef HAVE_GFC_REAL_10
512 elemental real(kind=10) function _gfortran_ieee_rint_10 (X)
513 real(kind=10), intent(in) :: X
516 #ifdef HAVE_GFC_REAL_16
517 elemental real(kind=16) function _gfortran_ieee_rint_16 (X)
518 real(kind=16), intent(in) :: X
525 #ifdef HAVE_GFC_REAL_16
526 _gfortran_ieee_rint_16, &
528 #ifdef HAVE_GFC_REAL_10
529 _gfortran_ieee_rint_10, &
531 _gfortran_ieee_rint_8, _gfortran_ieee_rint_4
538 #ifdef HAVE_GFC_INTEGER_16
539 #ifdef HAVE_GFC_REAL_16
540 elemental real(kind=16) function _gfortran_ieee_scalb_16_16 (X, I)
541 real(kind=16), intent(in) :: X
542 integer(kind=16), intent(in) :: I
545 #ifdef HAVE_GFC_REAL_10
546 elemental real(kind=10) function _gfortran_ieee_scalb_10_16 (X, I)
547 real(kind=10), intent(in) :: X
548 integer(kind=16), intent(in) :: I
551 elemental real(kind=8) function _gfortran_ieee_scalb_8_16 (X, I)
552 real(kind=8), intent(in) :: X
553 integer(kind=16), intent(in) :: I
555 elemental real(kind=4) function _gfortran_ieee_scalb_4_16 (X, I)
556 real(kind=4), intent(in) :: X
557 integer(kind=16), intent(in) :: I
561 #ifdef HAVE_GFC_INTEGER_8
562 #ifdef HAVE_GFC_REAL_16
563 elemental real(kind=16) function _gfortran_ieee_scalb_16_8 (X, I)
564 real(kind=16), intent(in) :: X
565 integer(kind=8), intent(in) :: I
568 #ifdef HAVE_GFC_REAL_10
569 elemental real(kind=10) function _gfortran_ieee_scalb_10_8 (X, I)
570 real(kind=10), intent(in) :: X
571 integer(kind=8), intent(in) :: I
574 elemental real(kind=8) function _gfortran_ieee_scalb_8_8 (X, I)
575 real(kind=8), intent(in) :: X
576 integer(kind=8), intent(in) :: I
578 elemental real(kind=4) function _gfortran_ieee_scalb_4_8 (X, I)
579 real(kind=4), intent(in) :: X
580 integer(kind=8), intent(in) :: I
584 #ifdef HAVE_GFC_INTEGER_2
585 #ifdef HAVE_GFC_REAL_16
586 elemental real(kind=16) function _gfortran_ieee_scalb_16_2 (X, I)
587 real(kind=16), intent(in) :: X
588 integer(kind=2), intent(in) :: I
591 #ifdef HAVE_GFC_REAL_10
592 elemental real(kind=10) function _gfortran_ieee_scalb_10_2 (X, I)
593 real(kind=10), intent(in) :: X
594 integer(kind=2), intent(in) :: I
597 elemental real(kind=8) function _gfortran_ieee_scalb_8_2 (X, I)
598 real(kind=8), intent(in) :: X
599 integer(kind=2), intent(in) :: I
601 elemental real(kind=4) function _gfortran_ieee_scalb_4_2 (X, I)
602 real(kind=4), intent(in) :: X
603 integer(kind=2), intent(in) :: I
607 #ifdef HAVE_GFC_INTEGER_1
608 #ifdef HAVE_GFC_REAL_16
609 elemental real(kind=16) function _gfortran_ieee_scalb_16_1 (X, I)
610 real(kind=16), intent(in) :: X
611 integer(kind=1), intent(in) :: I
614 #ifdef HAVE_GFC_REAL_10
615 elemental real(kind=10) function _gfortran_ieee_scalb_10_1 (X, I)
616 real(kind=10), intent(in) :: X
617 integer(kind=1), intent(in) :: I
620 elemental real(kind=8) function _gfortran_ieee_scalb_8_1 (X, I)
621 real(kind=8), intent(in) :: X
622 integer(kind=1), intent(in) :: I
624 elemental real(kind=4) function _gfortran_ieee_scalb_4_1 (X, I)
625 real(kind=4), intent(in) :: X
626 integer(kind=1), intent(in) :: I
630 #ifdef HAVE_GFC_REAL_16
631 elemental real(kind=16) function _gfortran_ieee_scalb_16_4 (X, I)
632 real(kind=16), intent(in) :: X
633 integer, intent(in) :: I
636 #ifdef HAVE_GFC_REAL_10
637 elemental real(kind=10) function _gfortran_ieee_scalb_10_4 (X, I)
638 real(kind=10), intent(in) :: X
639 integer, intent(in) :: I
642 elemental real(kind=8) function _gfortran_ieee_scalb_8_4 (X, I)
643 real(kind=8), intent(in) :: X
644 integer, intent(in) :: I
646 elemental real(kind=4) function _gfortran_ieee_scalb_4_4 (X, I)
647 real(kind=4), intent(in) :: X
648 integer, intent(in) :: I
654 #ifdef HAVE_GFC_INTEGER_16
655 #ifdef HAVE_GFC_REAL_16
656 _gfortran_ieee_scalb_16_16, &
658 #ifdef HAVE_GFC_REAL_10
659 _gfortran_ieee_scalb_10_16, &
661 _gfortran_ieee_scalb_8_16, &
662 _gfortran_ieee_scalb_4_16, &
664 #ifdef HAVE_GFC_INTEGER_8
665 #ifdef HAVE_GFC_REAL_16
666 _gfortran_ieee_scalb_16_8, &
668 #ifdef HAVE_GFC_REAL_10
669 _gfortran_ieee_scalb_10_8, &
671 _gfortran_ieee_scalb_8_8, &
672 _gfortran_ieee_scalb_4_8, &
674 #ifdef HAVE_GFC_INTEGER_2
675 #ifdef HAVE_GFC_REAL_16
676 _gfortran_ieee_scalb_16_2, &
678 #ifdef HAVE_GFC_REAL_10
679 _gfortran_ieee_scalb_10_2, &
681 _gfortran_ieee_scalb_8_2, &
682 _gfortran_ieee_scalb_4_2, &
684 #ifdef HAVE_GFC_INTEGER_1
685 #ifdef HAVE_GFC_REAL_16
686 _gfortran_ieee_scalb_16_1, &
688 #ifdef HAVE_GFC_REAL_10
689 _gfortran_ieee_scalb_10_1, &
691 _gfortran_ieee_scalb_8_1, &
692 _gfortran_ieee_scalb_4_1, &
694 #ifdef HAVE_GFC_REAL_16
695 _gfortran_ieee_scalb_16_4, &
697 #ifdef HAVE_GFC_REAL_10
698 _gfortran_ieee_scalb_10_4, &
700 _gfortran_ieee_scalb_8_4, &
701 _gfortran_ieee_scalb_4_4
709 #ifdef HAVE_GFC_REAL_16
712 #ifdef HAVE_GFC_REAL_10
715 IEEE_VALUE_8, IEEE_VALUE_4
723 #ifdef HAVE_GFC_REAL_16
726 #ifdef HAVE_GFC_REAL_10
729 IEEE_CLASS_8, IEEE_CLASS_4
733 ! Public declarations for contained procedures
734 public :: IEEE_GET_ROUNDING_MODE, IEEE_SET_ROUNDING_MODE
735 public :: IEEE_GET_UNDERFLOW_MODE, IEEE_SET_UNDERFLOW_MODE
736 public :: IEEE_SELECTED_REAL_KIND
738 ! IEEE_SUPPORT_ROUNDING
740 interface IEEE_SUPPORT_ROUNDING
741 module procedure IEEE_SUPPORT_ROUNDING_4, IEEE_SUPPORT_ROUNDING_8, &
742 #ifdef HAVE_GFC_REAL_10
743 IEEE_SUPPORT_ROUNDING_10, &
745 #ifdef HAVE_GFC_REAL_16
746 IEEE_SUPPORT_ROUNDING_16, &
748 IEEE_SUPPORT_ROUNDING_NOARG
750 public :: IEEE_SUPPORT_ROUNDING
752 ! Interface to the FPU-specific function
754 pure integer function support_rounding_helper(flag) &
755 bind(c, name="_gfortrani_support_fpu_rounding_mode")
756 integer, intent(in), value :: flag
760 ! IEEE_SUPPORT_UNDERFLOW_CONTROL
762 interface IEEE_SUPPORT_UNDERFLOW_CONTROL
763 module procedure IEEE_SUPPORT_UNDERFLOW_CONTROL_4, &
764 IEEE_SUPPORT_UNDERFLOW_CONTROL_8, &
765 #ifdef HAVE_GFC_REAL_10
766 IEEE_SUPPORT_UNDERFLOW_CONTROL_10, &
768 #ifdef HAVE_GFC_REAL_16
769 IEEE_SUPPORT_UNDERFLOW_CONTROL_16, &
771 IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG
773 public :: IEEE_SUPPORT_UNDERFLOW_CONTROL
775 ! Interface to the FPU-specific function
777 pure integer function support_underflow_control_helper(kind) &
778 bind(c, name="_gfortrani_support_fpu_underflow_control")
779 integer, intent(in), value :: kind
783 ! IEEE_SUPPORT_* generic functions
785 #if defined(HAVE_GFC_REAL_10) && defined(HAVE_GFC_REAL_16)
786 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_16, NAME/**/_NOARG
787 #elif defined(HAVE_GFC_REAL_10)
788 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_NOARG
789 #elif defined(HAVE_GFC_REAL_16)
790 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_16, NAME/**/_NOARG
792 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_NOARG
795 #define SUPPORTGENERIC(NAME) \
796 interface NAME ; module procedure MACRO1(NAME) ; end interface ; \
799 SUPPORTGENERIC(IEEE_SUPPORT_DATATYPE)
800 SUPPORTGENERIC(IEEE_SUPPORT_DENORMAL)
801 SUPPORTGENERIC(IEEE_SUPPORT_SUBNORMAL)
802 SUPPORTGENERIC(IEEE_SUPPORT_DIVIDE)
803 SUPPORTGENERIC(IEEE_SUPPORT_INF)
804 SUPPORTGENERIC(IEEE_SUPPORT_IO)
805 SUPPORTGENERIC(IEEE_SUPPORT_NAN)
806 SUPPORTGENERIC(IEEE_SUPPORT_SQRT)
807 SUPPORTGENERIC(IEEE_SUPPORT_STANDARD)
811 ! Equality operators for IEEE_CLASS_TYPE and IEEE_ROUNDING_MODE
812 elemental logical function IEEE_CLASS_TYPE_EQ (X, Y) result(res)
814 type(IEEE_CLASS_TYPE), intent(in) :: X, Y
815 res = (X%hidden == Y%hidden)
818 elemental logical function IEEE_CLASS_TYPE_NE (X, Y) result(res)
820 type(IEEE_CLASS_TYPE), intent(in) :: X, Y
821 res = (X%hidden /= Y%hidden)
824 elemental logical function IEEE_ROUND_TYPE_EQ (X, Y) result(res)
826 type(IEEE_ROUND_TYPE), intent(in) :: X, Y
827 res = (X%hidden == Y%hidden)
830 elemental logical function IEEE_ROUND_TYPE_NE (X, Y) result(res)
832 type(IEEE_ROUND_TYPE), intent(in) :: X, Y
833 res = (X%hidden /= Y%hidden)
837 ! IEEE_SELECTED_REAL_KIND
839 integer function IEEE_SELECTED_REAL_KIND (P, R, RADIX) result(res)
841 integer, intent(in), optional :: P, R, RADIX
843 ! Currently, if IEEE is supported and this module is built, it means
844 ! all our floating-point types conform to IEEE. Hence, we simply call
845 ! SELECTED_REAL_KIND.
847 res = SELECTED_REAL_KIND (P, R, RADIX)
854 elemental function IEEE_CLASS_4 (X) result(res)
856 real(kind=4), intent(in) :: X
857 type(IEEE_CLASS_TYPE) :: res
860 pure integer function _gfortrani_ieee_class_helper_4(val)
861 real(kind=4), intent(in) :: val
865 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_4(X))
868 elemental function IEEE_CLASS_8 (X) result(res)
870 real(kind=8), intent(in) :: X
871 type(IEEE_CLASS_TYPE) :: res
874 pure integer function _gfortrani_ieee_class_helper_8(val)
875 real(kind=8), intent(in) :: val
879 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_8(X))
882 #ifdef HAVE_GFC_REAL_10
883 elemental function IEEE_CLASS_10 (X) result(res)
885 real(kind=10), intent(in) :: X
886 type(IEEE_CLASS_TYPE) :: res
889 pure integer function _gfortrani_ieee_class_helper_10(val)
890 real(kind=10), intent(in) :: val
894 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_10(X))
898 #ifdef HAVE_GFC_REAL_16
899 elemental function IEEE_CLASS_16 (X) result(res)
901 real(kind=16), intent(in) :: X
902 type(IEEE_CLASS_TYPE) :: res
905 pure integer function _gfortrani_ieee_class_helper_16(val)
906 real(kind=16), intent(in) :: val
910 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_16(X))
917 elemental real(kind=4) function IEEE_VALUE_4(X, CLASS) result(res)
918 real(kind=4), intent(in) :: X
919 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
922 pure real(kind=4) function _gfortrani_ieee_value_helper_4(x)
923 use ISO_C_BINDING, only: C_INT
924 integer(kind=C_INT), value :: x
928 res = _gfortrani_ieee_value_helper_4(CLASS%hidden)
931 elemental real(kind=8) function IEEE_VALUE_8(X, CLASS) result(res)
932 real(kind=8), intent(in) :: X
933 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
936 pure real(kind=8) function _gfortrani_ieee_value_helper_8(x)
937 use ISO_C_BINDING, only: C_INT
938 integer(kind=C_INT), value :: x
942 res = _gfortrani_ieee_value_helper_8(CLASS%hidden)
945 #ifdef HAVE_GFC_REAL_10
946 elemental real(kind=10) function IEEE_VALUE_10(X, CLASS) result(res)
947 real(kind=10), intent(in) :: X
948 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
951 pure real(kind=10) function _gfortrani_ieee_value_helper_10(x)
952 use ISO_C_BINDING, only: C_INT
953 integer(kind=C_INT), value :: x
957 res = _gfortrani_ieee_value_helper_10(CLASS%hidden)
962 #ifdef HAVE_GFC_REAL_16
963 elemental real(kind=16) function IEEE_VALUE_16(X, CLASS) result(res)
964 real(kind=16), intent(in) :: X
965 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
968 pure real(kind=16) function _gfortrani_ieee_value_helper_16(x)
969 use ISO_C_BINDING, only: C_INT
970 integer(kind=C_INT), value :: x
974 res = _gfortrani_ieee_value_helper_16(CLASS%hidden)
979 ! IEEE_GET_ROUNDING_MODE
981 subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE)
983 type(IEEE_ROUND_TYPE), intent(out) :: ROUND_VALUE
986 integer function helper() &
987 bind(c, name="_gfortrani_get_fpu_rounding_mode")
991 ROUND_VALUE = IEEE_ROUND_TYPE(helper())
995 ! IEEE_SET_ROUNDING_MODE
997 subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE)
999 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1002 subroutine helper(val) &
1003 bind(c, name="_gfortrani_set_fpu_rounding_mode")
1004 integer, value :: val
1008 call helper(ROUND_VALUE%hidden)
1012 ! IEEE_GET_UNDERFLOW_MODE
1014 subroutine IEEE_GET_UNDERFLOW_MODE (GRADUAL)
1016 logical, intent(out) :: GRADUAL
1019 integer function helper() &
1020 bind(c, name="_gfortrani_get_fpu_underflow_mode")
1024 GRADUAL = (helper() /= 0)
1028 ! IEEE_SET_UNDERFLOW_MODE
1030 subroutine IEEE_SET_UNDERFLOW_MODE (GRADUAL)
1032 logical, intent(in) :: GRADUAL
1035 subroutine helper(val) &
1036 bind(c, name="_gfortrani_set_fpu_underflow_mode")
1037 integer, value :: val
1041 call helper(merge(1, 0, GRADUAL))
1044 ! IEEE_SUPPORT_ROUNDING
1046 pure logical function IEEE_SUPPORT_ROUNDING_4 (ROUND_VALUE, X) result(res)
1048 real(kind=4), intent(in) :: X
1049 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1050 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1053 pure logical function IEEE_SUPPORT_ROUNDING_8 (ROUND_VALUE, X) result(res)
1055 real(kind=8), intent(in) :: X
1056 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1057 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1060 #ifdef HAVE_GFC_REAL_10
1061 pure logical function IEEE_SUPPORT_ROUNDING_10 (ROUND_VALUE, X) result(res)
1063 real(kind=10), intent(in) :: X
1064 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1065 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1069 #ifdef HAVE_GFC_REAL_16
1070 pure logical function IEEE_SUPPORT_ROUNDING_16 (ROUND_VALUE, X) result(res)
1072 real(kind=16), intent(in) :: X
1073 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1074 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1078 pure logical function IEEE_SUPPORT_ROUNDING_NOARG (ROUND_VALUE) result(res)
1080 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1081 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1084 ! IEEE_SUPPORT_UNDERFLOW_CONTROL
1086 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_4 (X) result(res)
1088 real(kind=4), intent(in) :: X
1089 res = (support_underflow_control_helper(4) /= 0)
1092 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_8 (X) result(res)
1094 real(kind=8), intent(in) :: X
1095 res = (support_underflow_control_helper(8) /= 0)
1098 #ifdef HAVE_GFC_REAL_10
1099 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_10 (X) result(res)
1101 real(kind=10), intent(in) :: X
1102 res = (support_underflow_control_helper(10) /= 0)
1106 #ifdef HAVE_GFC_REAL_16
1107 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_16 (X) result(res)
1109 real(kind=16), intent(in) :: X
1110 res = (support_underflow_control_helper(16) /= 0)
1114 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG () result(res)
1116 res = (support_underflow_control_helper(4) /= 0 &
1117 .and. support_underflow_control_helper(8) /= 0 &
1118 #ifdef HAVE_GFC_REAL_10
1119 .and. support_underflow_control_helper(10) /= 0 &
1121 #ifdef HAVE_GFC_REAL_16
1122 .and. support_underflow_control_helper(16) /= 0 &
1127 ! IEEE_SUPPORT_* functions
1129 #define SUPPORTMACRO(NAME, INTKIND, VALUE) \
1130 pure logical function NAME/**/_/**/INTKIND (X) result(res) ; \
1132 real(INTKIND), intent(in) :: X(..) ; \
1136 #define SUPPORTMACRO_NOARG(NAME, VALUE) \
1137 pure logical function NAME/**/_NOARG () result(res) ; \
1142 ! IEEE_SUPPORT_DATATYPE
1144 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,4,.true.)
1145 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,8,.true.)
1146 #ifdef HAVE_GFC_REAL_10
1147 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,10,.true.)
1149 #ifdef HAVE_GFC_REAL_16
1150 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,16,.true.)
1152 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DATATYPE,.true.)
1154 ! IEEE_SUPPORT_DENORMAL and IEEE_SUPPORT_SUBNORMAL
1156 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,4,.true.)
1157 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,8,.true.)
1158 #ifdef HAVE_GFC_REAL_10
1159 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,10,.true.)
1161 #ifdef HAVE_GFC_REAL_16
1162 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,16,.true.)
1164 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DENORMAL,.true.)
1166 SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,4,.true.)
1167 SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,8,.true.)
1168 #ifdef HAVE_GFC_REAL_10
1169 SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,10,.true.)
1171 #ifdef HAVE_GFC_REAL_16
1172 SUPPORTMACRO(IEEE_SUPPORT_SUBNORMAL,16,.true.)
1174 SUPPORTMACRO_NOARG(IEEE_SUPPORT_SUBNORMAL,.true.)
1176 ! IEEE_SUPPORT_DIVIDE
1178 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,4,.true.)
1179 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,8,.true.)
1180 #ifdef HAVE_GFC_REAL_10
1181 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,10,.true.)
1183 #ifdef HAVE_GFC_REAL_16
1184 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,16,.true.)
1186 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DIVIDE,.true.)
1190 SUPPORTMACRO(IEEE_SUPPORT_INF,4,.true.)
1191 SUPPORTMACRO(IEEE_SUPPORT_INF,8,.true.)
1192 #ifdef HAVE_GFC_REAL_10
1193 SUPPORTMACRO(IEEE_SUPPORT_INF,10,.true.)
1195 #ifdef HAVE_GFC_REAL_16
1196 SUPPORTMACRO(IEEE_SUPPORT_INF,16,.true.)
1198 SUPPORTMACRO_NOARG(IEEE_SUPPORT_INF,.true.)
1202 SUPPORTMACRO(IEEE_SUPPORT_IO,4,.true.)
1203 SUPPORTMACRO(IEEE_SUPPORT_IO,8,.true.)
1204 #ifdef HAVE_GFC_REAL_10
1205 SUPPORTMACRO(IEEE_SUPPORT_IO,10,.true.)
1207 #ifdef HAVE_GFC_REAL_16
1208 SUPPORTMACRO(IEEE_SUPPORT_IO,16,.true.)
1210 SUPPORTMACRO_NOARG(IEEE_SUPPORT_IO,.true.)
1214 SUPPORTMACRO(IEEE_SUPPORT_NAN,4,.true.)
1215 SUPPORTMACRO(IEEE_SUPPORT_NAN,8,.true.)
1216 #ifdef HAVE_GFC_REAL_10
1217 SUPPORTMACRO(IEEE_SUPPORT_NAN,10,.true.)
1219 #ifdef HAVE_GFC_REAL_16
1220 SUPPORTMACRO(IEEE_SUPPORT_NAN,16,.true.)
1222 SUPPORTMACRO_NOARG(IEEE_SUPPORT_NAN,.true.)
1226 SUPPORTMACRO(IEEE_SUPPORT_SQRT,4,.true.)
1227 SUPPORTMACRO(IEEE_SUPPORT_SQRT,8,.true.)
1228 #ifdef HAVE_GFC_REAL_10
1229 SUPPORTMACRO(IEEE_SUPPORT_SQRT,10,.true.)
1231 #ifdef HAVE_GFC_REAL_16
1232 SUPPORTMACRO(IEEE_SUPPORT_SQRT,16,.true.)
1234 SUPPORTMACRO_NOARG(IEEE_SUPPORT_SQRT,.true.)
1236 ! IEEE_SUPPORT_STANDARD
1238 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,4,.true.)
1239 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,8,.true.)
1240 #ifdef HAVE_GFC_REAL_10
1241 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,10,.true.)
1243 #ifdef HAVE_GFC_REAL_16
1244 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,16,.true.)
1246 SUPPORTMACRO_NOARG(IEEE_SUPPORT_STANDARD,.true.)
1248 end module IEEE_ARITHMETIC