re PR libfortran/35862 ([F2003] Implement new rounding modes for run time)

2013-07-21  Tobias Burnus  <burnus@net-b.de>

        PR fortran/35862
        * libgfortran.h (GFC_FPE_DOWNWARD, GFC_FPE_TONEAREST,
        GFC_FPE_TOWARDZERO, GFC_FPE_UPWARD): New defines.

2013-07-21  Tobias Burnus  <burnus@net-b.de>

        PR fortran/35862
        * libgfortran.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): New prototypes.
        * config/fpu-387.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): New functions.
        * config/fpu-aix.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): Ditto.
        * config/fpu-generic.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): Ditto.
        * config/fpu-glibc.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): Ditto.
        * config/fpu-sysv.h (set_fpu_rounding_mode,
        get_fpu_rounding_mode): Ditto.
        * configure.ac: Check for fp_rnd and fp_rnd_t.
        * io/io.h (enum unit_round): Use GFC_FPE_* for the value.
        * io/read.c (convert_real): Set FP ronding mode.
        * Makefile.in: Regenerate.
        * aclocal.m4: Regenerate.
        * config.h.in: Regenerate.
        * configure: Regenerate.

2013-07-21  Tobias Burnus  <burnus@net-b.de>

        PR fortran/35862
        * gfortran.dg/round_4.f90: New.


Co-Authored-By: Uros Bizjak <ubizjak@gmail.com>

From-SVN: r201093
This commit is contained in:
Tobias Burnus 2013-07-21 13:54:27 +02:00 committed by Tobias Burnus
parent 3b833dcda5
commit 82a4f54cc5
18 changed files with 571 additions and 88 deletions

View File

@ -1,3 +1,9 @@
2013-07-21 Tobias Burnus <burnus@net-b.de>
PR fortran/35862
* libgfortran.h (GFC_FPE_DOWNWARD, GFC_FPE_TONEAREST,
GFC_FPE_TOWARDZERO, GFC_FPE_UPWARD): New defines.
2013-07-21 Tobias Burnus <burnus@net-b.de>
PR fortran/57894

View File

@ -43,6 +43,12 @@ along with GCC; see the file COPYING3. If not see
#define GFC_FPE_UNDERFLOW (1<<4)
#define GFC_FPE_INEXACT (1<<5)
/* Defines for floating-point rounding modes. */
#define GFC_FPE_DOWNWARD 1
#define GFC_FPE_TONEAREST 2
#define GFC_FPE_TOWARDZERO 3
#define GFC_FPE_UPWARD 4
/* Bitmasks for the various runtime checks that can be enabled. */
#define GFC_RTCHECK_BOUNDS (1<<0)

View File

@ -1,3 +1,8 @@
2013-07-21 Tobias Burnus <burnus@net-b.de>
PR fortran/35862
* gfortran.dg/round_4.f90: New.
2013-07-21 Tobias Burnus <burnus@net-b.de>
PR fortran/57894

View File

