diff options
author | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2005-10-12 20:21:31 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2005-10-12 20:21:31 +0000 |
commit | 944b8b35a92ccdde4c4fa5458a1b48d8e8a25412 (patch) | |
tree | af4f5409e807606750191918d192516dcd170012 /gcc | |
parent | f23a977ce50e244b7cda0d54d36e5b8e6d505795 (diff) | |
download | gcc-944b8b35a92ccdde4c4fa5458a1b48d8e8a25412.zip gcc-944b8b35a92ccdde4c4fa5458a1b48d8e8a25412.tar.gz gcc-944b8b35a92ccdde4c4fa5458a1b48d8e8a25412.tar.bz2 |
gfortran.h: Add bitmasks for different FPE traps.
* gfortran.h: Add bitmasks for different FPE traps. Add fpe
member to options_t.
* invoke.texi: Document the new -ffpe-trap option.
* lang.opt: Add -ffpe-trap option.
* options.c (gfc_init_options): Initialize the FPE option.
(gfc_handle_fpe_trap_option): New function to parse the argument
of the -ffpe-trap option.
(gfc_handle_option): Add case for -ffpe-trap.
* trans-decl.c: Declare a tree for the set_fpe library function.
(gfc_build_builtin_function_decls): Build this tree.
(gfc_generate_function_code): Generate a call to set_fpe at
the beginning of the main program.
* trans.h: New tree for the set_fpe library function.
* Makefile.am: Add fpu.c to the build process, and
target-dependent code as fpu-target.h.
* Makefile.in: Regenerate.
* configure.ac: Add call to configure.host to set
FPU_HOST_HEADER.
* configure: Regenerate.
* config.h.in: Regenerate.
* aclocal.m4: Regenerate.
* configure.host: New script to determine which host-dependent
code should go in.
* libgfortran.h: Add fpe option, remove previous fpu_ options.
Add bitmasks for different FPE traps. Add prototype for set_fpu.
* runtime/environ.c: Remove environment variables to control
fpu behaviour.
* runtime/fpu.c (set_fpe): New function for the front-end.
* runtime/main.c (init): Set FPU state.
* config: New directory to store host-dependent code.
* config/fpu-387.h: New file with code handling the i387 FPU.
* config/fpu-glibc.h: New file with code for glibc systems.
* config/fpu-generic.h: Fallback for the most generic host. Issue
warnings.
From-SVN: r105328
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 11 | ||||
-rw-r--r-- | gcc/fortran/invoke.texi | 18 | ||||
-rw-r--r-- | gcc/fortran/lang.opt | 4 | ||||
-rw-r--r-- | gcc/fortran/options.c | 41 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 21 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 1 |
7 files changed, 112 insertions, 2 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a02586f..91acbf2 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,19 @@ +2005-10-12 Francois-Xavier Coudert <coudert@clipper.ens.fr> + + * gfortran.h: Add bitmasks for different FPE traps. Add fpe + member to options_t. + * invoke.texi: Document the new -ffpe-trap option. + * lang.opt: Add -ffpe-trap option. + * options.c (gfc_init_options): Initialize the FPE option. + (gfc_handle_fpe_trap_option): New function to parse the argument + of the -ffpe-trap option. + (gfc_handle_option): Add case for -ffpe-trap. + * trans-decl.c: Declare a tree for the set_fpe library function. + (gfc_build_builtin_function_decls): Build this tree. + (gfc_generate_function_code): Generate a call to set_fpe at + the beginning of the main program. + * trans.h: New tree for the set_fpe library function. + 2005-10-12 Paul Thomas <pault@gcc.gnu.org> PR fortran/20847 @@ -34,7 +50,7 @@ 2005-10-07 Erik Edelmann <erik.edelmann@iki.fi> - PR 18568 + PR 18568 * resolve.c (find_array_spec): Search through the list of components in the symbol of the type instead of the symbol of the variable. diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 1923826..63b4b93 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -103,6 +103,15 @@ mstring; #define GFC_STD_F95_OBS (1<<1) /* Obsoleted in F95. */ #define GFC_STD_F77 (1<<0) /* Up to and including F77. */ +/* Bitmasks for the various FPE that can be enabled. */ +#define GFC_FPE_INVALID (1<<0) +#define GFC_FPE_DENORMAL (1<<1) +#define GFC_FPE_ZERO (1<<2) +#define GFC_FPE_OVERFLOW (1<<3) +#define GFC_FPE_UNDERFLOW (1<<4) +#define GFC_FPE_PRECISION (1<<5) + + /*************************** Enums *****************************/ /* The author remains confused to this day about the convention of @@ -1453,6 +1462,8 @@ typedef struct int q_kind; + int fpe; + int warn_std; int allow_std; int warn_nonstd_intrinsics; diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 847ab29..88e8eef 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -133,7 +133,7 @@ by type. Explanations are in the following sections. @item Debugging Options @xref{Debugging Options,,Options for Debugging Your Program or GCC}. @gccoptlist{ --fdump-parse-tree} +-fdump-parse-tree -ffpe-trap=@var{list}} @item Directory Options @xref{Directory Options,,Options for Directory Search}. @@ -464,6 +464,22 @@ Output the internal parse tree before starting code generation. Only really useful for debugging gfortran itself. @end table +@table @gcctabopt +@cindex -ffpe-trap=@var{list} option +@cindex option, -ffpe-trap=@var{list} +@item -ffpe-trap=@var{list} +Specify a list of IEEE exceptions when a Floating Point Exception +(FPE) should be raised. On most systems, this will result in a SIGFPE +signal being sent and the program being interrupted, producing a core +file useful for debugging. @var{list} is a (possibly empty) comma-separated +list of the following IEEE exceptions: @samp{invalid} (invalid floating +point operation, such as @code{sqrt(-1.0)}), @samp{zero} (division by +zero), @samp{overflow} (overflow in a floating point operation), +@samp{underflow} (underflow in a floating point operation), +@samp{precision} (loss of precision during operation) and @samp{denormal} +(operation produced a denormal denormal value). +@end table + @xref{Debugging Options,,Options for Debugging Your Program or GCC, gcc,Using the GNU Compiler Collection (GCC)}, for more information on debugging options. diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index ee0d61f..053cc3d 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -165,6 +165,10 @@ qkind= Fortran RejectNegative Joined UInteger -qkind=<n> Set the kind for a real with the 'q' exponent to 'n' +ffpe-trap= +Fortran RejectNegative JoinedOrMissing +-ffpe-trap=[..] Stop on following floating point exceptions + std=f95 Fortran Conform to the ISO Fortran 95 standard diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 48df674..95720bf 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -76,6 +76,8 @@ gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED, gfc_option.q_kind = gfc_default_double_kind; + gfc_option.fpe = 0; + flag_argument_noalias = 2; flag_errno_math = 0; @@ -278,6 +280,41 @@ gfc_handle_module_path_options (const char *arg) strcat (gfc_option.module_dir, "/"); } +static void +gfc_handle_fpe_trap_option (const char *arg) +{ + int result, pos = 0, n; + static const char * const exception[] = { "invalid", "denormal", "zero", + "overflow", "underflow", + "precision", NULL }; + static const int opt_exception[] = { GFC_FPE_INVALID, GFC_FPE_DENORMAL, + GFC_FPE_ZERO, GFC_FPE_OVERFLOW, + GFC_FPE_UNDERFLOW, GFC_FPE_PRECISION, + 0 }; + + while (*arg) + { + while (*arg == ',') + arg++; + while (arg[pos] && arg[pos] != ',') + pos++; + result = 0; + for (n = 0; exception[n] != NULL; n++) + { + if (exception[n] && strncmp (exception[n], arg, pos) == 0) + { + gfc_option.fpe |= opt_exception[n]; + arg += pos; + pos = 0; + result = 1; + break; + } + } + if (! result) + gfc_fatal_error ("Argument to -ffpe-trap is not valid: %s", arg); + } +} + /* Handle command-line options. Returns 0 if unrecognized, 1 if recognized and handled. */ int @@ -440,6 +477,10 @@ gfc_handle_option (size_t scode, const char *arg, int value) gfc_handle_module_path_options (arg); break; + case OPT_ffpe_trap_: + gfc_handle_fpe_trap_option (arg); + break; + case OPT_std_f95: gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77; gfc_option.warn_std = GFC_STD_F95_OBS; diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 3f656dd..70e8e82 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -85,6 +85,7 @@ tree gfor_fndecl_stop_numeric; tree gfor_fndecl_stop_string; tree gfor_fndecl_select_string; tree gfor_fndecl_runtime_error; +tree gfor_fndecl_set_fpe; tree gfor_fndecl_set_std; tree gfor_fndecl_in_pack; tree gfor_fndecl_in_unpack; @@ -1934,6 +1935,7 @@ gfc_build_intrinsic_function_decls (void) void gfc_build_builtin_function_decls (void) { + tree gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind); tree gfc_int4_type_node = gfc_get_int_type (4); tree gfc_int8_type_node = gfc_get_int_type (8); tree gfc_logical4_type_node = gfc_get_logical_type (4); @@ -2018,6 +2020,10 @@ gfc_build_builtin_function_decls (void) /* The runtime_error function does not return. */ TREE_THIS_VOLATILE (gfor_fndecl_runtime_error) = 1; + gfor_fndecl_set_fpe = + gfc_build_library_function_decl (get_identifier (PREFIX("set_fpe")), + void_type_node, 1, gfc_c_int_type_node); + gfor_fndecl_set_std = gfc_build_library_function_decl (get_identifier (PREFIX("set_std")), void_type_node, @@ -2455,6 +2461,21 @@ gfc_generate_function_code (gfc_namespace * ns) gfc_add_expr_to_block (&body, tmp); } + /* If this is the main program and a -ffpe-trap option was provided, + add a call to set_fpe so that the library will raise a FPE when + needed. */ + if (sym->attr.is_main_program && gfc_option.fpe != 0) + { + tree arglist, gfc_c_int_type_node; + + gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind); + arglist = gfc_chainon_list (NULL_TREE, + build_int_cst (gfc_c_int_type_node, + gfc_option.fpe)); + tmp = gfc_build_function_call (gfor_fndecl_set_fpe, arglist); + gfc_add_expr_to_block (&body, tmp); + } + if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node && sym->attr.subroutine) { diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index e64640c..16d0a37 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -455,6 +455,7 @@ extern GTY(()) tree gfor_fndecl_stop_numeric; extern GTY(()) tree gfor_fndecl_stop_string; extern GTY(()) tree gfor_fndecl_select_string; extern GTY(()) tree gfor_fndecl_runtime_error; +extern GTY(()) tree gfor_fndecl_set_fpe; extern GTY(()) tree gfor_fndecl_set_std; extern GTY(()) tree gfor_fndecl_in_pack; extern GTY(()) tree gfor_fndecl_in_unpack; |