/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
-and support for XFmode IEEE extended real floating point arithmetic.
-Contributed by Stephen L. Moshier (moshier@world.std.com).
+ and support for XFmode IEEE extended real floating point arithmetic.
+ Contributed by Stephen L. Moshier (moshier@world.std.com).
- Copyright (C) 1993 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
void warning ();
extern int extra_warnings;
int ecmp (), enormlz (), eshift ();
-int eisneg (), eisinf (), eisnan (), eiisinf (), eiisnan ();
+int eisneg (), eisinf (), eisnan (), eiisinf (), eiisnan (), eiisneg ();
void eadd (), esub (), emul (), ediv ();
void eshup1 (), eshup8 (), eshup6 (), eshdn1 (), eshdn8 (), eshdn6 ();
void eabs (), eneg (), emov (), eclear (), einfin (), efloor ();
if (ecmp (d2, ezero) == 0)
{
#ifdef NANS
- enan (v);
+ enan (v, eisneg (d1) ^ eisneg (d2));
break;
#else
abort ();
REAL_VALUE_TYPE r;
GET_REAL (&x, e);
-#ifdef NANS
- if (eisnan (e))
- return (x);
-#endif
eneg (e);
PUT_REAL (e, &r);
return (r);
* esubm (ai, bi) subtract significands, bi = bi - ai
* eiisinf (ai) 1 if infinite
* eiisnan (ai) 1 if a NaN
+ * eiisneg (ai) 1 if sign bit of ai != 0, else 0
* einan (ai) set ai = NaN
* eiinfin (ai) set ai = infinity
*
unsigned EMUSHORT x[];
{
-#ifdef NANS
- if (eisnan (x))
- return;
-#endif
x[NE - 1] ^= 0x8000; /* Toggle the sign bit */
}
-/* Return 1 if external format number is negative,
- * else return zero, including when it is a NaN.
+/* Return 1 if sign bit of external format number is nonzero,
+ * else return zero.
*/
int
eisneg (x)
unsigned EMUSHORT x[];
{
-#ifdef NANS
- if (eisnan (x))
- return (0);
-#endif
if (x[NE - 1] & 0x8000)
return (1);
else
The exponent is 7fff, the leading mantissa word is c000. */
void
-enan (x)
+enan (x, sign)
register unsigned EMUSHORT *x;
+ int sign;
{
register int i;
for (i = 0; i < NE - 2; i++)
*x++ = 0;
*x++ = 0xc000;
- *x = 0x7fff;
+ *x = (sign << 15) | 0x7fff;
}
#ifdef NANS
if (eiisnan (a))
{
- enan (b);
+ enan (b, eiisneg (a));
return;
}
#endif
return (0);
}
+/* Return nonzero if sign of internal format number is nonzero. */
+
+int
+eiisneg (x)
+ unsigned EMUSHORT x[];
+{
+
+ return x[0] != 0;
+}
+
/* Fill internal format number with infinity pattern.
This has maximum exponent and significand all zeros. */
&& ((eisneg (a) ^ eisneg (b)) == 0))
{
mtherr ("esub", INVALID);
- enan (c);
+ enan (c, 0);
return;
}
#endif
&& ((eisneg (a) ^ eisneg (b)) != 0))
{
mtherr ("esub", INVALID);
- enan (c);
+ enan (c, 0);
return;
}
#endif
|| (eisinf (a) && eisinf (b)))
{
mtherr ("ediv", INVALID);
- enan (c);
+ enan (c, eisneg (a) ^ eisneg (b));
return;
}
#endif
|| (eisinf (b) && (ecmp (a, ezero) == 0)))
{
mtherr ("emul", INVALID);
- enan (c);
+ enan (c, eisneg (a) ^ eisneg (b));
return;
}
#endif
if (((pe[3] & 0xf) != 0) || (pe[2] != 0)
|| (pe[1] != 0) || (pe[0] != 0))
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
#else
if (((pe[0] & 0xf) != 0) || (pe[1] != 0)
|| (pe[2] != 0) || (pe[3] != 0))
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
#endif
{
if (pe[i] != 0)
{
- enan (y);
+ enan (y, (*p & 0x8000) != 0);
return;
}
}
{
if (pe[i] != 0)
{
- enan (y);
+ enan (y, (*p & 0x8000) != 0);
return;
}
}
{
if (pe[i] != 0)
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
}
{
if (pe[i] != 0)
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
}
#ifdef MIEEE
if (((pe[0] & 0x7f) != 0) || (pe[1] != 0))
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
#else
if (((pe[1] & 0x7f) != 0) || (pe[0] != 0))
{
- enan (y);
+ enan (y, yy[0] != 0);
return;
}
#endif
#ifdef NANS
if (eisnan (x))
{
- make_nan (e, TFmode);
+ make_nan (e, eisneg (x), TFmode);
return;
}
#endif
#ifdef NANS
if (eiisnan (a))
{
- make_nan (b, TFmode);
+ make_nan (b, eiisneg (a), TFmode);
return;
}
#endif
#ifdef NANS
if (eisnan (x))
{
- make_nan (e, XFmode);
+ make_nan (e, eisneg (x), XFmode);
return;
}
#endif
#ifdef NANS
if (eiisnan (a))
{
- make_nan (b, XFmode);
+ make_nan (b, eiisneg (a), XFmode);
return;
}
#endif
#ifdef NANS
if (eisnan (x))
{
- make_nan (e, DFmode);
+ make_nan (e, eisneg (x), DFmode);
return;
}
#endif
#ifdef NANS
if (eiisnan (x))
{
- make_nan (y, DFmode);
+ make_nan (y, eiisneg (x), DFmode);
return;
}
#endif
#ifdef NANS
if (eisnan (x))
{
- make_nan (e, SFmode);
+ make_nan (e, eisneg (x), SFmode);
return;
}
#endif
#ifdef NANS
if (eiisnan (x))
{
- make_nan (y, SFmode);
+ make_nan (y, eiisneg (x), SFmode);
return;
}
#endif
|| eisnan (a)
|| eisnan (b))
{
- enan (c);
+ enan (c, 0);
return;
}
#endif
void
-make_nan (nan, mode)
+make_nan (nan, sign, mode)
unsigned EMUSHORT *nan;
+int sign;
enum machine_mode mode;
{
- int i, n;
+ int n;
unsigned EMUSHORT *p;
- n = 0;
switch (mode)
{
/* Possibly the `reserved operand' patterns on a VAX can be
default:
abort ();
}
- for (i=0; i < n; i++)
+#ifdef MIEEE
+ *nan++ = (sign << 15) | *p++;
+#endif
+ while (--n != 0)
*nan++ = *p++;
+#ifndef MIEEE
+ *nan = (sign << 15) | *p;
+#endif
}
/* Convert an SFmode target `float' value to a REAL_VALUE_TYPE.
i = ecmp (x, ezero);
if (i <= 0)
{
-#ifdef NANS
- if (i == -2)
+ if (i == -1)
{
- enan (y);
- return;
+ mtherr ("esqrt", DOMAIN);
+ eclear (y);
}
-#endif
- eclear (y);
- if (i < 0)
- mtherr ("esqrt", DOMAIN);
+ else
+ emov (x, y);
return;
}