@ -0,0 +1,102 @@
! { dg-do run }
! { dg-add-options ieee }
!
! PR fortran/35862
!
! Test whether I/O rounding works. Uses internally (libgfortran) strtod
! for the conversion - and sets the CPU rounding mode accordingly.
!
! If it doesn't work on your system, please check whether strtod handles
! rounding and whether your system is supported in libgfortran/config/fpu*.c
!
! Please only add ... run { target { ! { triplets } } } if it is unfixable
! on your target - and a note why (strtod doesn't handle it, no rounding
! support, etc.)
!
program main
use iso_fortran_env
implicit none
! The following uses kinds=10 and 16 if available or
! 8 and 10 - or 8 and 16 - or 4 and 8.
integer, parameter :: xp = real_kinds(ubound(real_kinds,dim=1)-1)
integer, parameter :: qp = real_kinds(ubound(real_kinds,dim=1))
real(4) :: r4p, r4m, ref4u, ref4d
real(8) :: r8p, r8m, ref8u, ref8d
real(xp) :: r10p, r10m, ref10u, ref10d
real(qp) :: r16p, r16m, ref16u, ref16d
character(len=20) :: str, round
ref4u = 0.100000001_4
ref8u = 0.10000000000000001_8
if (xp == 4) then
ref10u = 0.100000001_xp
elseif (xp == 8) then
ref10u = 0.10000000000000001_xp
else ! xp == 10
ref10u = 0.1000000000000000000014_xp
end if
if (qp == 8) then
ref16u = 0.10000000000000001_qp
elseif (qp == 10) then
ref16u = 0.1000000000000000000014_qp
else ! qp == 16
ref16u = 0.10000000000000000000000000000000000481_qp
end if
! ref*d = 9.999999...
ref4d = nearest (ref4u, -1.0_4)
ref8d = nearest (ref8u, -1.0_8)
ref10d = nearest (ref10u, -1.0_xp)
ref16d = nearest (ref16u, -1.0_qp)
round = 'up'
call t()
if (r4p /= ref4u .or. r4m /= -ref4d) call abort()
if (r8p /= ref8u .or. r8m /= -ref8d) call abort()
if (r10p /= ref10u .or. r10m /= -ref10d) call abort()
if (r16p /= ref16u .or. r16m /= -ref16d) call abort()
round = 'down'
call t()
if (r4p /= ref4d .or. r4m /= -ref4u) call abort()
if (r8p /= ref8d .or. r8m /= -ref8u) call abort()
if (r10p /= ref10d .or. r10m /= -ref10u) call abort()
if (r16p /= ref16d .or. r16m /= -ref16u) call abort()
round = 'zero'
call t()
if (r4p /= ref4d .or. r4m /= -ref4d) call abort()
if (r8p /= ref8d .or. r8m /= -ref8d) call abort()
if (r10p /= ref10d .or. r10m /= -ref10d) call abort()
if (r16p /= ref16d .or. r16m /= -ref16d) call abort()
round = 'nearest'
call t()
if (r4p /= ref4u .or. r4m /= -ref4u) call abort()
if (r8p /= ref8u .or. r8m /= -ref8u) call abort()
if (r10p /= ref10u .or. r10m /= -ref10u) call abort()
if (r16p /= ref16u .or. r16m /= -ref16u) call abort()
! Same as nearest (but rounding towards zero if there is a tie
! [does not apply here])
round = 'compatible'
call t()
if (r4p /= ref4u .or. r4m /= -ref4u) call abort()
if (r8p /= ref8u .or. r8m /= -ref8u) call abort()
if (r10p /= ref10u .or. r10m /= -ref10u) call abort()
if (r16p /= ref16u .or. r16m /= -ref16u) call abort()
contains
subroutine t()
! print *, round
str = "0.1 0.1 0.1 0.1"
read (str, *,round=round) r4p, r8p, r10p, r16p
! write (*, '(*(g0:" "))') r4p, r8p, r10p, r16p
str = "-0.1 -0.1 -0.1 -0.1"
read (str, *,round=round) r4m, r8m, r10m, r16m
! write (*, *) r4m, r8m, r10m, r16m
end subroutine t
end program main

View File

@ -1,3 +1,27 @@
2013-07-21 Tobias Burnus <burnus@net-b.de>
Uros Bizjak <ubizjak@gmail.com>
PR fortran/35862
* libgfortran.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): New prototypes.
* config/fpu-387.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): New functions.
* config/fpu-aix.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): Ditto.
* config/fpu-generic.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): Ditto.
* config/fpu-glibc.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): Ditto.
* config/fpu-sysv.h (set_fpu_rounding_mode,
get_fpu_rounding_mode): Ditto.
* configure.ac: Check for fp_rnd and fp_rnd_t.
* io/io.h (enum unit_round): Use GFC_FPE_* for the value.
* io/read.c (convert_real): Set FP ronding mode.
* Makefile.in: Regenerate.
* aclocal.m4: Regenerate.
* config.h.in: Regenerate.
* configure: Regenerate.
2013-06-24 Tobias Burnus <burnus@net-b.de>
* configure.ac: Check for fp_except and fp_except_t.

