From 1a87eea22067f6e19e30ad9f5dc2e41c3f204b80 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Sun, 14 Mar 1999 14:02:10 +0000 Subject: [PATCH] cse.c (check_fold_consts): New static function. * cse.c (check_fold_consts): New static function. (cfc_args): New struct. (simplify_relational_operation): Use them in call to `do_float_handler'. * toplev.c (do_float_handler): New function to wrap calls to setjmp/set_float_handler. * toplev.h (do_float_handler): Add extern prototype. * tree.c (build_real_from_int_cst_1): New static function. (brfic_args): New struct. (build_real_from_int_cst): Use them in call to `do_float_handler'. From-SVN: r25768 --- gcc/ChangeLog | 17 +++++++++++++++++ gcc/cse.c | 44 ++++++++++++++++++++++++++++++++++---------- gcc/toplev.c | 27 +++++++++++++++++++++++++++ gcc/toplev.h | 1 + gcc/tree.c | 54 +++++++++++++++++++++++++++++++++++++----------------- 5 files changed, 116 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8390e37..a3084bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +Sun Mar 14 16:22:10 1999 Kaveh R. Ghazi + + * cse.c (check_fold_consts): New static function. + (cfc_args): New struct. + (simplify_relational_operation): Use them in call to + `do_float_handler'. + + * toplev.c (do_float_handler): New function to wrap calls to + setjmp/set_float_handler. + + * toplev.h (do_float_handler): Add extern prototype. + + * tree.c (build_real_from_int_cst_1): New static function. + (brfic_args): New struct. + (build_real_from_int_cst): Use them in call to + `do_float_handler'. + Sun Mar 14 01:15:06 PST 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. diff --git a/gcc/cse.c b/gcc/cse.c index 7d96908..bc22df9 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -664,6 +664,7 @@ static void cse_set_around_loop PROTO((rtx, rtx, rtx)); static rtx cse_basic_block PROTO((rtx, rtx, struct branch_path *, int)); static void count_reg_usage PROTO((rtx, int *, rtx, int)); extern void dump_class PROTO((struct table_elt*)); +static void check_fold_consts PROTO((PTR)); extern int rtx_equal_function_value_matters; @@ -4594,6 +4595,28 @@ cse_gen_binary (code, mode, op0, op1) return gen_rtx_fmt_ee (code, mode, op0, op1); } +struct cfc_args +{ + /* Input */ + rtx op0, op1; + /* Output */ + int equal, op0lt, op1lt; +}; + +static void +check_fold_consts (data) + PTR data; +{ + struct cfc_args * args = (struct cfc_args *) data; + REAL_VALUE_TYPE d0, d1; + + REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0); + REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1); + args->equal = REAL_VALUES_EQUAL (d0, d1); + args->op0lt = REAL_VALUES_LESS (d0, d1); + args->op1lt = REAL_VALUES_LESS (d1, d0); +} + /* Like simplify_binary_operation except used for relational operators. MODE is the mode of the operands, not that of the result. If MODE is VOIDmode, both operands must also be VOIDmode and we compare the @@ -4655,19 +4678,20 @@ simplify_relational_operation (code, mode, op0, op1) else if (GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) { - REAL_VALUE_TYPE d0, d1; - jmp_buf handler; + struct cfc_args args; + + /* Setup input for check_fold_consts() */ + args.op0 = op0; + args.op1 = op1; - if (setjmp (handler)) + if (do_float_handler(check_fold_consts, (PTR) &args) == 0) + /* We got an exception from check_fold_consts() */ return 0; - set_float_handler (handler); - REAL_VALUE_FROM_CONST_DOUBLE (d0, op0); - REAL_VALUE_FROM_CONST_DOUBLE (d1, op1); - equal = REAL_VALUES_EQUAL (d0, d1); - op0lt = op0ltu = REAL_VALUES_LESS (d0, d1); - op1lt = op1ltu = REAL_VALUES_LESS (d1, d0); - set_float_handler (NULL_PTR); + /* Receive output from check_fold_consts() */ + equal = args.equal; + op0lt = op0ltu = args.op0lt; + op1lt = op1ltu = args.op1lt; } #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */ diff --git a/gcc/toplev.c b/gcc/toplev.c index f9a4c20..bceb6cf 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2389,6 +2389,33 @@ set_float_handler (handler) } } +/* This is a wrapper function for code which might elicit an + arithmetic exception. That code should be passed in as a function + pointer FN, and one argument DATA. DATA is usually a struct which + contains the real input and output for function FN. This function + returns 0 (failure) if longjmp was called (i.e. an exception + occured.) It returns 1 (success) otherwise. */ + +int +do_float_handler (fn, data) + void (*fn) PROTO ((PTR)); + PTR data; +{ + jmp_buf buf; + + if (setjmp (buf)) + { + /* We got here via longjmp() caused by an exception in function fn() */ + set_float_handler (NULL); + return 0; + } + + set_float_handler (buf); + (*fn)(data); + set_float_handler (NULL); + return 1; +} + /* Specify, in HANDLER, where to longjmp to when a floating arithmetic error happens, pushing the previous specification into OLD_HANDLER. Return an indication of whether there was a previous handler in effect. */ diff --git a/gcc/toplev.h b/gcc/toplev.h index 1363519..d8acd0d 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -92,6 +92,7 @@ extern void set_float_handler PROTO((jmp_buf)); extern int push_float_handler PROTO((jmp_buf, jmp_buf)); extern void pop_float_handler PROTO((int, jmp_buf)); #endif +extern int do_float_handler PROTO((void (*) (PTR), PTR)); #ifdef BUFSIZ extern void output_quoted_string PROTO ((FILE *, const char *)); diff --git a/gcc/tree.c b/gcc/tree.c index 1114ec34..bfbc8c2 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" -#include #include "flags.h" #include "tree.h" #include "except.h" @@ -266,6 +265,7 @@ int (*lang_get_alias_set) PROTO((tree)); static void set_type_quals PROTO((tree, int)); static void append_random_chars PROTO((char *)); +static void build_real_from_int_cst_1 PROTO((PTR)); extern char *mode_name[]; @@ -1450,6 +1450,29 @@ real_value_from_int_cst (type, i) return d; } +struct brfic_args +{ + /* Input */ + tree type, i; + /* Output */ + REAL_VALUE_TYPE d; +}; + +static void +build_real_from_int_cst_1 (data) + PTR data; +{ + struct brfic_args * args = (struct brfic_args *) data; + +#ifdef REAL_ARITHMETIC + args->d = real_value_from_int_cst (args->type, args->i); +#else + args->d = + REAL_VALUE_TRUNCATE (TYPE_MODE (args->type), + real_value_from_int_cst (args->type, args->i)); +#endif +} + /* This function can't be implemented if we can't do arithmetic on the float representation. */ @@ -1461,32 +1484,29 @@ build_real_from_int_cst (type, i) tree v; int overflow = TREE_OVERFLOW (i); REAL_VALUE_TYPE d; - jmp_buf float_error; + struct brfic_args args; v = make_node (REAL_CST); TREE_TYPE (v) = type; - if (setjmp (float_error)) + /* Setup input for build_real_from_int_cst_1() */ + args.type = type; + args.i = i; + + if (do_float_handler (build_real_from_int_cst_1, (PTR) &args)) + { + /* Receive output from build_real_from_int_cst_1() */ + d = args.d; + } + else { + /* We got an exception from build_real_from_int_cst_1() */ d = dconst0; overflow = 1; - goto got_it; } - - set_float_handler (float_error); - -#ifdef REAL_ARITHMETIC - d = real_value_from_int_cst (type, i); -#else - d = REAL_VALUE_TRUNCATE (TYPE_MODE (type), - real_value_from_int_cst (type, i)); -#endif - + /* Check for valid float value for this type on this target machine. */ - got_it: - set_float_handler (NULL_PTR); - #ifdef CHECK_FLOAT_VALUE CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow); #endif -- 2.7.4