summaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-25 20:52:28 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-25 20:52:28 +0000
commit536f5fb115792c70f4e8e459454a9aaeb83cb8f4 (patch)
tree8c35b0cf468101ecc396f5eb7631e99dc328e79c /gcc/simplify-rtx.c
parentcb6b7c90629c20399ced93bb7ef0ee60ec166e80 (diff)
downloadgcc-536f5fb115792c70f4e8e459454a9aaeb83cb8f4.tar.gz
* toplev.c: Don't include setjmp.h. Kill float_handler_set,
float_handled, float_handler, float_signal, set_float_handler, and do_float_handler. Set handler for SIGFPE to crash_signal. * toplev.h: Don't prototype do_float_handler. * c-lex.c: Fold parse_float into lex_number. Make warning about portability of hex float constants more informative, and don't issue it on top of a syntax error. * fold-const.c: Fold const_binop_1 and fold_convert_1 into their callers. * real.h: Define REAL_VALUE_ABS here... * simplify-rtx.c: ... not here. Fold check_fold_consts, simplify_unary_real, simplify_binary_real, and simplify_binary_is2orm1 into their callers. * tree.c: Fold build_real_from_int_cst_1 into caller. * doc/tm.texi: Document REAL_VALUE_ABS and REAL_VALUE_NEGATIVE. * tsystem.h: Include float.h here... * libgcc2.c: ... not here. java: * lex.c: Change java_perform_atof to take normal parameters instead of a pointer to a parameter block. Call it directly from java_lex. testsuite: * gcc.dg/c90-hexfloat-1.c: Adjust error regexps. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51336 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c259
1 files changed, 59 insertions, 200 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 53f8293078e..3bc2824b58a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -101,11 +101,6 @@ static int simplify_plus_minus_op_data_cmp PARAMS ((const void *,
static rtx simplify_plus_minus PARAMS ((enum rtx_code,
enum machine_mode, rtx,
rtx, int));
-static void check_fold_consts PARAMS ((PTR));
-static void simplify_unary_real PARAMS ((PTR));
-static void simplify_binary_real PARAMS ((PTR));
-static void simplify_binary_is2orm1 PARAMS ((PTR));
-
/* Negate a CONST_INT rtx, truncating (because a conversion from a
maximally negative number can overflow). */
@@ -341,65 +336,6 @@ simplify_replace_rtx (x, old, new)
return x;
}
-/* 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_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);
- }
-}
-
/* 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. */
@@ -638,16 +574,25 @@ simplify_unary_operation (code, mode, op, op_mode)
else if (GET_CODE (trueop) == CONST_DOUBLE
&& GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- struct simplify_unary_real_args args;
- args.operand = trueop;
- args.mode = mode;
- args.code = code;
- args.want_integer = false;
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
- if (do_float_handler (simplify_unary_real, (PTR) &args))
- return args.result;
+ switch (code)
+ {
+ case SQRT:
+ /* We don't attempt to optimize this. */
+ return 0;
- return 0;
+ case ABS: d = REAL_VALUE_ABS (d); break;
+ case NEG: 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;
+ default:
+ abort ();
+ }
+ return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
}
else if (GET_CODE (trueop) == CONST_DOUBLE
@@ -655,16 +600,17 @@ simplify_unary_operation (code, mode, op, op_mode)
&& GET_MODE_CLASS (mode) == MODE_INT
&& width <= HOST_BITS_PER_WIDE_INT && width > 0)
{
- struct simplify_unary_real_args args;
- args.operand = trueop;
- args.mode = mode;
- args.code = code;
- args.want_integer = true;
-
- if (do_float_handler (simplify_unary_real, (PTR) &args))
- return args.result;
-
- return 0;
+ HOST_WIDE_INT i;
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
+ switch (code)
+ {
+ case FIX: i = REAL_VALUE_FIX (d); break;
+ case UNSIGNED_FIX: i = REAL_VALUE_UNSIGNED_FIX (d); break;
+ default:
+ abort ();
+ }
+ return gen_int_mode (i, mode);
}
/* This was formerly used only for non-IEEE float.
@@ -740,64 +686,6 @@ simplify_unary_operation (code, mode, op, op_mode)
}
}
-/* 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);
-
- if (args->code == DIV
- && !MODE_HAS_INFINITIES (args->mode)
- && REAL_VALUES_EQUAL (f1, dconst0))
- {
- args->result = 0;
- return;
- }
- REAL_ARITHMETIC (value, rtx_to_tree_code (args->code), f0, f1);
-
- value = real_value_truncate (args->mode, value);
- args->result = CONST_DOUBLE_FROM_REAL_VALUE (value, args->mode);
-}
-
-/* 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.
@@ -837,15 +725,22 @@ simplify_binary_operation (code, mode, op0, op1)
&& GET_CODE (trueop1) == CONST_DOUBLE
&& mode == GET_MODE (op0) && mode == GET_MODE (op1))
{
- 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;
+ REAL_VALUE_TYPE f0, f1, value;
+
+ 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);
+
+ if (code == DIV
+ && !MODE_HAS_INFINITIES (mode)
+ && REAL_VALUES_EQUAL (f1, dconst0))
+ return 0;
+
+ REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
+
+ value = real_value_truncate (mode, value);
+ return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
}
/* We can fold some multi-word operations. */
@@ -1276,20 +1171,18 @@ simplify_binary_operation (code, mode, op0, op1)
&& ! rtx_equal_function_value_matters)
return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));
+ /* x*2 is x+x and x*(-1) is -x */
if (GET_CODE (trueop1) == CONST_DOUBLE
- && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT)
+ && GET_MODE_CLASS (GET_MODE (trueop1)) == MODE_FLOAT
+ && GET_MODE (op0) == mode)
{
- struct simplify_binary_is2orm1_args args;
-
- args.value = trueop1;
- if (! do_float_handler (simplify_binary_is2orm1, (PTR) &args))
- return 0;
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
- /* x*2 is x+x and x*(-1) is -x */
- if (args.is_2 && GET_MODE (op0) == mode)
+ if (REAL_VALUES_EQUAL (d, dconst2))
return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
- else if (args.is_m1 && GET_MODE (op0) == mode)
+ if (REAL_VALUES_EQUAL (d, dconstm1))
return gen_rtx_NEG (mode, op0);
}
break;
@@ -1923,35 +1816,6 @@ simplify_plus_minus (code, mode, op0, op1, force)
return negate ? gen_rtx_NEG (mode, result) : result;
}
-struct cfc_args
-{
- rtx op0, op1; /* Input */
- int equal, op0lt, op1lt; /* Output */
- int unordered;
-};
-
-static void
-check_fold_consts (data)
- PTR data;
-{
- struct cfc_args *args = (struct cfc_args *) data;
- REAL_VALUE_TYPE d0, d1;
-
- /* We may possibly raise an exception while reading the value. */
- args->unordered = 1;
- REAL_VALUE_FROM_CONST_DOUBLE (d0, args->op0);
- REAL_VALUE_FROM_CONST_DOUBLE (d1, args->op1);
-
- /* Comparisons of Inf versus Inf are ordered. */
- if (REAL_VALUE_ISNAN (d0)
- || REAL_VALUE_ISNAN (d1))
- return;
- args->equal = REAL_VALUES_EQUAL (d0, d1);
- args->op0lt = REAL_VALUES_LESS (d0, d1);
- args->op1lt = REAL_VALUES_LESS (d1, d0);
- args->unordered = 0;
-}
-
/* 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
@@ -2035,17 +1899,13 @@ simplify_relational_operation (code, mode, op0, op1)
&& GET_CODE (trueop1) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (trueop0)) == MODE_FLOAT)
{
- struct cfc_args args;
+ REAL_VALUE_TYPE d0, d1;
- /* Setup input for check_fold_consts() */
- args.op0 = trueop0;
- args.op1 = trueop1;
-
-
- if (!do_float_handler (check_fold_consts, (PTR) &args))
- args.unordered = 1;
+ REAL_VALUE_FROM_CONST_DOUBLE (d0, trueop0);
+ REAL_VALUE_FROM_CONST_DOUBLE (d1, trueop1);
- if (args.unordered)
+ /* Comparisons are unordered iff at least one of the values is NaN. */
+ if (REAL_VALUE_ISNAN (d0) || REAL_VALUE_ISNAN (d1))
switch (code)
{
case UNEQ:
@@ -2068,10 +1928,9 @@ simplify_relational_operation (code, mode, op0, op1)
return 0;
}
- /* Receive output from check_fold_consts() */
- equal = args.equal;
- op0lt = op0ltu = args.op0lt;
- op1lt = op1ltu = args.op1lt;
+ equal = REAL_VALUES_EQUAL (d0, d1);
+ op0lt = op0ltu = REAL_VALUES_LESS (d0, d1);
+ op1lt = op1ltu = REAL_VALUES_LESS (d1, d0);
}
/* Otherwise, see if the operands are both integers. */