View File

@ -1,9 +1,9 @@
# Makefile.in generated by automake 1.11.3 from Makefile.am.
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -87,12 +87,6 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(cafexeclibdir)" \
"$(DESTDIR)$(myexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" \
"$(DESTDIR)$(toolexeclibdir)"
@ -1282,7 +1276,7 @@ all: $(BUILT_SOURCES) config.h
.SUFFIXES:
.SUFFIXES: .F90 .c .f90 .lo .o .obj
am--refresh: Makefile
am--refresh:
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
@ -1318,8 +1312,10 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@if test ! -f $@; then rm -f stamp-h1; else :; fi
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@ -1426,11 +1422,11 @@ clean-toolexeclibLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES) $(EXTRA_libcaf_single_la_DEPENDENCIES)
libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES)
$(libcaf_single_la_LINK) -rpath $(cafexeclibdir) $(libcaf_single_la_OBJECTS) $(libcaf_single_la_LIBADD) $(LIBS)
libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES) $(EXTRA_libgfortran_la_DEPENDENCIES)
libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES)
$(libgfortran_la_LINK) -rpath $(toolexeclibdir) $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD) $(LIBS)
libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES) $(EXTRA_libgfortranbegin_la_DEPENDENCIES)
libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES)
$(libgfortranbegin_la_LINK) -rpath $(myexeclibdir) $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_LIBADD) $(LIBS)
mostlyclean-compile:
@ -5690,7 +5686,9 @@ uninstall-toolexeclibDATA:
@$(NORMAL_UNINSTALL)
@list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@ -5762,15 +5760,10 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:

View File

