diff options
Diffstat (limited to 'gcc/real.c')
-rw-r--r-- | gcc/real.c | 60 |
1 files changed, 15 insertions, 45 deletions
@@ -3235,53 +3235,23 @@ encode_ibm_extended (const struct real_format *fmt, long *buf, base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format; - switch (r->class) - { - case rvc_zero: - /* Both doubles have sign bit set. */ - buf[0] = FLOAT_WORDS_BIG_ENDIAN ? r->sign << 31 : 0; - buf[1] = FLOAT_WORDS_BIG_ENDIAN ? 0 : r->sign << 31; - buf[2] = buf[0]; - buf[3] = buf[1]; - break; - - case rvc_inf: - case rvc_nan: - /* Both doubles set to Inf / NaN. */ - encode_ieee_double (base_fmt, &buf[0], r); - buf[2] = buf[0]; - buf[3] = buf[1]; - return; + /* u = IEEE double precision portion of significand. */ + u = *r; + round_for_format (base_fmt, &u); + encode_ieee_double (base_fmt, &buf[0], &u); - case rvc_normal: - /* u = IEEE double precision portion of significand. */ - u = *r; - clear_significand_below (&u, SIGNIFICAND_BITS - 53); - - normalize (&u); - /* If the upper double is zero, we have a denormal double, so - move it to the first double and leave the second as zero. */ - if (u.class == rvc_zero) - { - v = u; - u = *r; - normalize (&u); - } - else - { - /* v = remainder containing additional 53 bits of significand. */ - do_add (&v, r, &u, 1); - round_for_format (base_fmt, &v); - } - - round_for_format (base_fmt, &u); - - encode_ieee_double (base_fmt, &buf[0], &u); + if (r->class == rvc_normal) + { + do_add (&v, r, &u, 1); + round_for_format (base_fmt, &v); encode_ieee_double (base_fmt, &buf[2], &v); - break; - - default: - abort (); + } + else + { + /* Inf, NaN, 0 are all representable as doubles, so the + least-significant part can be 0.0. */ + buf[2] = 0; + buf[3] = 0; } } |