diff options
author | Martin Liska <mliska@suse.cz> | 2022-09-20 13:53:30 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-09-20 13:53:30 +0200 |
commit | 6df29b782e87c6c800be0425023d8438fdc67b92 (patch) | |
tree | 48eebe497e384d66a7f5cf861b4b1b963785a2cd /libgfortran | |
parent | fdb97cd0b7d15efa39ba79dca44be93debb0ef12 (diff) | |
parent | 63e3cc294d835b43701eeef9410d1b8fc8922869 (diff) | |
download | gcc-6df29b782e87c6c800be0425023d8438fdc67b92.zip gcc-6df29b782e87c6c800be0425023d8438fdc67b92.tar.gz gcc-6df29b782e87c6c800be0425023d8438fdc67b92.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 18 | ||||
-rw-r--r-- | libgfortran/config/fpu-387.h | 7 | ||||
-rw-r--r-- | libgfortran/config/fpu-aarch64.h | 7 | ||||
-rw-r--r-- | libgfortran/config/fpu-aix.h | 22 | ||||
-rw-r--r-- | libgfortran/config/fpu-generic.h | 11 | ||||
-rw-r--r-- | libgfortran/config/fpu-glibc.h | 18 | ||||
-rw-r--r-- | libgfortran/config/fpu-sysv.h | 7 | ||||
-rw-r--r-- | libgfortran/ieee/ieee_arithmetic.F90 | 10 | ||||
-rw-r--r-- | libgfortran/ieee/ieee_exceptions.F90 | 63 |
9 files changed, 150 insertions, 13 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 51c9f5c..fab472e 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,21 @@ +2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + * ieee/ieee_exceptions.F90: Add IEEE_MODES_TYPE, IEEE_GET_MODES + and IEEE_SET_MODES. + * ieee/ieee_arithmetic.F90: Make them public in IEEE_ARITHMETIC + as well. + +2022-09-19 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + * ieee/ieee_arithmetic.F90: Add RADIX argument to + IEEE_SET_ROUNDING_MODE and IEEE_GET_ROUNDING_MODE. + * config/fpu-387.h: Add IEEE_AWAY mode. + * config/fpu-aarch64.h: Add IEEE_AWAY mode. + * config/fpu-aix.h: Add IEEE_AWAY mode. + * config/fpu-generic.h: Add IEEE_AWAY mode. + * config/fpu-glibc.h: Add IEEE_AWAY mode. + * config/fpu-sysv.h: Add IEEE_AWAY mode. + 2022-09-10 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR fortran/95644 diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index fd00dab..e2f4a7d 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -418,9 +418,12 @@ get_fpu_rounding_mode (void) } int -support_fpu_rounding_mode (int mode __attribute__((unused))) +support_fpu_rounding_mode (int mode) { - return 1; + if (mode == GFC_FPE_AWAY) + return 0; + else + return 1; } void diff --git a/libgfortran/config/fpu-aarch64.h b/libgfortran/config/fpu-aarch64.h index 3a2e4ba..4789390 100644 --- a/libgfortran/config/fpu-aarch64.h +++ b/libgfortran/config/fpu-aarch64.h @@ -293,9 +293,12 @@ set_fpu_rounding_mode (int round) int -support_fpu_rounding_mode (int mode __attribute__((unused))) +support_fpu_rounding_mode (int mode) { - return 1; + if (mode == GFC_FPE_AWAY) + return 0; + else + return 1; } diff --git a/libgfortran/config/fpu-aix.h b/libgfortran/config/fpu-aix.h index c643874..fb1ac80 100644 --- a/libgfortran/config/fpu-aix.h +++ b/libgfortran/config/fpu-aix.h @@ -320,6 +320,11 @@ get_fpu_rounding_mode (void) return GFC_FPE_TOWARDZERO; #endif +#ifdef FE_TONEARESTFROMZERO + case FE_TONEARESTFROMZERO: + return GFC_FPE_AWAY; +#endif + default: return 0; /* Should be unreachable. */ } @@ -357,8 +362,14 @@ set_fpu_rounding_mode (int mode) break; #endif +#ifdef FE_TONEARESTFROMZERO + case GFC_FPE_AWAY: + rnd_mode = FE_TONEARESTFROMZERO; + break; +#endif + default: - return; /* Should be unreachable. */ + return; } fesetround (rnd_mode); @@ -398,8 +409,15 @@ support_fpu_rounding_mode (int mode) return 0; #endif + case GFC_FPE_AWAY: +#ifdef FE_TONEARESTFROMZERO + return 1; +#else + return 0; +#endif + default: - return 0; /* Should be unreachable. */ + return 0; } } diff --git a/libgfortran/config/fpu-generic.h b/libgfortran/config/fpu-generic.h index 3b62228..9e976a8 100644 --- a/libgfortran/config/fpu-generic.h +++ b/libgfortran/config/fpu-generic.h @@ -66,9 +66,16 @@ get_fpu_except_flags (void) int get_fpu_rounding_mode (void) -{ +{ + return 0; +} + + +int +support_fpu_rounding_mode (int mode __attribute__((unused))) +{ return 0; -} +} void diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h index 265ef69..f34b696 100644 --- a/libgfortran/config/fpu-glibc.h +++ b/libgfortran/config/fpu-glibc.h @@ -342,6 +342,11 @@ get_fpu_rounding_mode (void) return GFC_FPE_TOWARDZERO; #endif +#ifdef FE_TONEARESTFROMZERO + case FE_TONEARESTFROMZERO: + return GFC_FPE_AWAY; +#endif + default: return 0; /* Should be unreachable. */ } @@ -379,6 +384,12 @@ set_fpu_rounding_mode (int mode) break; #endif +#ifdef FE_TONEARESTFROMZERO + case GFC_FPE_AWAY: + rnd_mode = FE_TONEARESTFROMZERO; + break; +#endif + default: return; /* Should be unreachable. */ } @@ -420,6 +431,13 @@ support_fpu_rounding_mode (int mode) return 0; #endif + case GFC_FPE_AWAY: +#ifdef FE_TONEARESTFROMZERO + return 1; +#else + return 0; +#endif + default: return 0; /* Should be unreachable. */ } diff --git a/libgfortran/config/fpu-sysv.h b/libgfortran/config/fpu-sysv.h index 4de3852..4681322 100644 --- a/libgfortran/config/fpu-sysv.h +++ b/libgfortran/config/fpu-sysv.h @@ -374,9 +374,12 @@ set_fpu_rounding_mode (int mode) int -support_fpu_rounding_mode (int mode __attribute__((unused))) +support_fpu_rounding_mode (int mode) { - return 1; + if (mode == GFC_FPE_AWAY) + return 0; + else + return 1; } diff --git a/libgfortran/ieee/ieee_arithmetic.F90 b/libgfortran/ieee/ieee_arithmetic.F90 index 4e01aa5..ce30e4a 100644 --- a/libgfortran/ieee/ieee_arithmetic.F90 +++ b/libgfortran/ieee/ieee_arithmetic.F90 @@ -39,7 +39,8 @@ module IEEE_ARITHMETIC IEEE_DIVIDE_BY_ZERO, IEEE_UNDERFLOW, IEEE_INEXACT, IEEE_USUAL, & IEEE_ALL, IEEE_STATUS_TYPE, IEEE_GET_FLAG, IEEE_GET_HALTING_MODE, & IEEE_GET_STATUS, IEEE_SET_FLAG, IEEE_SET_HALTING_MODE, & - IEEE_SET_STATUS, IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING + IEEE_SET_STATUS, IEEE_SUPPORT_FLAG, IEEE_SUPPORT_HALTING, & + IEEE_MODES_TYPE, IEEE_GET_MODES, IEEE_SET_MODES ! Derived types and named constants @@ -73,6 +74,7 @@ module IEEE_ARITHMETIC IEEE_TO_ZERO = IEEE_ROUND_TYPE(GFC_FPE_TOWARDZERO), & IEEE_UP = IEEE_ROUND_TYPE(GFC_FPE_UPWARD), & IEEE_DOWN = IEEE_ROUND_TYPE(GFC_FPE_DOWNWARD), & + IEEE_AWAY = IEEE_ROUND_TYPE(GFC_FPE_AWAY), & IEEE_OTHER = IEEE_ROUND_TYPE(0) @@ -1044,9 +1046,10 @@ contains ! IEEE_GET_ROUNDING_MODE - subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE) + subroutine IEEE_GET_ROUNDING_MODE (ROUND_VALUE, RADIX) implicit none type(IEEE_ROUND_TYPE), intent(out) :: ROUND_VALUE + integer, intent(in), optional :: RADIX interface integer function helper() & @@ -1060,9 +1063,10 @@ contains ! IEEE_SET_ROUNDING_MODE - subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE) + subroutine IEEE_SET_ROUNDING_MODE (ROUND_VALUE, RADIX) implicit none type(IEEE_ROUND_TYPE), intent(in) :: ROUND_VALUE + integer, intent(in), optional :: RADIX interface subroutine helper(val) & diff --git a/libgfortran/ieee/ieee_exceptions.F90 b/libgfortran/ieee/ieee_exceptions.F90 index 77363cf..3ed2f6e 100644 --- a/libgfortran/ieee/ieee_exceptions.F90 +++ b/libgfortran/ieee/ieee_exceptions.F90 @@ -56,6 +56,13 @@ module IEEE_EXCEPTIONS character(len=GFC_FPE_STATE_BUFFER_SIZE) :: hidden end type + type, public :: IEEE_MODES_TYPE + private + integer :: rounding + integer :: underflow + integer :: halting + end type + interface IEEE_SUPPORT_FLAG module procedure IEEE_SUPPORT_FLAG_4, & IEEE_SUPPORT_FLAG_8, & @@ -72,9 +79,65 @@ module IEEE_EXCEPTIONS public :: IEEE_SET_HALTING_MODE, IEEE_GET_HALTING_MODE public :: IEEE_SET_FLAG, IEEE_GET_FLAG public :: IEEE_SET_STATUS, IEEE_GET_STATUS + public :: IEEE_SET_MODES, IEEE_GET_MODES contains +! Fortran 2018: Saving and restoring floating-point modes +! (rounding modes, underflow mode, and halting mode) +! +! For now, we only have one rounding mode for all kinds. +! Some targets could optimize getting/setting all modes at once, but for now +! we make three calls. This code must be kept in sync with: +! - IEEE_{GET,SET}_ROUNDING_MODE +! - IEEE_{GET,SET}_UNDERFLOW_MODE +! - IEEE_{GET,SET}_HALTING_MODE + + subroutine IEEE_GET_MODES (MODES) + implicit none + type(IEEE_MODES_TYPE), intent(out) :: MODES + + interface + integer function helper_rounding() & + bind(c, name="_gfortrani_get_fpu_rounding_mode") + end function + integer function helper_underflow() & + bind(c, name="_gfortrani_get_fpu_underflow_mode") + end function + pure integer function helper_halting() & + bind(c, name="_gfortrani_get_fpu_trap_exceptions") + end function + end interface + + MODES%rounding = helper_rounding() + MODES%underflow = helper_underflow() + MODES%halting = helper_halting() + end subroutine + + subroutine IEEE_SET_MODES (MODES) + implicit none + type(IEEE_MODES_TYPE), intent(in) :: MODES + + interface + subroutine helper_rounding(val) & + bind(c, name="_gfortrani_set_fpu_rounding_mode") + integer, value :: val + end subroutine + subroutine helper_underflow(val) & + bind(c, name="_gfortrani_set_fpu_underflow_mode") + integer, value :: val + end subroutine + pure subroutine helper_halting(trap, notrap) & + bind(c, name="_gfortrani_set_fpu_trap_exceptions") + integer, intent(in), value :: trap, notrap + end subroutine + end interface + + call helper_rounding(MODES%rounding) + call helper_underflow(MODES%underflow) + call helper_halting(MODES%halting, NOT(MODES%halting)) + end subroutine + ! Saving and restoring floating-point status subroutine IEEE_GET_STATUS (STATUS_VALUE) |