@ -1,8 +1,7 @@
# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
# Inc.
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -20,15 +19,12 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
# Foundation, Inc.
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
@ -38,7 +34,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.11.3], [],
m4_if([$1], [1.11.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -54,21 +50,19 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.11.3])dnl
[AM_AUTOMAKE_VERSION([1.11.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
@ -150,14 +144,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
# 2010, 2011 Free Software Foundation, Inc.
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 12
# serial 10
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
@ -197,7 +191,6 @@ AC_CACHE_CHECK([dependency style of $depcc],
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@ -262,7 +255,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
break
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@ -327,13 +320,10 @@ AC_DEFUN([AM_DEP_TRACK],
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
AC_SUBST([am__nodep])dnl
_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
@ -555,15 +545,12 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
# Inc.
# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@ -582,8 +569,8 @@ AC_SUBST(install_sh)])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
# 2011 Free Software Foundation, Inc.
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -603,7 +590,7 @@ AC_DEFUN([AM_MAINTAINER_MODE],
[disable], [m4_define([am_maintainer_other], [enable])],
[m4_define([am_maintainer_other], [enable])
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
AC_ARG_ENABLE([maintainer-mode],
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
@ -749,15 +736,12 @@ else
fi
])
# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
# Inc.
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
@ -780,14 +764,13 @@ esac
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
# Foundation, Inc.
# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 5
# serial 4
# _AM_MANGLE_OPTION(NAME)
# -----------------------
@ -795,13 +778,13 @@ AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# --------------------
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@ -877,14 +860,12 @@ Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 1
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
@ -907,13 +888,13 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 3
# serial 2
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
@ -922,13 +903,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
# --------------------------
# ---------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -950,11 +931,10 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
[# Always define AMTAR for backward compatibility.
AM_MISSING_PROG([AMTAR], [tar])
m4_if([$1], [v7],
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])

View File

@ -411,6 +411,12 @@
/* Define to 1 if the system has the type `fp_except_t'. */
#undef HAVE_FP_EXCEPT_T
/* Define to 1 if the system has the type `fp_rnd'. */
#undef HAVE_FP_RND
/* Define to 1 if the system has the type `fp_rnd_t'. */
#undef HAVE_FP_RND_T
/* fp_trap is present */
#undef HAVE_FP_TRAP

View File

@ -88,7 +88,7 @@ has_sse (void)
#endif
}
/* i387 -- see linux <fpu_control.h> header file for details. */
/* i387 exceptions -- see linux <fpu_control.h> header file for details. */
#define _FPU_MASK_IM 0x01
#define _FPU_MASK_DM 0x02
#define _FPU_MASK_ZM 0x04
@ -99,7 +99,18 @@ has_sse (void)
#define _FPU_EX_ALL 0x3f
void set_fpu (void)
/* i387 rounding modes. */
#define _FPU_RC_NEAREST 0x0
#define _FPU_RC_DOWN 0x400
#define _FPU_RC_UP 0x800
#define _FPU_RC_ZERO 0xc00
#define _FPU_RC_MASK 0xc00
void
set_fpu (void)
{
int excepts = 0;
unsigned short cw;
@ -164,3 +175,72 @@ get_fpu_except_flags (void)
return result;
}
void
set_fpu_rounding_mode (int round)
{
int round_mode;
unsigned short cw;
switch (round)
{
case GFC_FPE_TONEAREST:
round_mode = _FPU_RC_NEAREST;
break;
case GFC_FPE_UPWARD:
round_mode = _FPU_RC_UP;
break;
case GFC_FPE_DOWNWARD:
round_mode = _FPU_RC_DOWN;
break;
case GFC_FPE_TOWARDZERO:
round_mode = _FPU_RC_ZERO;
break;
default:
return; /* Should be unreachable. */
}
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw));
cw &= ~FPU_RC_MASK;
cw |= round_mode;
__asm__ __volatile__ ("fldcw\t%0" : : "m" (cw));
if (has_sse())
{
unsigned int cw_sse;
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
/* The SSE round control bits are shifted by 3 bits. */
cw_sse &= ~(FPU_RC_MASK << 3);
cw_sse |= round_mode << 3;
__asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse));
}
}
int
get_fpu_rounding_mode (void)
{
unsigned short cw;
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw));
cw &= FPU_RC_MASK;
switch (cw)
{
case _FPU_RC_NEAREST:
return GFC_FPE_TONEAREST;
case _FPU_RC_UP:
return GFC_FPE_UPWARD;
case _FPU_RC_DOWN:
return GFC_FPE_DOWNWARD;
case _FPU_RC_ZERO:
return GFC_FPE_TOWARDZERO;
default:
return GFC_FPE_INVALID; /* Should be unreachable. */
}
}

View File

@ -116,3 +116,75 @@ get_fpu_except_flags (void)
return result;
}
int
get_fpu_rounding_mode (void)
{
int rnd_mode;
rnd_mode = fegetround ();
switch (rnd_mode)
{
#ifdef FE_TONEAREST
case FE_TONEAREST:
return GFC_FPE_TONEAREST;
#endif
#ifdef FE_UPWARD
case FE_UPWARD:
return GFC_FPE_UPWARD;
#endif
#ifdef FE_DOWNWARD
case FE_DOWNWARD:
return GFC_FPE_DOWNWARD;
#endif
#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
return GFC_FPE_TOWARDZERO;
#endif
default:
return GFC_FPE_INVALID;
}
}
void
set_fpu_rounding_mode (int mode)
{
int rnd_mode;
switch (mode)
{
#ifdef FE_TONEAREST
case GFC_FPE_TONEAREST:
rnd_mode = FE_TONEAREST;
break;
#endif
#ifdef FE_UPWARD
case GFC_FPE_UPWARD:
rnd_mode = FE_UPWARD;
break;
#endif
#ifdef FE_DOWNWARD
case GFC_FPE_DOWNWARD:
rnd_mode = FE_DOWNWARD;
break;
#endif
#ifdef FE_TOWARDZERO
case GFC_FPE_TOWARDZERO:
rnd_mode = FE_TOWARDZERO;
break;
#endif
default:
return;
}
fesetround (rnd_mode);
}

