diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/fortran/gfortranspec.c | 38 | ||||
-rw-r--r-- | gcc/fortran/trans-io.c | 49 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/quad_1.f90 | 35 | ||||
-rw-r--r-- | gcc/testsuite/lib/gcc-defs.exp | 3 | ||||
-rw-r--r-- | gcc/testsuite/lib/gfortran.exp | 20 |
8 files changed, 168 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a7c4439..61a0df6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2010-11-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + Tobias Burnus <burnus@net-b.de> + + PR fortran/32049 + * gfortranspec.c (find_spec_file): New function. + (lang_specific_driver): Try to find .spec file and use it. + * trans-io.c (iocall): Define IOCALL_X_REAL128/COMPLEX128(,write). + (gfc_build_io_library_fndecls): Build decl for __float128 I/O. + (transfer_expr): Call __float128 I/O functions. + * trans-types.c (gfc_init_kinds): Allow kind-16 belonging + to __float128. + 2010-11-15 Tobias Burnus <burnus@net.b.de> PR fortran/46484 diff --git a/gcc/fortran/gfortranspec.c b/gcc/fortran/gfortranspec.c index 44d80232..24c9093 100644 --- a/gcc/fortran/gfortranspec.c +++ b/gcc/fortran/gfortranspec.c @@ -63,6 +63,9 @@ along with GCC; see the file COPYING3. If not see #define FORTRAN_LIBRARY "gfortran" #endif +/* Name of the spec file. */ +#define SPEC_FILE "libgfortran.spec" + /* The original argument list and related info is copied here. */ static unsigned int g77_xargc; static const struct cl_decoded_option *g77_x_decoded_options; @@ -72,6 +75,27 @@ static void append_arg (const struct cl_decoded_option *); static unsigned int g77_newargc; static struct cl_decoded_option *g77_new_decoded_options; + +/* Return full path name of spec file if it is in DIR, or NULL if + not. */ +static char * +find_spec_file (const char *dir) +{ + const char dirsep_string[] = { DIR_SEPARATOR, '\0' }; + char *spec; + struct stat sb; + + spec = XNEWVEC (char, strlen (dir) + sizeof (SPEC_FILE) + 4); + strcpy (spec, dir); + strcat (spec, dirsep_string); + strcat (spec, SPEC_FILE); + if (!stat (spec, &sb)) + return spec; + free (spec); + return NULL; +} + + /* Return whether strings S1 and S2 are both NULL or both the same string. */ @@ -199,6 +223,9 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options, /* Whether we should link a static libgfortran. */ int static_lib = 0; + /* The path to the spec file. */ + char *spec_file = NULL; + /* Whether we need to link statically. */ int static_linking = 0; @@ -283,6 +310,12 @@ For more information about these matters, see the file named COPYING\n\n")); cool facility for handling --help and --verbose --help. */ return; + case OPT_L: + if (!spec_file) + spec_file = find_spec_file (decoded_options[i].arg); + break; + + default: break; } @@ -413,6 +446,11 @@ For more information about these matters, see the file named COPYING\n\n")); #endif + /* Read the specs file corresponding to libgfortran. + If we didn't find the spec file on the -L path, then we hope it + is somewhere in the standard install areas. */ + append_option (OPT_specs_, spec_file == NULL ? SPEC_FILE : spec_file, 1); + if (verbose && g77_new_decoded_options != g77_x_decoded_options) { fprintf (stderr, _("Driving:")); diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c index 2ac3e5c..04ad870 100644 --- a/gcc/fortran/trans-io.c +++ b/gcc/fortran/trans-io.c @@ -126,6 +126,10 @@ enum iocall IOCALL_X_REAL_WRITE, IOCALL_X_COMPLEX, IOCALL_X_COMPLEX_WRITE, + IOCALL_X_REAL128, + IOCALL_X_REAL128_WRITE, + IOCALL_X_COMPLEX128, + IOCALL_X_COMPLEX128_WRITE, IOCALL_X_ARRAY, IOCALL_X_ARRAY_WRITE, IOCALL_OPEN, @@ -365,6 +369,23 @@ gfc_build_io_library_fndecls (void) get_identifier (PREFIX("transfer_complex_write")), ".wR", void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node); + /* Version for __float128. */ + iocall[IOCALL_X_REAL128] = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("transfer_real128")), ".wW", + void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node); + + iocall[IOCALL_X_REAL128_WRITE] = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("transfer_real128_write")), ".wR", + void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node); + + iocall[IOCALL_X_COMPLEX128] = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("transfer_complex128")), ".wW", + void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node); + + iocall[IOCALL_X_COMPLEX128_WRITE] = gfc_build_library_function_decl_with_spec ( + get_identifier (PREFIX("transfer_complex128_write")), ".wR", + void_type_node, 3, dt_parm_type, pvoid_type_node, gfc_int4_type_node); + iocall[IOCALL_X_ARRAY] = gfc_build_library_function_decl_with_spec ( get_identifier (PREFIX("transfer_array")), ".ww", void_type_node, 4, dt_parm_type, pvoid_type_node, @@ -2057,18 +2078,38 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code) case BT_REAL: arg2 = build_int_cst (NULL_TREE, kind); if (last_dt == READ) - function = iocall[IOCALL_X_REAL]; + { + if (gfc_real16_is_float128 && ts->kind == 16) + function = iocall[IOCALL_X_REAL128]; + else + function = iocall[IOCALL_X_REAL]; + } else - function = iocall[IOCALL_X_REAL_WRITE]; + { + if (gfc_real16_is_float128 && ts->kind == 16) + function = iocall[IOCALL_X_REAL128_WRITE]; + else + function = iocall[IOCALL_X_REAL_WRITE]; + } break; case BT_COMPLEX: arg2 = build_int_cst (NULL_TREE, kind); if (last_dt == READ) - function = iocall[IOCALL_X_COMPLEX]; + { + if (gfc_real16_is_float128 && ts->kind == 16) + function = iocall[IOCALL_X_COMPLEX128]; + else + function = iocall[IOCALL_X_COMPLEX]; + } else - function = iocall[IOCALL_X_COMPLEX_WRITE]; + { + if (gfc_real16_is_float128 && ts->kind == 16) + function = iocall[IOCALL_X_COMPLEX128_WRITE]; + else + function = iocall[IOCALL_X_COMPLEX_WRITE]; + } break; diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index a597cd7..0571bd1 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -418,8 +418,12 @@ gfc_init_kinds (void) useless. TODO: TFmode support should be enabled once libgfortran support is done. */ if (mode != TYPE_MODE (float_type_node) - && (mode != TYPE_MODE (double_type_node)) - && (mode != TYPE_MODE (long_double_type_node))) + && (mode != TYPE_MODE (double_type_node)) + && (mode != TYPE_MODE (long_double_type_node)) +#ifdef LIBGCC2_HAS_TF_MODE + && (mode != TFmode) +#endif + ) continue; /* Let the kind equal the precision divided by 8, rounding up. Again, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 87aebe6..f6f9671 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2010-11-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + Tobias Burnus <burnus@net-b.de> + + PR fortran/32049 + * gfortran.dg/quad_1.f90: New. + * lib/gcc-defs.exp (gcc-set-multilib-library-path): Use also + compiler arguments. + * lib/gfortran.exp (gfortran_link_flags): Add libquadmath to + library search path; call gcc-set-multilib-library-path with + arguments such that libgfortran.spec is found. + (gfortran_init): Add path for libgfortran.spec to GFORTRAN_UNDER_TEST. + 2010-11-16 Jakub Jelinek <jakub@redhat.com> PR c++/46401 diff --git a/gcc/testsuite/gfortran.dg/quad_1.f90 b/gcc/testsuite/gfortran.dg/quad_1.f90 new file mode 100644 index 0000000..7d4322e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/quad_1.f90 @@ -0,0 +1,35 @@ +! { dg-do link } +! +! This test checks whether the largest possible +! floating-point number works. That's usually +! REAL(16) -- either because the hardware supports it or +! because of libquadmath. However, it can also be +! REAL(10) or REAL(8) +! +program test_qp + use iso_fortran_env, only: real_kinds + implicit none + integer, parameter :: QP = real_kinds(ubound(real_kinds,dim=1)) + real(QP), parameter :: Z1 = 1,HALF_PI = asin(Z1),PI = HALF_PI+HALF_PI + real(QP) :: x = 0.124_QP + complex(QP) :: z = 0.124_QP + print *, 'kind = ', qp + print *, x + print *, PI + print *, 16*atan(0.2_QP)-4*atan(Z1/239) + print *, sin(PI) + print *, cos(HALF_PI) + print *, asinh(PI) + print *, erfc(Z1) + print *, epsilon(x) + print *, precision(x) + print *, digits(x) + + print *, z + print *, PI*cmplx(0.0_qp, 1.0_qp) + print *, 16*atan(0.2_QP)-4*atan(Z1/239) + print *, sin(z) + print *, cos(z) + print *, sinh(z) ! asinh not implemented, cf. PR 46416 + print *, precision(z) +end program test_qp diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp index 776456d..af898e5 100644 --- a/gcc/testsuite/lib/gcc-defs.exp +++ b/gcc/testsuite/lib/gcc-defs.exp @@ -250,9 +250,10 @@ proc gcc-set-multilib-library-path { compiler } { } set libpath ":${rootme}" + set options [lrange $compiler 1 end] set compiler [lindex $compiler 0] if { [is_remote host] == 0 && [which $compiler] != 0 } { - foreach i "[exec $compiler --print-multi-lib]" { + foreach i "[exec $compiler $options --print-multi-lib]" { set mldir "" regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir set mldir [string trimright $mldir "\;@"] diff --git a/gcc/testsuite/lib/gfortran.exp b/gcc/testsuite/lib/gfortran.exp index 56aef29..be4e7fe 100644 --- a/gcc/testsuite/lib/gfortran.exp +++ b/gcc/testsuite/lib/gfortran.exp @@ -103,11 +103,22 @@ proc gfortran_link_flags { paths } { if [file exists "${gccpath}/libgfortran/libgforbegin.a"] { append flags "-L${gccpath}/libgfortran " } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.a"] { + # Some targets use libquadmath.a%s in their specs, so they need a -B option + # for uninstalled testing. + append flags "-B${gccpath}/libquadmath/.libs " + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } + if [file exists "${gccpath}/libquadmath/.libs/libquadmath.${shlib_ext}"] { + append flags "-L${gccpath}/libquadmath/.libs " + append ld_library_path ":${gccpath}/libquadmath/.libs" + } if [file exists "${gccpath}/libiberty/libiberty.a"] { append flags "-L${gccpath}/libiberty " } append ld_library_path \ - [gcc-set-multilib-library-path $GFORTRAN_UNDER_TEST] + [gcc-set-multilib-library-path { $GFORTRAN_UNDER_TEST } ] } set_ld_library_path_env_vars @@ -150,7 +161,12 @@ proc gfortran_init { args } { if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } { set GFORTRAN_UNDER_TEST [transform gfortran] } else { - set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]] + if [info exists TOOL_OPTIONS] { + set specpath [get_multilibs ${TOOL_OPTIONS}] + } else { + set specpath [get_multilibs] + } + set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../ -L$specpath/libgfortran" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]] } } } |