Both of these requirements are easily satisfied. The largest target
significand is 113 bits; we store at least 160. The smallest
- denormal number fits in 17 exponent bits; we store 29.
+ denormal number fits in 17 exponent bits; we store 27.
Note that the decimal string conversion routines are sensitive to
rounding errors. Since the raw arithmetic routines do not themselves
get_canonical_qnan (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->canonical = 1;
}
get_canonical_snan (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->signalling = 1;
r->canonical = 1;
get_inf (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
- r->class = rvc_inf;
+ r->cl = rvc_inf;
r->sign = sign;
}
/* Zero significand flushes to zero. */
if (i < 0)
{
- r->class = rvc_zero;
+ r->cl = rvc_zero;
SET_REAL_EXP (r, 0);
return;
}
sign = a->sign;
subtract_p = (sign ^ b->sign) ^ subtract_p;
- switch (CLASS2 (a->class, b->class))
+ switch (CLASS2 (a->cl, b->cl))
{
case CLASS2 (rvc_zero, rvc_zero):
/* -0 + -0 = -0, -0 - +0 = -0; all other cases yield +0. */
break;
default:
- abort ();
+ gcc_unreachable ();
}
/* Swap the arguments such that A has the larger exponent. */
}
}
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp);
/* Special case: if the subtraction results in zero, the result
is positive. */
- if (r->class == rvc_zero)
+ if (r->cl == rvc_zero)
r->sign = 0;
else
r->sig[0] |= inexact;
int sign = a->sign ^ b->sign;
bool inexact = false;
- switch (CLASS2 (a->class, b->class))
+ switch (CLASS2 (a->cl, b->cl))
{
case CLASS2 (rvc_zero, rvc_zero):
case CLASS2 (rvc_zero, rvc_normal):
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (r == a || r == b)
}
memset (&u, 0, sizeof (u));
- u.class = rvc_normal;
+ u.cl = rvc_normal;
SET_REAL_EXP (&u, exp);
for (k = j; k < SIGSZ * 2; k += 2)
REAL_VALUE_TYPE t, *rr;
bool inexact;
- switch (CLASS2 (a->class, b->class))
+ switch (CLASS2 (a->cl, b->cl))
{
case CLASS2 (rvc_zero, rvc_zero):
/* 0 / 0 = NaN. */
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (r == a || r == b)
/* Make sure all fields in the result are initialized. */
get_zero (rr, 0);
- rr->class = rvc_normal;
+ rr->cl = rvc_normal;
rr->sign = sign;
exp = REAL_EXP (a) - REAL_EXP (b) + 1;
{
int ret;
- switch (CLASS2 (a->class, b->class))
+ switch (CLASS2 (a->cl, b->cl))
{
case CLASS2 (rvc_zero, rvc_zero):
/* Sign of zero doesn't matter for compares. */
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (a->sign != b->sign)
{
*r = *a;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
case rvc_inf:
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
break;
case MIN_EXPR:
- if (op1->class == rvc_nan)
+ if (op1->cl == rvc_nan)
*r = *op1;
else if (do_compare (op0, op1, -1) < 0)
*r = *op0;
break;
case MAX_EXPR:
- if (op1->class == rvc_nan)
+ if (op1->cl == rvc_nan)
*r = *op1;
else if (do_compare (op0, op1, 1) < 0)
*r = *op1;
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
case NE_EXPR:
return do_compare (op0, op1, -1) != 0;
case UNORDERED_EXPR:
- return op0->class == rvc_nan || op1->class == rvc_nan;
+ return op0->cl == rvc_nan || op1->cl == rvc_nan;
case ORDERED_EXPR:
- return op0->class != rvc_nan && op1->class != rvc_nan;
+ return op0->cl != rvc_nan && op1->cl != rvc_nan;
case UNLT_EXPR:
return do_compare (op0, op1, -1) < 0;
case UNLE_EXPR:
return do_compare (op0, op1, 0) != 0;
default:
- abort ();
+ gcc_unreachable ();
}
}
int
real_exponent (const REAL_VALUE_TYPE *r)
{
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
return 0;
case rvc_normal:
return REAL_EXP (r);
default:
- abort ();
+ gcc_unreachable ();
}
}
real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
{
*r = *op0;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
case rvc_inf:
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
bool
real_isinf (const REAL_VALUE_TYPE *r)
{
- return (r->class == rvc_inf);
+ return (r->cl == rvc_inf);
}
/* Determine whether a floating-point value X is a NaN. */
bool
real_isnan (const REAL_VALUE_TYPE *r)
{
- return (r->class == rvc_nan);
+ return (r->cl == rvc_nan);
}
/* Determine whether a floating-point value X is negative. */
bool
real_isnegzero (const REAL_VALUE_TYPE *r)
{
- return r->sign && r->class == rvc_zero;
+ return r->sign && r->cl == rvc_zero;
}
/* Compare two floating-point objects for bitwise identity. */
{
int i;
- if (a->class != b->class)
+ if (a->cl != b->cl)
return false;
if (a->sign != b->sign)
return false;
- switch (a->class)
+ switch (a->cl)
{
case rvc_zero:
case rvc_inf:
break;
default:
- abort ();
+ gcc_unreachable ();
}
for (i = 0; i < SIGSZ; ++i)
REAL_VALUE_TYPE u;
int i;
- if (r->class != rvc_normal)
+ if (r->cl != rvc_normal)
return false;
/* Check for a power of two: all significand bits zero except the MSB. */
real_convert (&u, mode, &u);
/* The rounding may have overflowed. */
- if (u.class != rvc_normal)
+ if (u.cl != rvc_normal)
return false;
for (i = 0; i < SIGSZ-1; ++i)
if (u.sig[i] != 0)
{
unsigned HOST_WIDE_INT i;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
underflow:
if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
i = r->sig[SIGSZ-1];
- else if (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG)
+ else
{
+ gcc_assert (HOST_BITS_PER_WIDE_INT == 2 * HOST_BITS_PER_LONG);
i = r->sig[SIGSZ-1];
i = i << (HOST_BITS_PER_LONG - 1) << 1;
i |= r->sig[SIGSZ-2];
}
- else
- abort ();
i >>= HOST_BITS_PER_WIDE_INT - REAL_EXP (r);
return i;
default:
- abort ();
+ gcc_unreachable ();
}
}
HOST_WIDE_INT low, high;
int exp;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
underflow:
high = t.sig[SIGSZ-1];
low = t.sig[SIGSZ-2];
}
- else if (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG)
+ else
{
+ gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
high = t.sig[SIGSZ-1];
high = high << (HOST_BITS_PER_LONG - 1) << 1;
high |= t.sig[SIGSZ-2];
low = low << (HOST_BITS_PER_LONG - 1) << 1;
low |= t.sig[SIGSZ-4];
}
- else
- abort ();
if (r->sign)
{
break;
default:
- abort ();
+ gcc_unreachable ();
}
*plow = low;
bool sign;
r = *r_orig;
- switch (r.class)
+ switch (r.cl)
{
case rvc_zero:
strcpy (str, (r.sign ? "-0.0" : "0.0"));
strcpy (str, (r.sign ? "-NaN" : "+NaN"));
return;
default:
- abort ();
+ gcc_unreachable ();
}
/* Bound the number of digits printed by the size of the representation. */
/* Bound the number of digits printed by the size of the output buffer. */
max_digits = buf_size - 1 - 1 - 2 - max_digits - 1;
- if (max_digits > buf_size)
- abort ();
+ gcc_assert (max_digits <= buf_size);
if (digits > max_digits)
digits = max_digits;
do_multiply (&r, &r, ten);
digit = rtd_divmod (&r, &pten);
dec_exp -= 1;
- if (digit == 0)
- abort ();
+ gcc_assert (digit != 0);
}
/* ... or overflow. */
*p++ = '0';
dec_exp += 1;
}
- else if (digit > 10)
- abort ();
else
- *p++ = digit + '0';
+ {
+ gcc_assert (digit <= 10);
+ *p++ = digit + '0';
+ }
/* Generate subsequent digits. */
while (--digits > 0)
char exp_buf[16];
size_t max_digits;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
exp = 0;
strcpy (str, (r->sign ? "-NaN" : "+NaN"));
return;
default:
- abort ();
+ gcc_unreachable ();
}
if (digits == 0)
sprintf (exp_buf, "p%+d", exp);
max_digits = buf_size - strlen (exp_buf) - r->sign - 4 - 1;
- if (max_digits > buf_size)
- abort ();
+ gcc_assert (max_digits <= buf_size);
if (digits > max_digits)
digits = max_digits;
exp += d;
}
- r->class = rvc_normal;
+ r->cl = rvc_normal;
SET_REAL_EXP (r, exp);
normalize (r);
if (*str == '.')
{
str++;
- if (r->class == rvc_zero)
+ if (r->cl == rvc_zero)
{
while (*str == '0')
str++, exp--;
get_zero (r, 0);
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = high < 0 && !unsigned_p;
SET_REAL_EXP (r, 2 * HOST_BITS_PER_WIDE_INT);
r->sig[SIGSZ-2] = low;
memset (r->sig, 0, sizeof(long)*(SIGSZ-2));
}
- else if (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT)
+ else
{
+ gcc_assert (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT);
r->sig[SIGSZ-1] = high >> (HOST_BITS_PER_LONG - 1) >> 1;
r->sig[SIGSZ-2] = high;
r->sig[SIGSZ-3] = low >> (HOST_BITS_PER_LONG - 1) >> 1;
if (SIGSZ > 4)
memset (r->sig, 0, sizeof(long)*(SIGSZ-4));
}
- else
- abort ();
normalize (r);
}
{
static REAL_VALUE_TYPE tens[EXP_BITS];
- if (n < 0 || n >= EXP_BITS)
- abort ();
+ gcc_assert (n >= 0);
+ gcc_assert (n < EXP_BITS);
- if (tens[n].class == rvc_zero)
+ if (tens[n].cl == rvc_zero)
{
if (n < (HOST_BITS_PER_WIDE_INT == 64 ? 5 : 4))
{
{
static REAL_VALUE_TYPE tens[EXP_BITS];
- if (n < 0 || n >= EXP_BITS)
- abort ();
+ gcc_assert (n >= 0);
+ gcc_assert (n < EXP_BITS);
- if (tens[n].class == rvc_zero)
+ if (tens[n].cl == rvc_zero)
do_divide (&tens[n], real_digit (1), ten_to_ptwo (n));
return &tens[n];
{
static REAL_VALUE_TYPE num[10];
- if (n < 0 || n > 9)
- abort ();
+ gcc_assert (n >= 0);
+ gcc_assert (n <= 9);
- if (n > 0 && num[n].class == rvc_zero)
+ if (n > 0 && num[n].cl == rvc_zero)
real_from_integer (&num[n], VOIDmode, n, 0, 1);
return &num[n];
const struct real_format *fmt;
fmt = REAL_MODE_FORMAT (mode);
- if (fmt == NULL)
- abort ();
+ gcc_assert (fmt);
if (*str == 0)
{
bool neg = false;
memset (r, 0, sizeof (*r));
- r->class = rvc_nan;
+ r->cl = rvc_nan;
/* Parse akin to strtol into the significand of R. */
add_significands (r, r, &u);
break;
default:
- abort ();
+ gcc_unreachable ();
}
get_zero (&u, 0);
int np2;
fmt = REAL_MODE_FORMAT (mode);
- if (fmt == NULL)
- abort ();
+ gcc_assert (fmt);
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
r->signalling = 0;
r->canonical = 0;
n++;
if (n > MAX_EXP)
- r->class = rvc_inf;
+ r->cl = rvc_inf;
else if (n < -MAX_EXP)
;
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
SET_REAL_EXP (r, n);
r->sig[SIGSZ-1] = SIG_MSB;
}
emax2 = fmt->emax * fmt->log2_b;
np2 = SIGNIFICAND_BITS - p2;
- switch (r->class)
+ switch (r->cl)
{
underflow:
get_zero (r, r->sign);
break;
default:
- abort ();
+ gcc_unreachable ();
}
/* If we're not base2, normalize the exponent to a multiple of
const struct real_format *fmt;
fmt = REAL_MODE_FORMAT (mode);
- if (fmt == NULL)
- abort ();
+ gcc_assert (fmt);
*r = *a;
round_for_format (fmt, r);
/* round_for_format de-normalizes denormals. Undo just that part. */
- if (r->class == rvc_normal)
+ if (r->cl == rvc_normal)
normalize (r);
}
const struct real_format *fmt;
fmt = REAL_MODE_FORMAT (mode);
- if (fmt == NULL)
- abort ();
+ gcc_assert (fmt);
return real_to_target_fmt (buf, r, fmt);
}
const struct real_format *fmt;
fmt = REAL_MODE_FORMAT (mode);
- if (fmt == NULL)
- abort ();
+ gcc_assert (fmt);
(*fmt->decode) (fmt, r, buf);
}
unsigned int h;
size_t i;
- h = r->class | (r->sign << 2);
- switch (r->class)
+ h = r->cl | (r->sign << 2);
+ switch (r->cl)
{
case rvc_zero:
case rvc_inf:
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (sizeof(unsigned long) > sizeof(unsigned int))
image = sign << 31;
sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 24)) & 0x7fffff;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
break;
break;
default:
- abort ();
+ gcc_unreachable ();
}
buf[0] = image;
{
if (image && fmt->has_denorm)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, -126);
r->sig[SIGSZ-1] = image << 1;
{
if (image)
{
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
^ fmt->qnan_msb_set);
}
else
{
- r->class = rvc_inf;
+ r->cl = rvc_inf;
r->sign = sign;
}
}
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp - 127 + 1);
r->sig[SIGSZ-1] = image | SIG_MSB;
sig_hi = (sig_hi >> 11) & 0xfffff;
}
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
break;
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (FLOAT_WORDS_BIG_ENDIAN)
{
if ((image_hi || image_lo) && fmt->has_denorm)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, -1022);
if (HOST_BITS_PER_LONG == 32)
{
if (image_hi || image_lo)
{
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set;
if (HOST_BITS_PER_LONG == 32)
}
else
{
- r->class = rvc_inf;
+ r->cl = rvc_inf;
r->sign = sign;
}
}
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp - 1023 + 1);
if (HOST_BITS_PER_LONG == 32)
};
\f
-/* IEEE extended double precision format. This comes in three
- flavors: Intel's as a 12 byte image, Intel's as a 16 byte image,
- and Motorola's. */
-
-static void encode_ieee_extended (const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *);
-static void decode_ieee_extended (const struct real_format *,
- REAL_VALUE_TYPE *, const long *);
-
-static void encode_ieee_extended_128 (const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *);
-static void decode_ieee_extended_128 (const struct real_format *,
- REAL_VALUE_TYPE *, const long *);
-
+/* IEEE extended real format. This comes in three flavors: Intel's as
+ a 12 byte image, Intel's as a 16 byte image, and Motorola's. Intel
+ 12- and 16-byte images may be big- or little endian; Motorola's is
+ always big endian. */
+
+/* Helper subroutine which converts from the internal format to the
+ 12-byte little-endian Intel format. Functions below adjust this
+ for the other possible formats. */
static void
encode_ieee_extended (const struct real_format *fmt, long *buf,
const REAL_VALUE_TYPE *r)
image_hi = r->sign << 15;
sig_hi = sig_lo = 0;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
break;
else
{
exp += 16383 - 1;
- if (exp < 0)
- abort ();
+ gcc_assert (exp >= 0);
}
image_hi |= exp;
break;
default:
- abort ();
+ gcc_unreachable ();
}
+ buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+}
+
+/* Convert from the internal format to the 12-byte Motorola format
+ for an IEEE extended real. */
+static void
+encode_ieee_extended_motorola (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
+{
+ long intermed[3];
+ encode_ieee_extended (fmt, intermed, r);
+
+ /* Motorola chips are assumed always to be big-endian. Also, the
+ padding in a Motorola extended real goes between the exponent and
+ the mantissa. At this point the mantissa is entirely within
+ elements 0 and 1 of intermed, and the exponent entirely within
+ element 2, so all we have to do is swap the order around, and
+ shift element 2 left 16 bits. */
+ buf[0] = intermed[2] << 16;
+ buf[1] = intermed[1];
+ buf[2] = intermed[0];
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+ an IEEE extended real. */
+static void
+encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
+{
if (FLOAT_WORDS_BIG_ENDIAN)
- buf[0] = image_hi << 16, buf[1] = sig_hi, buf[2] = sig_lo;
+ {
+ /* All the padding in an Intel-format extended real goes at the high
+ end, which in this case is after the mantissa, not the exponent.
+ Therefore we must shift everything down 16 bits. */
+ long intermed[3];
+ encode_ieee_extended (fmt, intermed, r);
+ buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16));
+ buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16));
+ buf[2] = (intermed[0] << 16);
+ }
else
- buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+ /* encode_ieee_extended produces what we want directly. */
+ encode_ieee_extended (fmt, buf, r);
}
+/* Convert from the internal format to the 16-byte Intel format for
+ an IEEE extended real. */
static void
-encode_ieee_extended_128 (const struct real_format *fmt, long *buf,
- const REAL_VALUE_TYPE *r)
+encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
- buf[3 * !FLOAT_WORDS_BIG_ENDIAN] = 0;
- encode_ieee_extended (fmt, buf+!!FLOAT_WORDS_BIG_ENDIAN, r);
+ /* All the padding in an Intel-format extended real goes at the high end. */
+ encode_ieee_extended_intel_96 (fmt, buf, r);
+ buf[3] = 0;
}
+/* As above, we have a helper function which converts from 12-byte
+ little-endian Intel format to internal format. Functions below
+ adjust for the other possible formats. */
static void
decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
const long *buf)
bool sign;
int exp;
- if (FLOAT_WORDS_BIG_ENDIAN)
- image_hi = buf[0] >> 16, sig_hi = buf[1], sig_lo = buf[2];
- else
- sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
+ sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
sig_lo &= 0xffffffff;
sig_hi &= 0xffffffff;
image_hi &= 0xffffffff;
{
if ((sig_hi || sig_lo) && fmt->has_denorm)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
/* When the IEEE format contains a hidden bit, we know that
if (sig_hi || sig_lo)
{
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set;
if (HOST_BITS_PER_LONG == 32)
}
else
{
- r->class = rvc_inf;
+ r->cl = rvc_inf;
r->sign = sign;
}
}
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp - 16383 + 1);
if (HOST_BITS_PER_LONG == 32)
}
}
+/* Convert from the internal format to the 12-byte Motorola format
+ for an IEEE extended real. */
+static void
+decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
+{
+ long intermed[3];
+
+ /* Motorola chips are assumed always to be big-endian. Also, the
+ padding in a Motorola extended real goes between the exponent and
+ the mantissa; remove it. */
+ intermed[0] = buf[2];
+ intermed[1] = buf[1];
+ intermed[2] = (unsigned long)buf[0] >> 16;
+
+ decode_ieee_extended (fmt, r, intermed);
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+ an IEEE extended real. */
+static void
+decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
+{
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ {
+ /* All the padding in an Intel-format extended real goes at the high
+ end, which in this case is after the mantissa, not the exponent.
+ Therefore we must shift everything up 16 bits. */
+ long intermed[3];
+
+ intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16));
+ intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16));
+ intermed[2] = ((unsigned long)buf[0] >> 16);
+
+ decode_ieee_extended (fmt, r, intermed);
+ }
+ else
+ /* decode_ieee_extended produces what we want directly. */
+ decode_ieee_extended (fmt, r, buf);
+}
+
+/* Convert from the internal format to the 16-byte Intel format for
+ an IEEE extended real. */
static void
-decode_ieee_extended_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
- const long *buf)
+decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
- decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN);
+ /* All the padding in an Intel-format extended real goes at the high end. */
+ decode_ieee_extended_intel_96 (fmt, r, buf);
}
const struct real_format ieee_extended_motorola_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_motorola,
+ decode_ieee_extended_motorola,
2,
1,
64,
const struct real_format ieee_extended_intel_96_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_intel_96,
+ decode_ieee_extended_intel_96,
2,
1,
64,
const struct real_format ieee_extended_intel_128_format =
{
- encode_ieee_extended_128,
- decode_ieee_extended_128,
+ encode_ieee_extended_intel_128,
+ decode_ieee_extended_intel_128,
2,
1,
64,
to 53 bits instead of 64, e.g. FreeBSD. */
const struct real_format ieee_extended_intel_96_round_53_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_intel_96,
+ decode_ieee_extended_intel_96,
2,
1,
53,
/* Renormlize R before doing any arithmetic on it. */
normr = *r;
- if (normr.class == rvc_normal)
+ if (normr.cl == rvc_normal)
normalize (&normr);
/* u = IEEE double precision portion of significand. */
round_for_format (base_fmt, &u);
encode_ieee_double (base_fmt, &buf[0], &u);
- if (u.class == rvc_normal)
+ if (u.cl == rvc_normal)
{
do_add (&v, &normr, &u, 1);
/* Call round_for_format since we might need to denormalize. */
base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
decode_ieee_double (base_fmt, &u, &buf[0]);
- if (u.class != rvc_zero && u.class != rvc_inf && u.class != rvc_nan)
+ if (u.cl != rvc_zero && u.cl != rvc_inf && u.cl != rvc_nan)
{
decode_ieee_double (base_fmt, &v, &buf[2]);
do_add (r, &u, &v, 0);
rshift_significand (&u, r, SIGNIFICAND_BITS - 113);
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
break;
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (FLOAT_WORDS_BIG_ENDIAN)
{
if ((image3 | image2 | image1 | image0) && fmt->has_denorm)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, -16382 + (SIGNIFICAND_BITS - 112));
{
if (image3 | image2 | image1 | image0)
{
- r->class = rvc_nan;
+ r->cl = rvc_nan;
r->sign = sign;
r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set;
}
else
{
- r->class = rvc_inf;
+ r->cl = rvc_inf;
r->sign = sign;
}
}
else
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, exp - 16383 + 1);
sign = r->sign << 15;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
image = 0;
break;
default:
- abort ();
+ gcc_unreachable ();
}
buf[0] = image;
if (exp != 0)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = (image >> 15) & 1;
SET_REAL_EXP (r, exp - 128);
{
unsigned long image0, image1, sign = r->sign << 15;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
image0 = image1 = 0;
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (FLOAT_WORDS_BIG_ENDIAN)
if (exp != 0)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = (image0 >> 15) & 1;
SET_REAL_EXP (r, exp - 128);
{
unsigned long image0, image1, sign = r->sign << 15;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
image0 = image1 = 0;
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (FLOAT_WORDS_BIG_ENDIAN)
if (exp != 0)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = (image0 >> 15) & 1;
SET_REAL_EXP (r, exp - 1024);
sign = r->sign << 31;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
image = 0;
break;
default:
- abort ();
+ gcc_unreachable ();
}
buf[0] = image;
if (exp || sig)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, (exp - 64) * 4);
r->sig[SIGSZ-1] = sig << (HOST_BITS_PER_LONG - 24);
sign = r->sign << 31;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
image_hi = image_lo = 0;
break;
default:
- abort ();
+ gcc_unreachable ();
}
if (FLOAT_WORDS_BIG_ENDIAN)
if (exp || image_hi || image_lo)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
r->sign = sign;
SET_REAL_EXP (r, (exp - 64) * 4 + (SIGNIFICAND_BITS - 56));
{
unsigned long image, exp, sig;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
exp = -128;
break;
default:
- abort ();
+ gcc_unreachable ();
}
image = ((exp & 0xff) << 24) | (sig & 0xffffff);
if (exp != -128)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
sig = sf & 0x7fffff;
if (sf < 0)
{
unsigned long exp, sig;
- switch (r->class)
+ switch (r->cl)
{
case rvc_zero:
exp = -128;
break;
default:
- abort ();
+ gcc_unreachable ();
}
exp = (exp & 0xff) << 24;
if (exp != -128)
{
- r->class = rvc_normal;
+ r->cl = rvc_normal;
sig = sf & 0x7fffffff;
if (sf < 0)