mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 21:51:36 +08:00
Fortran: F2018 rounding modes changes
Add the new IEEE_AWAY rounding mode. It is unsupported on all known targets, but could be supported by glibc and AIX as part of the C2x proposal. Testing for now is minimal. Add the optional RADIX argument to IEEE_SET_ROUNDING_MODE and IEEE_GET_ROUNDING_MODE. It is unused for now, because we do not support radices other than 2. 2022-08-31 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> gcc/fortran/ * libgfortran.h: Declare GFC_FPE_AWAY. gcc/testsuite/ * gfortran.dg/ieee/rounding_2.f90: New test. libgfortran/ * 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.
This commit is contained in:
parent
0b5b8ac5cb
commit
4637a1d293
@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define GFC_FPE_TONEAREST 2
|
||||
#define GFC_FPE_TOWARDZERO 3
|
||||
#define GFC_FPE_UPWARD 4
|
||||
#define GFC_FPE_AWAY 5
|
||||
|
||||
/* Size of the buffer required to store FPU state for any target.
|
||||
In particular, this has to be larger than fenv_t on all glibc targets.
|
||||
|
20
gcc/testsuite/gfortran.dg/ieee/rounding_2.f90
Normal file
20
gcc/testsuite/gfortran.dg/ieee/rounding_2.f90
Normal file
@ -0,0 +1,20 @@
|
||||
! { dg-do run }
|
||||
|
||||
use, intrinsic :: ieee_arithmetic
|
||||
implicit none
|
||||
|
||||
real :: sx1, sx2, sx3
|
||||
double precision :: dx1, dx2, dx3
|
||||
|
||||
! IEEE_AWAY was added in Fortran 2018 and not supported by any target
|
||||
! at the moment. Just check we can query for its support.
|
||||
|
||||
! We should support at least C float and C double types
|
||||
if (ieee_support_rounding(ieee_away) &
|
||||
.or. ieee_support_rounding(ieee_away, 0.) &
|
||||
.or. ieee_support_rounding(ieee_away, 0.d0)) then
|
||||
print *, "If a target / libc now supports this, we need to add a proper check!"
|
||||
stop 1
|
||||
end if
|
||||
|
||||
end
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,6 +73,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 +1045,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 +1062,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) &
|
||||
|
Loading…
x
Reference in New Issue
Block a user