toplev.c (set_float_handler): Make static.
* 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. From-SVN: r44815
This commit is contained in:
parent
31cdd4996b
commit
94aca34298
16 changed files with 314 additions and 224 deletions
|
@ -1,3 +1,26 @@
|
|||
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
|
||||
|
|
|
@ -38,7 +38,6 @@ end ifc
|
|||
%{
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include <setjmp.h>
|
||||
#include "tree.h"
|
||||
#include "input.h"
|
||||
#include "cpplib.h"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
101
gcc/fold-const.c
101
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. */
|
||||
|
||||
int
|
||||
exact_real_inverse (mode, r)
|
||||
enum machine_mode mode;
|
||||
REAL_VALUE_TYPE *r;
|
||||
struct exact_real_inverse_args
|
||||
{
|
||||
jmp_buf float_error;
|
||||
REAL_VALUE_TYPE *r;
|
||||
enum machine_mode mode;
|
||||
int success;
|
||||
};
|
||||
|
||||
static void
|
||||
exact_real_inverse_1 (p)
|
||||
PTR p;
|
||||
{
|
||||
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)
|
||||
# define K (2 * HOST_FLOAT_WORDS_BIG_ENDIAN)
|
||||
#endif
|
||||
#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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
struct simplify_unary_real_args args;
|
||||
args.operand = trueop;
|
||||
args.mode = mode;
|
||||
args.code = code;
|
||||
args.want_integer = false;
|
||||
|
||||
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;
|
||||
if (do_float_handler (simplify_unary_real, (PTR) &args))
|
||||
return args.result;
|
||||
|
||||
set_float_handler (handler);
|
||||
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case NEG:
|
||||
d = REAL_VALUE_NEGATE (d);
|
||||
break;
|
||||
|
||||
case ABS:
|
||||
if (REAL_VALUE_NEGATIVE (d))
|
||||
d = REAL_VALUE_NEGATE (d);
|
||||
break;
|
||||
|
||||
case FLOAT_TRUNCATE:
|
||||
d = real_value_truncate (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;
|
||||
|
||||
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;
|
||||
struct simplify_unary_real_args args;
|
||||
args.operand = trueop;
|
||||
args.mode = mode;
|
||||
args.code = code;
|
||||
args.want_integer = true;
|
||||
|
||||
if (setjmp (handler))
|
||||
return 0;
|
||||
if (do_float_handler (simplify_unary_real, (PTR) &args))
|
||||
return args.result;
|
||||
|
||||
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 ();
|
||||
}
|
||||
|
||||
set_float_handler (NULL);
|
||||
|
||||
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;
|
||||
struct simplify_binary_real_args args;
|
||||
args.trueop0 = trueop0;
|
||||
args.trueop1 = trueop1;
|
||||
args.mode = mode;
|
||||
args.code = code;
|
||||
|
||||
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);
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
58
gcc/varasm.c
58
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;
|
||||
REAL_VALUE_TYPE *d;
|
||||
enum machine_mode mode;
|
||||
};
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
set_float_handler (NULL);
|
||||
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;
|
||||
|
||||
internal_error ("floating point trap outputting a constant");
|
||||
}
|
||||
|
||||
/* Here we combine duplicate floating constants to make
|
||||
|
|
Loading…
Add table
Reference in a new issue