cse.c (check_fold_consts): New static function.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Sun, 14 Mar 1999 14:02:10 +0000 (14:02 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Sun, 14 Mar 1999 14:02:10 +0000 (14:02 +0000)
        * 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
gcc/cse.c
gcc/toplev.c
gcc/toplev.h
gcc/tree.c

index 8390e3738b2e75b077d501d8189f52fd86c3a006..a3084bf44c800cba40b1b996a1c6520eaee374e7 100644 (file)
@@ -1,3 +1,20 @@
+Sun Mar 14 16:22:10 1999  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * 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.
index 7d9690899e50f6822a8890d739766c87594216dc..bc22df9e2c8a9ba5e2a1aec25015553facbaf9f1 100644 (file)
--- 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;
 \f
@@ -4594,6 +4595,28 @@ cse_gen_binary (code, mode, op0, op1)
     return gen_rtx_fmt_ee (code, mode, op0, op1);
 }
 \f
+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 */
 
index f9a4c204ad13592aa8c1850e1e803a34ba787a9e..bceb6cfd6c5559a96ed88f64a1e6e10526c5b136 100644 (file)
@@ -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.  */
index 1363519cc4206679f8b494e3f28355d4a032c287..d8acd0d068bf1b540f0d77d5a00792d03556d854 100644 (file)
@@ -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 *));
index 1114ec3471672c35f7560068b07dfbc48610e09d..bfbc8c285ab12ccefa1329de71c3d9070e09c99e 100644 (file)
@@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
-#include <setjmp.h>
 #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