aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gmail.com>2022-09-04 18:24:23 +0200
committerFrancois-Xavier Coudert <fxcoudert@gmail.com>2022-09-19 14:26:34 +0200
commitde40fab2f32b03c3d8f69f72c7f1e38694f93d35 (patch)
treea5100ce2c023af13b9659f48592b3719b2577612 /gcc
parent6efc494a24bb423f1f9ef8dbdc65ca189072eb8d (diff)
downloadgcc-de40fab2f32b03c3d8f69f72c7f1e38694f93d35.zip
gcc-de40fab2f32b03c3d8f69f72c7f1e38694f93d35.tar.gz
gcc-de40fab2f32b03c3d8f69f72c7f1e38694f93d35.tar.bz2
Fortran: add IEEE_MODES_TYPE, IEEE_GET_MODES and IEEE_SET_MODES
The IEEE_MODES_TYPE type and the two functions that get and set it were added in Fortran 2018. They can be implemented using the already existing target-specific functions. A future optimization could, on some targets, set/get all modes through one or two instructions only, but that would need a new set of functions in all config/fpu-* files. 2022-09-04 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> libgfortran/ * 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. gcc/testsuite/ * gfortran.dg/ieee/modes_1.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gfortran.dg/ieee/modes_1.f9095
1 files changed, 95 insertions, 0 deletions
diff --git a/gcc/testsuite/gfortran.dg/ieee/modes_1.f90 b/gcc/testsuite/gfortran.dg/ieee/modes_1.f90
new file mode 100644
index 0000000..b6ab288
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/ieee/modes_1.f90
@@ -0,0 +1,95 @@
+! { dg-do run }
+!
+! Test IEEE_MODES_TYPE, IEEE_GET_MODES and IEEE_SET_MODES
+
+
+! The symbols should be accessible from both IEEE_EXCEPTIONS
+! and IEEE_ARITHMETIC.
+
+subroutine test_1
+ use ieee_exceptions, only : IEEE_GET_MODES, IEEE_SET_MODES
+end subroutine
+
+subroutine test_2
+ use ieee_arithmetic, only : IEEE_GET_MODES, IEEE_SET_MODES
+end subroutine
+
+subroutine test_3
+ use ieee_exceptions, only : IEEE_MODES_TYPE
+end subroutine
+
+subroutine test_4
+ use ieee_arithmetic, only : IEEE_MODES_TYPE
+end subroutine
+
+
+! Check that the functions actually do the job
+
+program foo
+ use ieee_arithmetic
+ implicit none
+
+ type(ieee_modes_type) :: modes1, modes2
+ type(ieee_round_type) :: rmode
+ logical :: f
+
+ ! Set some modes
+ if (ieee_support_underflow_control()) then
+ call ieee_set_underflow_mode(gradual=.false.)
+ endif
+ if (ieee_support_rounding(ieee_up)) then
+ call ieee_set_rounding_mode(ieee_up)
+ endif
+ if (ieee_support_halting(ieee_overflow)) then
+ call ieee_set_halting_mode(ieee_overflow, .true.)
+ endif
+
+ call ieee_get_modes(modes1)
+
+ ! Change modes
+ if (ieee_support_underflow_control()) then
+ call ieee_set_underflow_mode(gradual=.true.)
+ endif
+ if (ieee_support_rounding(ieee_down)) then
+ call ieee_set_rounding_mode(ieee_down)
+ endif
+ if (ieee_support_halting(ieee_overflow)) then
+ call ieee_set_halting_mode(ieee_overflow, .false.)
+ endif
+
+ ! Save and restore the previous modes
+ call ieee_get_modes(modes2)
+ call ieee_set_modes(modes1)
+
+ ! Check them
+ if (ieee_support_underflow_control()) then
+ call ieee_get_underflow_mode(f)
+ if (f) stop 1
+ endif
+ if (ieee_support_rounding(ieee_down)) then
+ call ieee_get_rounding_mode(rmode)
+ if (rmode /= ieee_up) stop 2
+ endif
+ if (ieee_support_halting(ieee_overflow)) then
+ call ieee_get_halting_mode(ieee_overflow, f)
+ if (.not. f) stop 3
+ endif
+
+ ! Restore the second set of modes
+ call ieee_set_modes(modes2)
+
+ ! Check again
+ if (ieee_support_underflow_control()) then
+ call ieee_get_underflow_mode(f)
+ if (.not. f) stop 3
+ endif
+ if (ieee_support_rounding(ieee_down)) then
+ call ieee_get_rounding_mode(rmode)
+ if (rmode /= ieee_down) stop 4
+ endif
+ if (ieee_support_halting(ieee_overflow)) then
+ call ieee_get_halting_mode(ieee_overflow, f)
+ if (f) stop 5
+ endif
+
+end program foo