View File

@ -56,3 +56,16 @@ get_fpu_except_flags (void)
{
return 0;
}
int
get_fpu_rounding_mode (void)
{
return 0;
}
void
set_fpu_rounding_mode (int round __attribute__((unused)))
{
}

View File

@ -127,3 +127,75 @@ get_fpu_except_flags (void)
return result;
}
int
get_fpu_rounding_mode (void)
{
int rnd_mode;
rnd_mode = fegetround ();
switch (rnd_mode)
{
#ifdef FE_TONEAREST
case FE_TONEAREST:
return GFC_FPE_TONEAREST;
#endif
#ifdef FE_UPWARD
case FE_UPWARD:
return GFC_FPE_UPWARD;
#endif
#ifdef FE_DOWNWARD
case FE_DOWNWARD:
return GFC_FPE_DOWNWARD;
#endif
#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
return GFC_FPE_TOWARDZERO;
#endif
default:
return GFC_FPE_INVALID;
}
}
void
set_fpu_rounding_mode (int mode)
{
int rnd_mode;
switch (mode)
{
#ifdef FE_TONEAREST
case GFC_FPE_TONEAREST:
rnd_mode = FE_TONEAREST;
break;
#endif
#ifdef FE_UPWARD
case GFC_FPE_UPWARD:
rnd_mode = FE_UPWARD;
break;
#endif
#ifdef FE_DOWNWARD
case GFC_FPE_DOWNWARD:
rnd_mode = FE_DOWNWARD;
break;
#endif
#ifdef FE_TOWARDZERO
case GFC_FPE_TOWARDZERO:
rnd_mode = FE_TOWARDZERO;
break;
#endif
default:
return;
}
fesetround (rnd_mode);
}

View File

@ -128,3 +128,76 @@ get_fpu_except_flags (void)
return result;
}
int
get_fpu_rounding_mode (void)
{
switch (fpgetround ())
{
#ifdef FP_RN
case FP_RN:
return GFC_FPE_TONEAREST;
#endif
#ifdef FP_RP
case FP_RP:
return GFC_FPE_UPWARD;
#endif
#ifdef FP_RM
case FP_RM:
return GFC_FPE_DOWNWARD;
#endif
#ifdef FP_RZ
case FP_RZ:
return GFC_FPE_TOWARDZERO;
#endif
default:
return GFC_FPE_INVALID;
}
}
void
set_fpu_rounding_mode (int mode)
{
#if HAVE_FP_RND
fp_rnd rnd_mode;
#elif HAVE_FP_RND_T
fp_rnd_t rnd_mode;
#else
choke me
#endif
switch (mode)
{
#ifdef FP_RN
case GFC_FPE_TONEAREST:
rnd_mode = FP_RN;
break;
#endif
#ifdef FP_RP
case GFC_FPE_UPWARD:
rnd_mode = FP_RP;
break;
#endif
#ifdef FP_RM
case GFC_FPE_DOWNWARD:
rnd_mode = FP_RM;
break;
#endif
#ifdef FP_RZ
case GFC_FPE_TOWARDZERO:
rnd_mode = FP_RZ;
break;
#endif
default:
return;
}
fpsetround (rnd_mode);
}

41
libgfortran/configure vendored
View File

