1 ! Implementation of the IEEE_ARITHMETIC standard intrinsic module
2 ! Copyright (C) 2013-2018 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_ZERO = IEEE_CLASS_TYPE(6), &
59 IEEE_POSITIVE_ZERO = IEEE_CLASS_TYPE(7), &
60 IEEE_POSITIVE_DENORMAL = IEEE_CLASS_TYPE(8), &
61 IEEE_POSITIVE_NORMAL = IEEE_CLASS_TYPE(9), &
62 IEEE_POSITIVE_INF = IEEE_CLASS_TYPE(10)
64 type, public :: IEEE_ROUND_TYPE
69 type(IEEE_ROUND_TYPE), parameter, public :: &
70 IEEE_NEAREST = IEEE_ROUND_TYPE(GFC_FPE_TONEAREST), &
71 IEEE_TO_ZERO = IEEE_ROUND_TYPE(GFC_FPE_TOWARDZERO), &
72 IEEE_UP = IEEE_ROUND_TYPE(GFC_FPE_UPWARD), &
73 IEEE_DOWN = IEEE_ROUND_TYPE(GFC_FPE_DOWNWARD), &
74 IEEE_OTHER = IEEE_ROUND_TYPE(0)
77 ! Equality operators on the derived types
78 interface operator (==)
79 module procedure IEEE_CLASS_TYPE_EQ, IEEE_ROUND_TYPE_EQ
81 public :: operator(==)
83 interface operator (/=)
84 module procedure IEEE_CLASS_TYPE_NE, IEEE_ROUND_TYPE_NE
86 public :: operator (/=)
92 elemental logical function _gfortran_ieee_is_finite_4(X)
93 real(kind=4), intent(in) :: X
95 elemental logical function _gfortran_ieee_is_finite_8(X)
96 real(kind=8), intent(in) :: X
98 #ifdef HAVE_GFC_REAL_10
99 elemental logical function _gfortran_ieee_is_finite_10(X)
100 real(kind=10), intent(in) :: X
103 #ifdef HAVE_GFC_REAL_16
104 elemental logical function _gfortran_ieee_is_finite_16(X)
105 real(kind=16), intent(in) :: X
110 interface IEEE_IS_FINITE
112 #ifdef HAVE_GFC_REAL_16
113 _gfortran_ieee_is_finite_16, &
115 #ifdef HAVE_GFC_REAL_10
116 _gfortran_ieee_is_finite_10, &
118 _gfortran_ieee_is_finite_8, _gfortran_ieee_is_finite_4
120 public :: IEEE_IS_FINITE
125 elemental logical function _gfortran_ieee_is_nan_4(X)
126 real(kind=4), intent(in) :: X
128 elemental logical function _gfortran_ieee_is_nan_8(X)
129 real(kind=8), intent(in) :: X
131 #ifdef HAVE_GFC_REAL_10
132 elemental logical function _gfortran_ieee_is_nan_10(X)
133 real(kind=10), intent(in) :: X
136 #ifdef HAVE_GFC_REAL_16
137 elemental logical function _gfortran_ieee_is_nan_16(X)
138 real(kind=16), intent(in) :: X
143 interface IEEE_IS_NAN
145 #ifdef HAVE_GFC_REAL_16
146 _gfortran_ieee_is_nan_16, &
148 #ifdef HAVE_GFC_REAL_10
149 _gfortran_ieee_is_nan_10, &
151 _gfortran_ieee_is_nan_8, _gfortran_ieee_is_nan_4
153 public :: IEEE_IS_NAN
158 elemental logical function _gfortran_ieee_is_negative_4(X)
159 real(kind=4), intent(in) :: X
161 elemental logical function _gfortran_ieee_is_negative_8(X)
162 real(kind=8), intent(in) :: X
164 #ifdef HAVE_GFC_REAL_10
165 elemental logical function _gfortran_ieee_is_negative_10(X)
166 real(kind=10), intent(in) :: X
169 #ifdef HAVE_GFC_REAL_16
170 elemental logical function _gfortran_ieee_is_negative_16(X)
171 real(kind=16), intent(in) :: X
176 interface IEEE_IS_NEGATIVE
178 #ifdef HAVE_GFC_REAL_16
179 _gfortran_ieee_is_negative_16, &
181 #ifdef HAVE_GFC_REAL_10
182 _gfortran_ieee_is_negative_10, &
184 _gfortran_ieee_is_negative_8, _gfortran_ieee_is_negative_4
186 public :: IEEE_IS_NEGATIVE
191 elemental logical function _gfortran_ieee_is_normal_4(X)
192 real(kind=4), intent(in) :: X
194 elemental logical function _gfortran_ieee_is_normal_8(X)
195 real(kind=8), intent(in) :: X
197 #ifdef HAVE_GFC_REAL_10
198 elemental logical function _gfortran_ieee_is_normal_10(X)
199 real(kind=10), intent(in) :: X
202 #ifdef HAVE_GFC_REAL_16
203 elemental logical function _gfortran_ieee_is_normal_16(X)
204 real(kind=16), intent(in) :: X
209 interface IEEE_IS_NORMAL
211 #ifdef HAVE_GFC_REAL_16
212 _gfortran_ieee_is_normal_16, &
214 #ifdef HAVE_GFC_REAL_10
215 _gfortran_ieee_is_normal_10, &
217 _gfortran_ieee_is_normal_8, _gfortran_ieee_is_normal_4
219 public :: IEEE_IS_NORMAL
223 #define COPYSIGN_MACRO(A,B) \
224 elemental real(kind = A) function \
225 _gfortran_ieee_copy_sign_/**/A/**/_/**/B (X,Y) ; \
226 real(kind = A), intent(in) :: X ; \
227 real(kind = B), intent(in) :: Y ; \
233 #ifdef HAVE_GFC_REAL_10
236 #ifdef HAVE_GFC_REAL_16
241 #ifdef HAVE_GFC_REAL_10
244 #ifdef HAVE_GFC_REAL_16
247 #ifdef HAVE_GFC_REAL_10
250 COPYSIGN_MACRO(10,10)
251 #ifdef HAVE_GFC_REAL_16
252 COPYSIGN_MACRO(10,16)
255 #ifdef HAVE_GFC_REAL_16
258 #ifdef HAVE_GFC_REAL_10
259 COPYSIGN_MACRO(16,10)
261 COPYSIGN_MACRO(16,16)
265 interface IEEE_COPY_SIGN
267 #ifdef HAVE_GFC_REAL_16
268 _gfortran_ieee_copy_sign_16_16, &
269 #ifdef HAVE_GFC_REAL_10
270 _gfortran_ieee_copy_sign_16_10, &
272 _gfortran_ieee_copy_sign_16_8, &
273 _gfortran_ieee_copy_sign_16_4, &
275 #ifdef HAVE_GFC_REAL_10
276 #ifdef HAVE_GFC_REAL_16
277 _gfortran_ieee_copy_sign_10_16, &
279 _gfortran_ieee_copy_sign_10_10, &
280 _gfortran_ieee_copy_sign_10_8, &
281 _gfortran_ieee_copy_sign_10_4, &
283 #ifdef HAVE_GFC_REAL_16
284 _gfortran_ieee_copy_sign_8_16, &
286 #ifdef HAVE_GFC_REAL_10
287 _gfortran_ieee_copy_sign_8_10, &
289 _gfortran_ieee_copy_sign_8_8, &
290 _gfortran_ieee_copy_sign_8_4, &
291 #ifdef HAVE_GFC_REAL_16
292 _gfortran_ieee_copy_sign_4_16, &
294 #ifdef HAVE_GFC_REAL_10
295 _gfortran_ieee_copy_sign_4_10, &
297 _gfortran_ieee_copy_sign_4_8, &
298 _gfortran_ieee_copy_sign_4_4
300 public :: IEEE_COPY_SIGN
304 #define UNORDERED_MACRO(A,B) \
305 elemental logical function \
306 _gfortran_ieee_unordered_/**/A/**/_/**/B (X,Y) ; \
307 real(kind = A), intent(in) :: X ; \
308 real(kind = B), intent(in) :: Y ; \
314 #ifdef HAVE_GFC_REAL_10
315 UNORDERED_MACRO(4,10)
317 #ifdef HAVE_GFC_REAL_16
318 UNORDERED_MACRO(4,16)
322 #ifdef HAVE_GFC_REAL_10
323 UNORDERED_MACRO(8,10)
325 #ifdef HAVE_GFC_REAL_16
326 UNORDERED_MACRO(8,16)
328 #ifdef HAVE_GFC_REAL_10
329 UNORDERED_MACRO(10,4)
330 UNORDERED_MACRO(10,8)
331 UNORDERED_MACRO(10,10)
332 #ifdef HAVE_GFC_REAL_16
333 UNORDERED_MACRO(10,16)
336 #ifdef HAVE_GFC_REAL_16
337 UNORDERED_MACRO(16,4)
338 UNORDERED_MACRO(16,8)
339 #ifdef HAVE_GFC_REAL_10
340 UNORDERED_MACRO(16,10)
342 UNORDERED_MACRO(16,16)
346 interface IEEE_UNORDERED
348 #ifdef HAVE_GFC_REAL_16
349 _gfortran_ieee_unordered_16_16, &
350 #ifdef HAVE_GFC_REAL_10
351 _gfortran_ieee_unordered_16_10, &
353 _gfortran_ieee_unordered_16_8, &
354 _gfortran_ieee_unordered_16_4, &
356 #ifdef HAVE_GFC_REAL_10
357 #ifdef HAVE_GFC_REAL_16
358 _gfortran_ieee_unordered_10_16, &
360 _gfortran_ieee_unordered_10_10, &
361 _gfortran_ieee_unordered_10_8, &
362 _gfortran_ieee_unordered_10_4, &
364 #ifdef HAVE_GFC_REAL_16
365 _gfortran_ieee_unordered_8_16, &
367 #ifdef HAVE_GFC_REAL_10
368 _gfortran_ieee_unordered_8_10, &
370 _gfortran_ieee_unordered_8_8, &
371 _gfortran_ieee_unordered_8_4, &
372 #ifdef HAVE_GFC_REAL_16
373 _gfortran_ieee_unordered_4_16, &
375 #ifdef HAVE_GFC_REAL_10
376 _gfortran_ieee_unordered_4_10, &
378 _gfortran_ieee_unordered_4_8, &
379 _gfortran_ieee_unordered_4_4
381 public :: IEEE_UNORDERED
386 elemental real(kind=4) function _gfortran_ieee_logb_4 (X)
387 real(kind=4), intent(in) :: X
389 elemental real(kind=8) function _gfortran_ieee_logb_8 (X)
390 real(kind=8), intent(in) :: X
392 #ifdef HAVE_GFC_REAL_10
393 elemental real(kind=10) function _gfortran_ieee_logb_10 (X)
394 real(kind=10), intent(in) :: X
397 #ifdef HAVE_GFC_REAL_16
398 elemental real(kind=16) function _gfortran_ieee_logb_16 (X)
399 real(kind=16), intent(in) :: X
406 #ifdef HAVE_GFC_REAL_16
407 _gfortran_ieee_logb_16, &
409 #ifdef HAVE_GFC_REAL_10
410 _gfortran_ieee_logb_10, &
412 _gfortran_ieee_logb_8, &
413 _gfortran_ieee_logb_4
419 #define NEXT_AFTER_MACRO(A,B) \
420 elemental real(kind = A) function \
421 _gfortran_ieee_next_after_/**/A/**/_/**/B (X,Y) ; \
422 real(kind = A), intent(in) :: X ; \
423 real(kind = B), intent(in) :: Y ; \
427 NEXT_AFTER_MACRO(4,4)
428 NEXT_AFTER_MACRO(4,8)
429 #ifdef HAVE_GFC_REAL_10
430 NEXT_AFTER_MACRO(4,10)
432 #ifdef HAVE_GFC_REAL_16
433 NEXT_AFTER_MACRO(4,16)
435 NEXT_AFTER_MACRO(8,4)
436 NEXT_AFTER_MACRO(8,8)
437 #ifdef HAVE_GFC_REAL_10
438 NEXT_AFTER_MACRO(8,10)
440 #ifdef HAVE_GFC_REAL_16
441 NEXT_AFTER_MACRO(8,16)
443 #ifdef HAVE_GFC_REAL_10
444 NEXT_AFTER_MACRO(10,4)
445 NEXT_AFTER_MACRO(10,8)
446 NEXT_AFTER_MACRO(10,10)
447 #ifdef HAVE_GFC_REAL_16
448 NEXT_AFTER_MACRO(10,16)
451 #ifdef HAVE_GFC_REAL_16
452 NEXT_AFTER_MACRO(16,4)
453 NEXT_AFTER_MACRO(16,8)
454 #ifdef HAVE_GFC_REAL_10
455 NEXT_AFTER_MACRO(16,10)
457 NEXT_AFTER_MACRO(16,16)
461 interface IEEE_NEXT_AFTER
463 #ifdef HAVE_GFC_REAL_16
464 _gfortran_ieee_next_after_16_16, &
465 #ifdef HAVE_GFC_REAL_10
466 _gfortran_ieee_next_after_16_10, &
468 _gfortran_ieee_next_after_16_8, &
469 _gfortran_ieee_next_after_16_4, &
471 #ifdef HAVE_GFC_REAL_10
472 #ifdef HAVE_GFC_REAL_16
473 _gfortran_ieee_next_after_10_16, &
475 _gfortran_ieee_next_after_10_10, &
476 _gfortran_ieee_next_after_10_8, &
477 _gfortran_ieee_next_after_10_4, &
479 #ifdef HAVE_GFC_REAL_16
480 _gfortran_ieee_next_after_8_16, &
482 #ifdef HAVE_GFC_REAL_10
483 _gfortran_ieee_next_after_8_10, &
485 _gfortran_ieee_next_after_8_8, &
486 _gfortran_ieee_next_after_8_4, &
487 #ifdef HAVE_GFC_REAL_16
488 _gfortran_ieee_next_after_4_16, &
490 #ifdef HAVE_GFC_REAL_10
491 _gfortran_ieee_next_after_4_10, &
493 _gfortran_ieee_next_after_4_8, &
494 _gfortran_ieee_next_after_4_4
496 public :: IEEE_NEXT_AFTER
500 #define REM_MACRO(RES,A,B) \
501 elemental real(kind = RES) function \
502 _gfortran_ieee_rem_/**/A/**/_/**/B (X,Y) ; \
503 real(kind = A), intent(in) :: X ; \
504 real(kind = B), intent(in) :: Y ; \
510 #ifdef HAVE_GFC_REAL_10
513 #ifdef HAVE_GFC_REAL_16
518 #ifdef HAVE_GFC_REAL_10
521 #ifdef HAVE_GFC_REAL_16
524 #ifdef HAVE_GFC_REAL_10
528 #ifdef HAVE_GFC_REAL_16
532 #ifdef HAVE_GFC_REAL_16
535 #ifdef HAVE_GFC_REAL_10
544 #ifdef HAVE_GFC_REAL_16
545 _gfortran_ieee_rem_16_16, &
546 #ifdef HAVE_GFC_REAL_10
547 _gfortran_ieee_rem_16_10, &
549 _gfortran_ieee_rem_16_8, &
550 _gfortran_ieee_rem_16_4, &
552 #ifdef HAVE_GFC_REAL_10
553 #ifdef HAVE_GFC_REAL_16
554 _gfortran_ieee_rem_10_16, &
556 _gfortran_ieee_rem_10_10, &
557 _gfortran_ieee_rem_10_8, &
558 _gfortran_ieee_rem_10_4, &
560 #ifdef HAVE_GFC_REAL_16
561 _gfortran_ieee_rem_8_16, &
563 #ifdef HAVE_GFC_REAL_10
564 _gfortran_ieee_rem_8_10, &
566 _gfortran_ieee_rem_8_8, &
567 _gfortran_ieee_rem_8_4, &
568 #ifdef HAVE_GFC_REAL_16
569 _gfortran_ieee_rem_4_16, &
571 #ifdef HAVE_GFC_REAL_10
572 _gfortran_ieee_rem_4_10, &
574 _gfortran_ieee_rem_4_8, &
575 _gfortran_ieee_rem_4_4
582 elemental real(kind=4) function _gfortran_ieee_rint_4 (X)
583 real(kind=4), intent(in) :: X
585 elemental real(kind=8) function _gfortran_ieee_rint_8 (X)
586 real(kind=8), intent(in) :: X
588 #ifdef HAVE_GFC_REAL_10
589 elemental real(kind=10) function _gfortran_ieee_rint_10 (X)
590 real(kind=10), intent(in) :: X
593 #ifdef HAVE_GFC_REAL_16
594 elemental real(kind=16) function _gfortran_ieee_rint_16 (X)
595 real(kind=16), intent(in) :: X
602 #ifdef HAVE_GFC_REAL_16
603 _gfortran_ieee_rint_16, &
605 #ifdef HAVE_GFC_REAL_10
606 _gfortran_ieee_rint_10, &
608 _gfortran_ieee_rint_8, _gfortran_ieee_rint_4
615 elemental real(kind=4) function _gfortran_ieee_scalb_4 (X, I)
616 real(kind=4), intent(in) :: X
617 integer, intent(in) :: I
619 elemental real(kind=8) function _gfortran_ieee_scalb_8 (X, I)
620 real(kind=8), intent(in) :: X
621 integer, intent(in) :: I
623 #ifdef HAVE_GFC_REAL_10
624 elemental real(kind=10) function _gfortran_ieee_scalb_10 (X, I)
625 real(kind=10), intent(in) :: X
626 integer, intent(in) :: I
629 #ifdef HAVE_GFC_REAL_16
630 elemental real(kind=16) function _gfortran_ieee_scalb_16 (X, I)
631 real(kind=16), intent(in) :: X
632 integer, intent(in) :: I
639 #ifdef HAVE_GFC_REAL_16
640 _gfortran_ieee_scalb_16, &
642 #ifdef HAVE_GFC_REAL_10
643 _gfortran_ieee_scalb_10, &
645 _gfortran_ieee_scalb_8, _gfortran_ieee_scalb_4
653 #ifdef HAVE_GFC_REAL_16
656 #ifdef HAVE_GFC_REAL_10
659 IEEE_VALUE_8, IEEE_VALUE_4
667 #ifdef HAVE_GFC_REAL_16
670 #ifdef HAVE_GFC_REAL_10
673 IEEE_CLASS_8, IEEE_CLASS_4
677 ! Public declarations for contained procedures
678 public :: IEEE_GET_ROUNDING_MODE, IEEE_SET_ROUNDING_MODE
679 public :: IEEE_GET_UNDERFLOW_MODE, IEEE_SET_UNDERFLOW_MODE
680 public :: IEEE_SELECTED_REAL_KIND
682 ! IEEE_SUPPORT_ROUNDING
684 interface IEEE_SUPPORT_ROUNDING
685 module procedure IEEE_SUPPORT_ROUNDING_4, IEEE_SUPPORT_ROUNDING_8, &
686 #ifdef HAVE_GFC_REAL_10
687 IEEE_SUPPORT_ROUNDING_10, &
689 #ifdef HAVE_GFC_REAL_16
690 IEEE_SUPPORT_ROUNDING_16, &
692 IEEE_SUPPORT_ROUNDING_NOARG
694 public :: IEEE_SUPPORT_ROUNDING
696 ! Interface to the FPU-specific function
698 pure integer function support_rounding_helper(flag) &
699 bind(c, name="_gfortrani_support_fpu_rounding_mode")
700 integer, intent(in), value :: flag
704 ! IEEE_SUPPORT_UNDERFLOW_CONTROL
706 interface IEEE_SUPPORT_UNDERFLOW_CONTROL
707 module procedure IEEE_SUPPORT_UNDERFLOW_CONTROL_4, &
708 IEEE_SUPPORT_UNDERFLOW_CONTROL_8, &
709 #ifdef HAVE_GFC_REAL_10
710 IEEE_SUPPORT_UNDERFLOW_CONTROL_10, &
712 #ifdef HAVE_GFC_REAL_16
713 IEEE_SUPPORT_UNDERFLOW_CONTROL_16, &
715 IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG
717 public :: IEEE_SUPPORT_UNDERFLOW_CONTROL
719 ! Interface to the FPU-specific function
721 pure integer function support_underflow_control_helper(kind) &
722 bind(c, name="_gfortrani_support_fpu_underflow_control")
723 integer, intent(in), value :: kind
727 ! IEEE_SUPPORT_* generic functions
729 #if defined(HAVE_GFC_REAL_10) && defined(HAVE_GFC_REAL_16)
730 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_16, NAME/**/_NOARG
731 #elif defined(HAVE_GFC_REAL_10)
732 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_10, NAME/**/_NOARG
733 #elif defined(HAVE_GFC_REAL_16)
734 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_16, NAME/**/_NOARG
736 # define MACRO1(NAME) NAME/**/_4, NAME/**/_8, NAME/**/_NOARG
739 #define SUPPORTGENERIC(NAME) \
740 interface NAME ; module procedure MACRO1(NAME) ; end interface ; \
743 SUPPORTGENERIC(IEEE_SUPPORT_DATATYPE)
744 SUPPORTGENERIC(IEEE_SUPPORT_DENORMAL)
745 SUPPORTGENERIC(IEEE_SUPPORT_DIVIDE)
746 SUPPORTGENERIC(IEEE_SUPPORT_INF)
747 SUPPORTGENERIC(IEEE_SUPPORT_IO)
748 SUPPORTGENERIC(IEEE_SUPPORT_NAN)
749 SUPPORTGENERIC(IEEE_SUPPORT_SQRT)
750 SUPPORTGENERIC(IEEE_SUPPORT_STANDARD)
754 ! Equality operators for IEEE_CLASS_TYPE and IEEE_ROUNDING_MODE
755 elemental logical function IEEE_CLASS_TYPE_EQ (X, Y) result(res)
757 type(IEEE_CLASS_TYPE), intent(in) :: X, Y
758 res = (X%hidden == Y%hidden)
761 elemental logical function IEEE_CLASS_TYPE_NE (X, Y) result(res)
763 type(IEEE_CLASS_TYPE), intent(in) :: X, Y
764 res = (X%hidden /= Y%hidden)
767 elemental logical function IEEE_ROUND_TYPE_EQ (X, Y) result(res)
769 type(IEEE_ROUND_TYPE), intent(in) :: X, Y
770 res = (X%hidden == Y%hidden)
773 elemental logical function IEEE_ROUND_TYPE_NE (X, Y) result(res)
775 type(IEEE_ROUND_TYPE), intent(in) :: X, Y
776 res = (X%hidden /= Y%hidden)
780 ! IEEE_SELECTED_REAL_KIND
782 integer function IEEE_SELECTED_REAL_KIND (P, R, RADIX) result(res)
784 integer, intent(in), optional :: P, R, RADIX
786 ! Currently, if IEEE is supported and this module is built, it means
787 ! all our floating-point types conform to IEEE. Hence, we simply call
788 ! SELECTED_REAL_KIND.
790 res = SELECTED_REAL_KIND (P, R, RADIX)
797 elemental function IEEE_CLASS_4 (X) result(res)
799 real(kind=4), intent(in) :: X
800 type(IEEE_CLASS_TYPE) :: res
803 pure integer function _gfortrani_ieee_class_helper_4(val)
804 real(kind=4), intent(in) :: val
808 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_4(X))
811 elemental function IEEE_CLASS_8 (X) result(res)
813 real(kind=8), intent(in) :: X
814 type(IEEE_CLASS_TYPE) :: res
817 pure integer function _gfortrani_ieee_class_helper_8(val)
818 real(kind=8), intent(in) :: val
822 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_8(X))
825 #ifdef HAVE_GFC_REAL_10
826 elemental function IEEE_CLASS_10 (X) result(res)
828 real(kind=10), intent(in) :: X
829 type(IEEE_CLASS_TYPE) :: res
832 pure integer function _gfortrani_ieee_class_helper_10(val)
833 real(kind=10), intent(in) :: val
837 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_10(X))
841 #ifdef HAVE_GFC_REAL_16
842 elemental function IEEE_CLASS_16 (X) result(res)
844 real(kind=16), intent(in) :: X
845 type(IEEE_CLASS_TYPE) :: res
848 pure integer function _gfortrani_ieee_class_helper_16(val)
849 real(kind=16), intent(in) :: val
853 res = IEEE_CLASS_TYPE(_gfortrani_ieee_class_helper_16(X))
860 elemental real(kind=4) function IEEE_VALUE_4(X, CLASS) result(res)
862 real(kind=4), intent(in) :: X
863 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
865 select case (CLASS%hidden)
866 case (1) ! IEEE_SIGNALING_NAN
869 case (2) ! IEEE_QUIET_NAN
872 case (3) ! IEEE_NEGATIVE_INF
875 case (4) ! IEEE_NEGATIVE_NORMAL
877 case (5) ! IEEE_NEGATIVE_DENORMAL
880 case (6) ! IEEE_NEGATIVE_ZERO
883 case (7) ! IEEE_POSITIVE_ZERO
885 case (8) ! IEEE_POSITIVE_DENORMAL
888 case (9) ! IEEE_POSITIVE_NORMAL
890 case (10) ! IEEE_POSITIVE_INF
893 case default ! IEEE_OTHER_VALUE, should not happen
898 elemental real(kind=8) function IEEE_VALUE_8(X, CLASS) result(res)
900 real(kind=8), intent(in) :: X
901 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
903 select case (CLASS%hidden)
904 case (1) ! IEEE_SIGNALING_NAN
907 case (2) ! IEEE_QUIET_NAN
910 case (3) ! IEEE_NEGATIVE_INF
913 case (4) ! IEEE_NEGATIVE_NORMAL
915 case (5) ! IEEE_NEGATIVE_DENORMAL
918 case (6) ! IEEE_NEGATIVE_ZERO
921 case (7) ! IEEE_POSITIVE_ZERO
923 case (8) ! IEEE_POSITIVE_DENORMAL
926 case (9) ! IEEE_POSITIVE_NORMAL
928 case (10) ! IEEE_POSITIVE_INF
931 case default ! IEEE_OTHER_VALUE, should not happen
936 #ifdef HAVE_GFC_REAL_10
937 elemental real(kind=10) function IEEE_VALUE_10(X, CLASS) result(res)
939 real(kind=10), intent(in) :: X
940 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
942 select case (CLASS%hidden)
943 case (1) ! IEEE_SIGNALING_NAN
946 case (2) ! IEEE_QUIET_NAN
949 case (3) ! IEEE_NEGATIVE_INF
952 case (4) ! IEEE_NEGATIVE_NORMAL
954 case (5) ! IEEE_NEGATIVE_DENORMAL
957 case (6) ! IEEE_NEGATIVE_ZERO
960 case (7) ! IEEE_POSITIVE_ZERO
962 case (8) ! IEEE_POSITIVE_DENORMAL
965 case (9) ! IEEE_POSITIVE_NORMAL
967 case (10) ! IEEE_POSITIVE_INF
970 case default ! IEEE_OTHER_VALUE, should not happen
977 #ifdef HAVE_GFC_REAL_16
978 elemental real(kind=16) function IEEE_VALUE_16(X, CLASS) result(res)
980 real(kind=16), intent(in) :: X
981 type(IEEE_CLASS_TYPE), intent(in) :: CLASS
983 select case (CLASS%hidden)
984 case (1) ! IEEE_SIGNALING_NAN
987 case (2) ! IEEE_QUIET_NAN
990 case (3) ! IEEE_NEGATIVE_INF
993 case (4) ! IEEE_NEGATIVE_NORMAL
995 case (5) ! IEEE_NEGATIVE_DENORMAL
998 case (6) ! IEEE_NEGATIVE_ZERO
1001 case (7) ! IEEE_POSITIVE_ZERO
1003 case (8) ! IEEE_POSITIVE_DENORMAL
1006 case (9) ! IEEE_POSITIVE_NORMAL
1008 case (10) ! IEEE_POSITIVE_INF
1011 case default ! IEEE_OTHER_VALUE, should not happen
1018 ! IEEE_GET_ROUNDING_MODE
1020 subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE)
1022 type(IEEE_ROUND_TYPE), intent(out) :: ROUND_VALUE
1025 integer function helper() &
1026 bind(c, name="_gfortrani_get_fpu_rounding_mode")
1030 ROUND_VALUE = IEEE_ROUND_TYPE(helper())
1034 ! IEEE_SET_ROUNDING_MODE
1036 subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE)
1038 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1041 subroutine helper(val) &
1042 bind(c, name="_gfortrani_set_fpu_rounding_mode")
1043 integer, value :: val
1047 call helper(ROUND_VALUE%hidden)
1051 ! IEEE_GET_UNDERFLOW_MODE
1053 subroutine IEEE_GET_UNDERFLOW_MODE (GRADUAL)
1055 logical, intent(out) :: GRADUAL
1058 integer function helper() &
1059 bind(c, name="_gfortrani_get_fpu_underflow_mode")
1063 GRADUAL = (helper() /= 0)
1067 ! IEEE_SET_UNDERFLOW_MODE
1069 subroutine IEEE_SET_UNDERFLOW_MODE (GRADUAL)
1071 logical, intent(in) :: GRADUAL
1074 subroutine helper(val) &
1075 bind(c, name="_gfortrani_set_fpu_underflow_mode")
1076 integer, value :: val
1080 call helper(merge(1, 0, GRADUAL))
1083 ! IEEE_SUPPORT_ROUNDING
1085 pure logical function IEEE_SUPPORT_ROUNDING_4 (ROUND_VALUE, X) result(res)
1087 real(kind=4), intent(in) :: X
1088 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1089 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1092 pure logical function IEEE_SUPPORT_ROUNDING_8 (ROUND_VALUE, X) result(res)
1094 real(kind=8), intent(in) :: X
1095 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1096 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1099 #ifdef HAVE_GFC_REAL_10
1100 pure logical function IEEE_SUPPORT_ROUNDING_10 (ROUND_VALUE, X) result(res)
1102 real(kind=10), intent(in) :: X
1103 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1104 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1108 #ifdef HAVE_GFC_REAL_16
1109 pure logical function IEEE_SUPPORT_ROUNDING_16 (ROUND_VALUE, X) result(res)
1111 real(kind=16), intent(in) :: X
1112 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1113 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1117 pure logical function IEEE_SUPPORT_ROUNDING_NOARG (ROUND_VALUE) result(res)
1119 type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE
1120 res = (support_rounding_helper(ROUND_VALUE%hidden) /= 0)
1123 ! IEEE_SUPPORT_UNDERFLOW_CONTROL
1125 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_4 (X) result(res)
1127 real(kind=4), intent(in) :: X
1128 res = (support_underflow_control_helper(4) /= 0)
1131 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_8 (X) result(res)
1133 real(kind=8), intent(in) :: X
1134 res = (support_underflow_control_helper(8) /= 0)
1137 #ifdef HAVE_GFC_REAL_10
1138 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_10 (X) result(res)
1140 real(kind=10), intent(in) :: X
1141 res = (support_underflow_control_helper(10) /= 0)
1145 #ifdef HAVE_GFC_REAL_16
1146 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_16 (X) result(res)
1148 real(kind=16), intent(in) :: X
1149 res = (support_underflow_control_helper(16) /= 0)
1153 pure logical function IEEE_SUPPORT_UNDERFLOW_CONTROL_NOARG () result(res)
1155 res = (support_underflow_control_helper(4) /= 0 &
1156 .and. support_underflow_control_helper(8) /= 0 &
1157 #ifdef HAVE_GFC_REAL_10
1158 .and. support_underflow_control_helper(10) /= 0 &
1160 #ifdef HAVE_GFC_REAL_16
1161 .and. support_underflow_control_helper(16) /= 0 &
1166 ! IEEE_SUPPORT_* functions
1168 #define SUPPORTMACRO(NAME, INTKIND, VALUE) \
1169 pure logical function NAME/**/_/**/INTKIND (X) result(res) ; \
1171 real(INTKIND), intent(in) :: X(..) ; \
1175 #define SUPPORTMACRO_NOARG(NAME, VALUE) \
1176 pure logical function NAME/**/_NOARG () result(res) ; \
1181 ! IEEE_SUPPORT_DATATYPE
1183 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,4,.true.)
1184 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,8,.true.)
1185 #ifdef HAVE_GFC_REAL_10
1186 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,10,.true.)
1188 #ifdef HAVE_GFC_REAL_16
1189 SUPPORTMACRO(IEEE_SUPPORT_DATATYPE,16,.true.)
1191 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DATATYPE,.true.)
1193 ! IEEE_SUPPORT_DENORMAL
1195 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,4,.true.)
1196 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,8,.true.)
1197 #ifdef HAVE_GFC_REAL_10
1198 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,10,.true.)
1200 #ifdef HAVE_GFC_REAL_16
1201 SUPPORTMACRO(IEEE_SUPPORT_DENORMAL,16,.true.)
1203 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DENORMAL,.true.)
1205 ! IEEE_SUPPORT_DIVIDE
1207 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,4,.true.)
1208 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,8,.true.)
1209 #ifdef HAVE_GFC_REAL_10
1210 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,10,.true.)
1212 #ifdef HAVE_GFC_REAL_16
1213 SUPPORTMACRO(IEEE_SUPPORT_DIVIDE,16,.true.)
1215 SUPPORTMACRO_NOARG(IEEE_SUPPORT_DIVIDE,.true.)
1219 SUPPORTMACRO(IEEE_SUPPORT_INF,4,.true.)
1220 SUPPORTMACRO(IEEE_SUPPORT_INF,8,.true.)
1221 #ifdef HAVE_GFC_REAL_10
1222 SUPPORTMACRO(IEEE_SUPPORT_INF,10,.true.)
1224 #ifdef HAVE_GFC_REAL_16
1225 SUPPORTMACRO(IEEE_SUPPORT_INF,16,.true.)
1227 SUPPORTMACRO_NOARG(IEEE_SUPPORT_INF,.true.)
1231 SUPPORTMACRO(IEEE_SUPPORT_IO,4,.true.)
1232 SUPPORTMACRO(IEEE_SUPPORT_IO,8,.true.)
1233 #ifdef HAVE_GFC_REAL_10
1234 SUPPORTMACRO(IEEE_SUPPORT_IO,10,.true.)
1236 #ifdef HAVE_GFC_REAL_16
1237 SUPPORTMACRO(IEEE_SUPPORT_IO,16,.true.)
1239 SUPPORTMACRO_NOARG(IEEE_SUPPORT_IO,.true.)
1243 SUPPORTMACRO(IEEE_SUPPORT_NAN,4,.true.)
1244 SUPPORTMACRO(IEEE_SUPPORT_NAN,8,.true.)
1245 #ifdef HAVE_GFC_REAL_10
1246 SUPPORTMACRO(IEEE_SUPPORT_NAN,10,.true.)
1248 #ifdef HAVE_GFC_REAL_16
1249 SUPPORTMACRO(IEEE_SUPPORT_NAN,16,.true.)
1251 SUPPORTMACRO_NOARG(IEEE_SUPPORT_NAN,.true.)
1255 SUPPORTMACRO(IEEE_SUPPORT_SQRT,4,.true.)
1256 SUPPORTMACRO(IEEE_SUPPORT_SQRT,8,.true.)
1257 #ifdef HAVE_GFC_REAL_10
1258 SUPPORTMACRO(IEEE_SUPPORT_SQRT,10,.true.)
1260 #ifdef HAVE_GFC_REAL_16
1261 SUPPORTMACRO(IEEE_SUPPORT_SQRT,16,.true.)
1263 SUPPORTMACRO_NOARG(IEEE_SUPPORT_SQRT,.true.)
1265 ! IEEE_SUPPORT_STANDARD
1267 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,4,.true.)
1268 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,8,.true.)
1269 #ifdef HAVE_GFC_REAL_10
1270 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,10,.true.)
1272 #ifdef HAVE_GFC_REAL_16
1273 SUPPORTMACRO(IEEE_SUPPORT_STANDARD,16,.true.)
1275 SUPPORTMACRO_NOARG(IEEE_SUPPORT_STANDARD,.true.)
1277 end module IEEE_ARITHMETIC