/* real.c - software floating point emulation.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
Re-written by Richard Henderson <rth@redhat.com>
r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp);
+ /* Zero out the remaining fields. */
+ r->signalling = 0;
+ r->canonical = 0;
/* Re-normalize the result. */
normalize (r);
}
/* Perform the binary or unary operation described by CODE.
- For a unary operation, leave OP1 NULL. */
+ For a unary operation, leave OP1 NULL. This function returns
+ true if the result may be inexact due to loss of precision. */
-void
+bool
real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
const REAL_VALUE_TYPE *op1)
{
switch (code)
{
case PLUS_EXPR:
- do_add (r, op0, op1, 0);
- break;
+ return do_add (r, op0, op1, 0);
case MINUS_EXPR:
- do_add (r, op0, op1, 1);
- break;
+ return do_add (r, op0, op1, 1);
case MULT_EXPR:
- do_multiply (r, op0, op1);
- break;
+ return do_multiply (r, op0, op1);
case RDIV_EXPR:
- do_divide (r, op0, op1);
- break;
+ return do_divide (r, op0, op1);
case MIN_EXPR:
if (op1->cl == rvc_nan)
default:
gcc_unreachable ();
}
+ return false;
}
/* Legacy. Similar, but return the result directly. */
get_zero (r, 0);
else
{
+ memset (r, 0, sizeof (*r));
r->cl = rvc_normal;
r->sign = high < 0 && !unsigned_p;
SET_REAL_EXP (r, 2 * HOST_BITS_PER_WIDE_INT);
{
r->sig[SIGSZ-1] = high;
r->sig[SIGSZ-2] = low;
- memset (r->sig, 0, sizeof(long)*(SIGSZ-2));
}
else
{
r->sig[SIGSZ-2] = high;
r->sig[SIGSZ-3] = low >> (HOST_BITS_PER_LONG - 1) >> 1;
r->sig[SIGSZ-4] = low;
- if (SIGSZ > 4)
- memset (r->sig, 0, sizeof(long)*(SIGSZ-4));
}
normalize (r);
else
{
int base = 10, d;
- bool neg = false;
memset (r, 0, sizeof (*r));
r->cl = rvc_nan;
while (ISSPACE (*str))
str++;
if (*str == '-')
- str++, neg = true;
+ str++;
else if (*str == '+')
str++;
if (*str == '0')
-125,
128,
31,
+ 31,
true,
true,
true,
-125,
128,
31,
+ 31,
true,
true,
true,
-1021,
1024,
63,
+ 63,
true,
true,
true,
-1021,
1024,
63,
+ 63,
true,
true,
true,
-16382,
16384,
95,
+ 95,
true,
true,
true,
-16381,
16384,
79,
+ 79,
true,
true,
true,
-16381,
16384,
79,
+ 79,
true,
true,
true,
-16381,
16384,
79,
+ 79,
true,
true,
true,
53,
-1021 + 53,
1024,
+ 127,
-1,
true,
true,
53,
-1021 + 53,
1024,
+ 127,
-1,
true,
true,
-16381,
16384,
127,
+ 127,
true,
true,
true,
-16381,
16384,
127,
+ 127,
true,
true,
true,
-127,
127,
15,
+ 15,
false,
false,
false,
-127,
127,
15,
+ 15,
false,
false,
false,
-1023,
1023,
15,
+ 15,
false,
false,
false,
-64,
63,
31,
+ 31,
false,
false,
false, /* ??? The encoding does allow for "unnormals". */
-64,
63,
63,
+ 63,
false,
false,
false, /* ??? The encoding does allow for "unnormals". */
24,
-126,
128,
+ 23,
-1,
false,
false,
32,
-126,
128,
+ 31,
-1,
false,
false,
-MAX_EXP,
MAX_EXP,
-1,
+ -1,
true,
true,
false,
do_add (&t, &t, &dconstm1, 0);
if (mode != VOIDmode)
real_convert (r, mode, &t);
+ else
+ *r = t;
}
/* Round X to the smallest integer not less then argument, i.e. round
do_add (&t, &t, &dconst1, 0);
if (mode != VOIDmode)
real_convert (r, mode, &t);
+ else
+ *r = t;
}
/* Round X to the nearest integer, but round halfway cases away from