@ -654,7 +654,6 @@ CPP
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
@ -3387,11 +3386,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
# Always define AMTAR for backward compatibility.
am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
AMTAR=${AMTAR-"${am_missing_run}tar"}
am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
@ -3524,7 +3523,6 @@ fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
@ -4342,7 +4340,6 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@ -4402,7 +4399,7 @@ else
break
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@ -5518,7 +5515,6 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@ -5578,7 +5574,7 @@ else
break
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@ -12335,7 +12331,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 12338 "configure"
#line 12334 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -12441,7 +12437,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 12444 "configure"
#line 12440 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -26030,6 +26026,27 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "fp_rnd" "ac_cv_type_fp_rnd" "#include <ieeefp.h>
"
if test "x$ac_cv_type_fp_rnd" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_FP_RND 1
_ACEOF
fi
ac_fn_c_check_type "$LINENO" "fp_rnd_t" "ac_cv_type_fp_rnd_t" "#include <ieeefp.h>
"
if test "x$ac_cv_type_fp_rnd_t" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_FP_RND_T 1
_ACEOF
fi

View File

@ -513,6 +513,7 @@ fi
# Check for SysV fpsetmask
LIBGFOR_CHECK_FPSETMASK
AC_CHECK_TYPES([fp_except,fp_except_t], [], [], [[#include <ieeefp.h>]])
AC_CHECK_TYPES([fp_rnd,fp_rnd_t], [], [], [[#include <ieeefp.h>]])
# Check for AIX fp_trap and fp_enable
AC_CHECK_FUNC([fp_trap],[have_fp_trap=yes AC_DEFINE([HAVE_FP_TRAP],[1],[fp_trap is present])])

View File

@ -186,8 +186,14 @@ typedef enum
unit_encoding;
typedef enum
{ ROUND_UP, ROUND_DOWN, ROUND_ZERO, ROUND_NEAREST, ROUND_COMPATIBLE,
ROUND_PROCDEFINED, ROUND_UNSPECIFIED }
{ ROUND_UP = GFC_FPE_UPWARD,
ROUND_DOWN = GFC_FPE_DOWNWARD,
ROUND_ZERO = GFC_FPE_TOWARDZERO,
ROUND_NEAREST = GFC_FPE_TONEAREST,
ROUND_COMPATIBLE = 10, /* round away from zero. */
ROUND_PROCDEFINED, /* Here as ROUND_NEAREST. */
ROUND_UNSPECIFIED /* Should never occur. */
}
unit_round;
/* NOTE: unit_sign must correspond with the sign_status enumerator in

View File

@ -129,6 +129,24 @@ int
convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length)
{
char *endptr = NULL;
int round_mode, old_round_mode;
switch (dtp->u.p.current_unit->round_status)
{
case ROUND_COMPATIBLE:
/* FIXME: As NEAREST but round away from zero for a tie. */
case ROUND_UNSPECIFIED:
/* Should not occur. */
case ROUND_PROCDEFINED:
round_mode = ROUND_NEAREST;
break;
default:
round_mode = dtp->u.p.current_unit->round_status;
break;
}
old_round_mode = get_fpu_rounding_mode();
set_fpu_rounding_mode (round_mode);
switch (length)
{
@ -167,6 +185,8 @@ convert_real (st_parameter_dt *dtp, void *dest, const char *buffer, int length)
internal_error (&dtp->common, "Unsupported real kind during IO");
}
set_fpu_rounding_mode (old_round_mode);
if (buffer == endptr)
{
generate_error (&dtp->common, LIBERROR_READ_VALUE,

View File

@ -743,9 +743,16 @@ internal_proto(gf_strerror);
extern void set_fpu (void);
internal_proto(set_fpu);
extern int get_fpu_except_flags (void);
internal_proto(get_fpu_except_flags);
extern void set_fpu_rounding_mode (int round);
internal_proto(set_fpu_rounding_mode);
extern int get_fpu_rounding_mode (void);
internal_proto(get_fpu_rounding_mode);
/* memory.c */
extern void *xmalloc (size_t) __attribute__ ((malloc));