(force_fit_value): Operate on REAL_CST as well.

(real_value_truncate): Don't use its own handler.
(const_binop): Set overflow on FP error and call force_fit_type.
(fold_convert): Likewise.

From-SVN: r6768
This commit is contained in:
Richard Kenner 1994-03-13 08:30:50 -05:00
parent 831522a46e
commit 649ff3b44f

View File

@ -140,7 +140,10 @@ decode (shorts, low, hi)
that don't belong in the type.
Yield 1 if a signed overflow occurs, 0 otherwise.
If OVERFLOW is nonzero, a signed overflow has already occurred
in calculating T, so propagate it. */
in calculating T, so propagate it.
Make the real constant T valid for its type by calling CHECK_FLOAT_VALUE,
if it exists. */
int
force_fit_type (t, overflow)
@ -150,7 +153,16 @@ force_fit_type (t, overflow)
HOST_WIDE_INT low, high;
register int prec;
if (TREE_CODE (t) != INTEGER_CST)
if (TREE_CODE (t) == REAL_CST)
{
#ifdef CHECK_FLOAT_VALUE
CHECK_FLOAT_VALUE (TYPE_MODE (TREE_TYPE (t)), TREE_REAL_CST (t),
overflow);
#endif
return overflow;
}
else if (TREE_CODE (t) != INTEGER_CST)
return overflow;
low = TREE_INT_CST_LOW (t);
@ -803,34 +815,19 @@ div_and_round_double (code, uns,
}
#ifndef REAL_ARITHMETIC
/* Effectively truncate a real value to represent
the nearest possible value in a narrower mode.
The result is actually represented in the same data type as the argument,
but its value is usually different. */
/* Effectively truncate a real value to represent the nearest possible value
in a narrower mode. The result is actually represented in the same data
type as the argument, but its value is usually different.
A trap may occur during the FP operations and it is the responsibility
of the calling function to have a handler established. */
REAL_VALUE_TYPE
real_value_truncate (mode, arg)
enum machine_mode mode;
REAL_VALUE_TYPE arg;
{
#ifdef __STDC__
/* Make sure the value is actually stored in memory before we turn off
the handler. */
volatile
#endif
REAL_VALUE_TYPE value;
jmp_buf handler, old_handler;
int handled;
if (setjmp (handler))
{
error ("floating overflow");
return dconst0;
}
handled = push_float_handler (handler, old_handler);
value = REAL_VALUE_TRUNCATE (mode, arg);
pop_float_handler (handled, old_handler);
return value;
return REAL_VALUE_TRUNCATE (mode, arg);
}
#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
@ -1333,18 +1330,19 @@ const_binop (code, arg1, arg2, notrunc)
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
if (TREE_CODE (arg1) == REAL_CST)
{
REAL_VALUE_TYPE d1;
REAL_VALUE_TYPE d2;
REAL_VALUE_TYPE d1 = TREE_REAL_CST (arg1);
REAL_VALUE_TYPE d2 = TREE_REAL_CST (arg2);
int overflow = 0;
REAL_VALUE_TYPE value;
tree t;
d1 = TREE_REAL_CST (arg1);
d2 = TREE_REAL_CST (arg2);
if (setjmp (float_error))
{
pedwarn ("floating overflow in constant expression");
return build (code, TREE_TYPE (arg1), arg1, arg2);
t = copy_node (arg1);
overflow = 1;
goto got_float;
}
set_float_handler (float_error);
#ifdef REAL_ARITHMETIC
@ -1387,7 +1385,16 @@ const_binop (code, arg1, arg2, notrunc)
#endif /* no REAL_ARITHMETIC */
t = build_real (TREE_TYPE (arg1),
real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value));
got_float:
set_float_handler (NULL_PTR);
TREE_OVERFLOW (t)
= (force_fit_type (t, overflow)
| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t)
| TREE_CONSTANT_OVERFLOW (arg1)
| TREE_CONSTANT_OVERFLOW (arg2);
return t;
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
@ -1540,6 +1547,7 @@ fold_convert (t, arg1)
register tree arg1;
{
register tree type = TREE_TYPE (t);
int overflow = 0;
if (TREE_CODE (type) == POINTER_TYPE || INTEGRAL_TYPE_P (type))
{
@ -1583,10 +1591,8 @@ fold_convert (t, arg1)
u++;
#endif
if (! (REAL_VALUES_LESS (l, x) && REAL_VALUES_LESS (x, u)))
{
pedwarn ("real constant out of range for integer conversion");
return t;
}
overflow = 1;
#ifndef REAL_ARITHMETIC
{
REAL_VALUE_TYPE d;
@ -1619,7 +1625,10 @@ fold_convert (t, arg1)
}
#endif
TREE_TYPE (t) = type;
force_fit_type (t, 0);
TREE_OVERFLOW (t)
= TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
TREE_TYPE (t) = type;
@ -1634,14 +1643,21 @@ fold_convert (t, arg1)
{
if (setjmp (float_error))
{
pedwarn ("floating overflow in constant expression");
return t;
overflow = 1;
t = copy_node (arg1);
goto got_it;
}
set_float_handler (float_error);
t = build_real (type, real_value_truncate (TYPE_MODE (type),
TREE_REAL_CST (arg1)));
set_float_handler (NULL_PTR);
got_it:
TREE_OVERFLOW (t)
= TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
return t;
}
}