summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2001-08-12 01:56:10 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2001-08-12 01:56:10 +0000
commitcc1900961aebe17dc7ff52e21a54ec71148bd951 (patch)
tree7e0d274b9d7e3a3888aa3d22cd6cba4854e43f24 /gcc
parent9dc9d0d3203a4285c79fb71ff4c5c92531ac45aa (diff)
downloadgcc-cc1900961aebe17dc7ff52e21a54ec71148bd951.tar.gz
* toplev.c (set_float_handler): Make static.
* toplev.h: Don't prototype set_float_handler. * simplify-rtx.c: Don't include setjmp.h. (simplify_unary_real, simplify_binary_real, simplify_binary_is2orm1): New functions. (simplify_unary_operation, simplify_binary_operation): Use them, via do_float_handler. * fold-const.c: Don't include setjmp.h. (exact_real_inverse_1): New function. (exact_real_inverse): Use it, via do_float_handler. * varasm.c: Don't include setjmp.h. (assemble_real_1): New function. (assemble_real): Use it, via do_float_handler. Call internal_error if we get a trap here. * c-parse.in, cse.c, cselib.c, ch/lex.c, config/i386/i386.c, config/pj/pj.c, config/s390/s390.c: Don't include setjmp.h. * java/lex.h: Don't include setjmp.h. Don't define SET_FLOAT_HANDLER or prototype set_float_handler. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44815 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/c-parse.in1
-rw-r--r--gcc/ch/ChangeLog4
-rw-r--r--gcc/ch/lex.c1
-rw-r--r--gcc/config/i386/i386.c1
-rw-r--r--gcc/config/pj/pj.c1
-rw-r--r--gcc/config/s390/s390.c1
-rw-r--r--gcc/cse.c1
-rw-r--r--gcc/cselib.c1
-rw-r--r--gcc/fold-const.c99
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/lex.h5
-rw-r--r--gcc/simplify-rtx.c331
-rw-r--r--gcc/toplev.c3
-rw-r--r--gcc/toplev.h3
-rw-r--r--gcc/varasm.c58
16 files changed, 314 insertions, 224 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 04cc0916e56..880b27b0df7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,28 @@
2001-08-11 Zack Weinberg <zackw@panix.com>
+ * toplev.c (set_float_handler): Make static.
+ * toplev.h: Don't prototype set_float_handler.
+
+ * simplify-rtx.c: Don't include setjmp.h.
+ (simplify_unary_real, simplify_binary_real, simplify_binary_is2orm1):
+ New functions.
+ (simplify_unary_operation, simplify_binary_operation): Use them,
+ via do_float_handler.
+
+ * fold-const.c: Don't include setjmp.h.
+ (exact_real_inverse_1): New function.
+ (exact_real_inverse): Use it, via do_float_handler.
+
+ * varasm.c: Don't include setjmp.h.
+ (assemble_real_1): New function.
+ (assemble_real): Use it, via do_float_handler.
+ Call internal_error if we get a trap here.
+
+ * c-parse.in, cse.c, cselib.c, config/i386/i386.c,
+ config/pj/pj.c, config/s390/s390.c: Don't include setjmp.h.
+
+2001-08-11 Zack Weinberg <zackw@panix.com>
+
* defaults.h: Define PREFERRED_STACK_BOUNDARY to
STACK_BOUNDARY if not already defined.
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index 801a265404c..67c603faf2a 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -38,7 +38,6 @@ end ifc
%{
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "tree.h"
#include "input.h"
#include "cpplib.h"
diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog
index f8fe135dcfb..31d6d4963a0 100644
--- a/gcc/ch/ChangeLog
+++ b/gcc/ch/ChangeLog
@@ -1,3 +1,7 @@
+2001-08-11 Zack Weinberg <zackw@panix.com>
+
+ * lex.c: Don't include setjmp.h.
+
2001-08-09 Richard Henderson <rth@redhat.com>
* grant.c (chill_finish_compile): Use target hooks instead of
diff --git a/gcc/ch/lex.c b/gcc/ch/lex.c
index 4eae0a5df3d..8b05f52ec29 100644
--- a/gcc/ch/lex.c
+++ b/gcc/ch/lex.c
@@ -21,7 +21,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include <sys/stat.h>
#include "tree.h"
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index aae281ca4c3..a557d05def8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -20,7 +20,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
-#include <setjmp.h>
#include "system.h"
#include "rtl.h"
#include "tree.h"
diff --git a/gcc/config/pj/pj.c b/gcc/config/pj/pj.c
index 02ef9a25acf..b867179a3fe 100644
--- a/gcc/config/pj/pj.c
+++ b/gcc/config/pj/pj.c
@@ -78,7 +78,6 @@ Boston, MA 02111-1307, USA. */
order, so nothing more needs to be done. */
-#include <setjmp.h>
#include "config.h"
#include "system.h"
#include "rtl.h"
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index c3917505445..e07c64c85ae 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -21,7 +21,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
-#include <setjmp.h>
#include "system.h"
#include "rtl.h"
#include "tree.h"
diff --git a/gcc/cse.c b/gcc/cse.c
index f5b1afa016e..256b28f6c49 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
/* stdio.h must precede rtl.h for FFS. */
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tm_p.h"
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 619bad174c2..002c2f5a2db 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -21,7 +21,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tm_p.h"
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5ffaf105742..00af527c380 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -44,7 +44,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "flags.h"
#include "tree.h"
#include "rtl.h"
@@ -59,6 +58,9 @@ static void encode PARAMS ((HOST_WIDE_INT *,
static void decode PARAMS ((HOST_WIDE_INT *,
unsigned HOST_WIDE_INT *,
HOST_WIDE_INT *));
+#ifndef REAL_ARITHMETIC
+static void exact_real_inverse_1 PARAMS ((PTR));
+#endif
static tree negate_expr PARAMS ((tree));
static tree split_tree PARAMS ((tree, enum tree_code, tree *, tree *,
int));
@@ -956,51 +958,41 @@ target_negative (x)
/* Try to change R into its exact multiplicative inverse in machine mode
MODE. Return nonzero function value if successful. */
+struct exact_real_inverse_args
+{
+ REAL_VALUE_TYPE *r;
+ enum machine_mode mode;
+ int success;
+};
-int
-exact_real_inverse (mode, r)
- enum machine_mode mode;
- REAL_VALUE_TYPE *r;
+static void
+exact_real_inverse_1 (p)
+ PTR p;
{
- jmp_buf float_error;
+ struct exact_real_inverse_args *args =
+ (struct exact_real_inverse_args *) p;
+
+ enum machine_mode mode = args->mode;
+ REAL_VALUE_TYPE *r = args->r;
+
union
- {
- double d;
- unsigned short i[4];
- }x, t, y;
+ {
+ double d;
+ unsigned short i[4];
+ }
+ x, t, y;
#ifdef CHECK_FLOAT_VALUE
int i;
#endif
- /* Usually disable if bounds checks are not reliable. */
- if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT) && !flag_pretend_float)
- return 0;
-
/* Set array index to the less significant bits in the unions, depending
- on the endian-ness of the host doubles.
- Disable if insufficient information on the data structure. */
-#if HOST_FLOAT_FORMAT == UNKNOWN_FLOAT_FORMAT
- return 0;
+ on the endian-ness of the host doubles. */
+#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT \
+ || HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
+# define K 2
#else
-#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
-#define K 2
-#else
-#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
-#define K 2
-#else
-#define K (2 * HOST_FLOAT_WORDS_BIG_ENDIAN)
-#endif
+# define K (2 * HOST_FLOAT_WORDS_BIG_ENDIAN)
#endif
-#endif
-
- if (setjmp (float_error))
- {
- /* Don't do the optimization if there was an arithmetic error. */
-fail:
- set_float_handler (NULL);
- return 0;
- }
- set_float_handler (float_error);
/* Domain check the argument. */
x.d = *r;
@@ -1040,9 +1032,40 @@ fail:
#endif
/* Output the reciprocal and return success flag. */
- set_float_handler (NULL);
*r = y.d;
- return 1;
+ args->success = 1;
+ return;
+
+ fail:
+ args->success = 0;
+ return;
+
+#undef K
+}
+
+
+int
+exact_real_inverse (mode, r)
+ enum machine_mode mode;
+ REAL_VALUE_TYPE *r;
+{
+ struct exact_real_inverse_args args;
+
+ /* Disable if insufficient information on the data structure. */
+#if HOST_FLOAT_FORMAT == UNKNOWN_FLOAT_FORMAT
+ return 0;
+#endif
+
+ /* Usually disable if bounds checks are not reliable. */
+ if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT) && !flag_pretend_float)
+ return 0;
+
+ args.mode = mode;
+ args.r = r;
+
+ if (do_float_handler (exact_real_inverse_1, (PTR) &args))
+ return args.success;
+ return 0;
}
/* Convert C99 hexadecimal floating point string constant S. Return
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 79245740fb8..0356cb7a2af 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+2001-08-11 Zack Weinberg <zackw@panix.com>
+
+ * lex.h: Don't include setjmp.h. Don't define
+ SET_FLOAT_HANDLER or prototype set_float_handler.
+
2001-08-09 Richard Henderson <rth@redhat.com>
* Make-lang.in (class.o): Depend on TARGET_H.
diff --git a/gcc/java/lex.h b/gcc/java/lex.h
index e5d217deb1e..ef9e6e40174 100644
--- a/gcc/java/lex.h
+++ b/gcc/java/lex.h
@@ -26,8 +26,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#ifndef GCC_JAVA_LEX_H
#define GCC_JAVA_LEX_H
-#include <setjmp.h> /* set_float_handler argument uses it */
-
/* Extern global variables declarations */
extern FILE *finput;
extern int lineno;
@@ -172,7 +170,6 @@ extern void java_destroy_lexer PARAMS ((java_lexer *));
#define DCONST0 0
#define REAL_VALUE_TYPE int
-#define SET_FLOAT_HANDLER(H)
#define GET_IDENTIFIER(S) xstrdup ((S))
#define REAL_VALUE_ATOF(LIT,MODE) 0
#define REAL_VALUE_ISINF(VALUE) 0
@@ -192,8 +189,6 @@ extern void java_destroy_lexer PARAMS ((java_lexer *));
#else
-extern void set_float_handler PARAMS ((jmp_buf));
-#define SET_FLOAT_HANDLER(H) set_float_handler ((H))
#define DCONST0 dconst0
#define GET_IDENTIFIER(S) get_identifier ((S))
#define SET_REAL_VALUE_ATOF(TARGET,SOURCE) (TARGET) = (SOURCE)
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 11254da5e1b..08adde25963 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tm_p.h"
@@ -99,6 +98,12 @@ Boston, MA 02111-1307, USA. */
static rtx simplify_plus_minus PARAMS ((enum rtx_code,
enum machine_mode, rtx, rtx));
static void check_fold_consts PARAMS ((PTR));
+#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
+static void simplify_unary_real PARAMS ((PTR));
+static void simplify_binary_real PARAMS ((PTR));
+#endif
+static void simplify_binary_is2orm1 PARAMS ((PTR));
+
/* Make a binary operation by properly ordering the operands and
seeing if the expression folds. */
@@ -324,10 +329,70 @@ simplify_replace_rtx (x, old, new)
return x;
}
+#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
+/* Subroutine of simplify_unary_operation, called via do_float_handler.
+ Handles simplification of unary ops on floating point values. */
+struct simplify_unary_real_args
+{
+ rtx operand;
+ rtx result;
+ enum machine_mode mode;
+ enum rtx_code code;
+ bool want_integer;
+};
+#define REAL_VALUE_ABS(d_) \
+ (REAL_VALUE_NEGATIVE (d_) ? REAL_VALUE_NEGATE (d_) : (d_))
+
+static void
+simplify_unary_real (p)
+ PTR p;
+{
+ REAL_VALUE_TYPE d;
+
+ struct simplify_unary_real_args *args =
+ (struct simplify_unary_real_args *) p;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d, args->operand);
+
+ if (args->want_integer)
+ {
+ HOST_WIDE_INT i;
+
+ switch (args->code)
+ {
+ case FIX: i = REAL_VALUE_FIX (d); break;
+ case UNSIGNED_FIX: i = REAL_VALUE_UNSIGNED_FIX (d); break;
+ default:
+ abort ();
+ }
+ args->result = GEN_INT (trunc_int_for_mode (i, args->mode));
+ }
+ else
+ {
+ switch (args->code)
+ {
+ case SQRT:
+ /* We don't attempt to optimize this. */
+ args->result = 0;
+ return;
+
+ case ABS: d = REAL_VALUE_ABS (d); break;
+ case NEG: d = REAL_VALUE_NEGATE (d); break;
+ case FLOAT_TRUNCATE: d = real_value_truncate (args->mode, d); break;
+ case FLOAT_EXTEND: /* All this does is change the mode. */ break;
+ case FIX: d = REAL_VALUE_RNDZINT (d); break;
+ case UNSIGNED_FIX: d = REAL_VALUE_UNSIGNED_RNDZINT (d); break;
+ default:
+ abort ();
+ }
+ args->result = CONST_DOUBLE_FROM_REAL_VALUE (d, args->mode);
+ }
+}
+#endif
+
/* Try to simplify a unary operation CODE whose output mode is to be
MODE with input operand OP whose mode was originally OP_MODE.
Return zero if no simplification can be made. */
-
rtx
simplify_unary_operation (code, mode, op, op_mode)
enum rtx_code code;
@@ -586,57 +651,16 @@ simplify_unary_operation (code, mode, op, op_mode)
else if (GET_CODE (trueop) == CONST_DOUBLE
&& GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- REAL_VALUE_TYPE d;
- jmp_buf handler;
- rtx x;
-
- if (setjmp (handler))
- /* There used to be a warning here, but that is inadvisable.
- People may want to cause traps, and the natural way
- to do it should not get a warning. */
- return 0;
-
- set_float_handler (handler);
-
- REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
-
- switch (code)
- {
- case NEG:
- d = REAL_VALUE_NEGATE (d);
- break;
+ struct simplify_unary_real_args args;
+ args.operand = trueop;
+ args.mode = mode;
+ args.code = code;
+ args.want_integer = false;
- case ABS:
- if (REAL_VALUE_NEGATIVE (d))
- d = REAL_VALUE_NEGATE (d);
- break;
-
- case FLOAT_TRUNCATE:
- d = real_value_truncate (mode, d);
- break;
+ if (do_float_handler (simplify_unary_real, (PTR) &args))
+ return args.result;
- case FLOAT_EXTEND:
- /* All this does is change the mode. */
- break;
-
- case FIX:
- d = REAL_VALUE_RNDZINT (d);
- break;
-
- case UNSIGNED_FIX:
- d = REAL_VALUE_UNSIGNED_RNDZINT (d);
- break;
-
- case SQRT:
- return 0;
-
- default:
- abort ();
- }
-
- x = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
- set_float_handler (NULL);
- return x;
+ return 0;
}
else if (GET_CODE (trueop) == CONST_DOUBLE
@@ -644,36 +668,16 @@ simplify_unary_operation (code, mode, op, op_mode)
&& GET_MODE_CLASS (mode) == MODE_INT
&& width <= HOST_BITS_PER_WIDE_INT && width > 0)
{
- REAL_VALUE_TYPE d;
- jmp_buf handler;
- HOST_WIDE_INT val;
-
- if (setjmp (handler))
- return 0;
-
- set_float_handler (handler);
-
- REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
-
- switch (code)
- {
- case FIX:
- val = REAL_VALUE_FIX (d);
- break;
-
- case UNSIGNED_FIX:
- val = REAL_VALUE_UNSIGNED_FIX (d);
- break;
-
- default:
- abort ();
- }
+ struct simplify_unary_real_args args;
+ args.operand = trueop;
+ args.mode = mode;
+ args.code = code;
+ args.want_integer = true;
- set_float_handler (NULL);
+ if (do_float_handler (simplify_unary_real, (PTR) &args))
+ return args.result;
- val = trunc_int_for_mode (val, mode);
-
- return GEN_INT (val);
+ return 0;
}
#endif
/* This was formerly used only for non-IEEE float.
@@ -749,12 +753,101 @@ simplify_unary_operation (code, mode, op, op_mode)
}
}
+#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
+/* Subroutine of simplify_binary_operation, called via do_float_handler.
+ Handles simplification of binary ops on floating point values. */
+struct simplify_binary_real_args
+{
+ rtx trueop0, trueop1;
+ rtx result;
+ enum rtx_code code;
+ enum machine_mode mode;
+};
+
+static void
+simplify_binary_real (p)
+ PTR p;
+{
+ REAL_VALUE_TYPE f0, f1, value;
+ struct simplify_binary_real_args *args =
+ (struct simplify_binary_real_args *) p;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (f0, args->trueop0);
+ REAL_VALUE_FROM_CONST_DOUBLE (f1, args->trueop1);
+ f0 = real_value_truncate (args->mode, f0);
+ f1 = real_value_truncate (args->mode, f1);
+
+#ifdef REAL_ARITHMETIC
+#ifndef REAL_INFINITY
+ if (args->code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
+ {
+ args->result = 0;
+ return;
+ }
+#endif
+ REAL_ARITHMETIC (value, rtx_to_tree_code (args->code), f0, f1);
+#else
+ switch (args->code)
+ {
+ case PLUS:
+ value = f0 + f1;
+ break;
+ case MINUS:
+ value = f0 - f1;
+ break;
+ case MULT:
+ value = f0 * f1;
+ break;
+ case DIV:
+#ifndef REAL_INFINITY
+ if (f1 == 0)
+ return 0;
+#endif
+ value = f0 / f1;
+ break;
+ case SMIN:
+ value = MIN (f0, f1);
+ break;
+ case SMAX:
+ value = MAX (f0, f1);
+ break;
+ default:
+ abort ();
+ }
+#endif
+
+ value = real_value_truncate (args->mode, value);
+ args->result = CONST_DOUBLE_FROM_REAL_VALUE (value, args->mode);
+}
+#endif
+
+/* Another subroutine called via do_float_handler. This one tests
+ the floating point value given against 2. and -1. */
+struct simplify_binary_is2orm1_args
+{
+ rtx value;
+ bool is_2;
+ bool is_m1;
+};
+
+static void
+simplify_binary_is2orm1 (p)
+ PTR p;
+{
+ REAL_VALUE_TYPE d;
+ struct simplify_binary_is2orm1_args *args =
+ (struct simplify_binary_is2orm1_args *) p;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d, args->value);
+ args->is_2 = REAL_VALUES_EQUAL (d, dconst2);
+ args->is_m1 = REAL_VALUES_EQUAL (d, dconstm1);
+}
+
/* Simplify a binary operation CODE with result mode MODE, operating on OP0
and OP1. Return 0 if no simplification is possible.
Don't use this for relational operations such as EQ or LT.
Use simplify_relational_operation instead. */
-
rtx
simplify_binary_operation (code, mode, op0, op1)
enum rtx_code code;
@@ -790,58 +883,15 @@ simplify_binary_operation (code, mode, op0, op1)
&& GET_CODE (trueop1) == CONST_DOUBLE
&& mode == GET_MODE (op0) && mode == GET_MODE (op1))
{
- REAL_VALUE_TYPE f0, f1, value;
- jmp_buf handler;
-
- if (setjmp (handler))
- return 0;
-
- set_float_handler (handler);
-
- REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0);
- REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1);
- f0 = real_value_truncate (mode, f0);
- f1 = real_value_truncate (mode, f1);
-
-#ifdef REAL_ARITHMETIC
-#ifndef REAL_INFINITY
- if (code == DIV && REAL_VALUES_EQUAL (f1, dconst0))
- return 0;
-#endif
- REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
-#else
- switch (code)
- {
- case PLUS:
- value = f0 + f1;
- break;
- case MINUS:
- value = f0 - f1;
- break;
- case MULT:
- value = f0 * f1;
- break;
- case DIV:
-#ifndef REAL_INFINITY
- if (f1 == 0)
- return 0;
-#endif
- value = f0 / f1;
- break;
- case SMIN:
- value = MIN (f0, f1);
- break;
- case SMAX:
- value = MAX (f0, f1);
- break;
- default:
- abort ();
- }
-#endif
-
- value = real_value_truncate (mode, value);
- set_float_handler (NULL);
- return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
+ struct simplify_binary_real_args args;
+ args.trueop0 = trueop0;
+ args.trueop1 = trueop1;
+ args.mode = mode;
+ args.code = code;
+
+ if (do_float_handler (simplify_binary_real, (PTR) &args))
+ return args.result;
+ return 0;
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
@@ -1263,24 +1313,17 @@ simplify_binary_operation (code, mode, op0, op1)
if (GET_CODE (trueop1) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT)
{
- REAL_VALUE_TYPE d;
- jmp_buf handler;
- int op1is2, op1ism1;
+ struct simplify_binary_is2orm1_args args;
- if (setjmp (handler))
+ args.value = trueop1;
+ if (! do_float_handler (simplify_binary_is2orm1, (PTR) &args))
return 0;
- set_float_handler (handler);
- REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
- op1is2 = REAL_VALUES_EQUAL (d, dconst2);
- op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
- set_float_handler (NULL);
-
/* x*2 is x+x and x*(-1) is -x */
- if (op1is2 && GET_MODE (op0) == mode)
+ if (args.is_2 && GET_MODE (op0) == mode)
return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
- else if (op1ism1 && GET_MODE (op0) == mode)
+ else if (args.is_m1 && GET_MODE (op0) == mode)
return gen_rtx_NEG (mode, op0);
}
break;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index a2d489da8ff..57646264704 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -161,6 +161,7 @@ static const char *decl_name PARAMS ((tree, int));
static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void set_float_handler PARAMS ((jmp_buf));
static void compile_file PARAMS ((const char *));
static void display_help PARAMS ((void));
static void display_target_options PARAMS ((void));
@@ -1679,7 +1680,7 @@ float_signal (signo)
/* Specify where to longjmp to when a floating arithmetic error happens.
If HANDLER is 0, it means don't handle the errors any more. */
-void
+static void
set_float_handler (handler)
jmp_buf handler;
{
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 2892dc4cab0..bc9b1608c62 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -102,9 +102,6 @@ extern void error_for_asm PARAMS ((struct rtx_def *,
extern void warning_for_asm PARAMS ((struct rtx_def *,
const char *, ...))
ATTRIBUTE_PRINTF_2;
-#if defined (_JBLEN) || defined (setjmp)
-extern void set_float_handler PARAMS ((jmp_buf));
-#endif
extern int do_float_handler PARAMS ((void (*) (PTR), PTR));
#ifdef BUFSIZ
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 7480cf68c7a..5f2810aca4d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "rtl.h"
#include "tree.h"
#include "flags.h"
@@ -138,6 +137,7 @@ tree last_assemble_variable_decl;
static const char *strip_reg_name PARAMS ((const char *));
static int contains_pointers_p PARAMS ((tree));
+static void assemble_real_1 PARAMS ((PTR));
static void decode_addr_const PARAMS ((tree, struct addr_const *));
static int const_hash PARAMS ((tree));
static int compare_constant PARAMS ((tree,
@@ -1798,68 +1798,74 @@ assemble_integer (x, size, force)
}
/* Assemble the floating-point constant D into an object of size MODE. */
-
-void
-assemble_real (d, mode)
- REAL_VALUE_TYPE d;
- enum machine_mode mode;
+struct assemble_real_args
{
- jmp_buf output_constant_handler;
-
- if (setjmp (output_constant_handler))
- {
- error ("floating point trap outputting a constant");
-#ifdef REAL_IS_NOT_DOUBLE
- memset ((char *) &d, 0, sizeof d);
- d = dconst0;
-#else
- d = 0;
-#endif
- }
+ REAL_VALUE_TYPE *d;
+ enum machine_mode mode;
+};
- set_float_handler (output_constant_handler);
+static void
+assemble_real_1 (p)
+ PTR p;
+{
+ struct assemble_real_args *args = (struct assemble_real_args *) p;
+ REAL_VALUE_TYPE *d = args->d;
+ enum machine_mode mode = args->mode;
switch (mode)
{
#ifdef ASM_OUTPUT_BYTE_FLOAT
case QFmode:
- ASM_OUTPUT_BYTE_FLOAT (asm_out_file, d);
+ ASM_OUTPUT_BYTE_FLOAT (asm_out_file, *d);
break;
#endif
#ifdef ASM_OUTPUT_SHORT_FLOAT
case HFmode:
- ASM_OUTPUT_SHORT_FLOAT (asm_out_file, d);
+ ASM_OUTPUT_SHORT_FLOAT (asm_out_file, *d);
break;
#endif
#ifdef ASM_OUTPUT_THREE_QUARTER_FLOAT
case TQFmode:
- ASM_OUTPUT_THREE_QUARTER_FLOAT (asm_out_file, d);
+ ASM_OUTPUT_THREE_QUARTER_FLOAT (asm_out_file, *d);
break;
#endif
#ifdef ASM_OUTPUT_FLOAT
case SFmode:
- ASM_OUTPUT_FLOAT (asm_out_file, d);
+ ASM_OUTPUT_FLOAT (asm_out_file, *d);
break;
#endif
#ifdef ASM_OUTPUT_DOUBLE
case DFmode:
- ASM_OUTPUT_DOUBLE (asm_out_file, d);
+ ASM_OUTPUT_DOUBLE (asm_out_file, *d);
break;
#endif
#ifdef ASM_OUTPUT_LONG_DOUBLE
case XFmode:
case TFmode:
- ASM_OUTPUT_LONG_DOUBLE (asm_out_file, d);
+ ASM_OUTPUT_LONG_DOUBLE (asm_out_file, *d);
break;
#endif
default:
abort ();
}
+}
+
+void
+assemble_real (d, mode)
+ REAL_VALUE_TYPE d;
+ enum machine_mode mode;
+{
+ struct assemble_real_args args;
+ args.d = &d;
+ args.mode = mode;
+
+ if (do_float_handler (assemble_real_1, (PTR) &args))
+ return;
- set_float_handler (NULL);
+ internal_error ("floating point trap outputting a constant");
}
/* Here we combine duplicate floating constants to make