This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: mips SNaN/QNaN is swapped
- From: Richard Henderson <rth at redhat dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: cgd at broadcom dot com, gcc-patches at gcc dot gnu dot org
- Date: Mon, 31 Mar 2003 21:34:33 -0800
- Subject: Re: mips SNaN/QNaN is swapped
- References: <orr88we85f.fsf@free.redhat.lsd.ic.unicamp.br> <orisu8e2f3.fsf@free.redhat.lsd.ic.unicamp.br> <20030325034356.GE15567@redhat.com> <orsmtbaido.fsf@free.redhat.lsd.ic.unicamp.br> <20030327012642.GA29837@redhat.com> <orn0jhfpyh.fsf@free.redhat.lsd.ic.unicamp.br> <20030327093138.GC16558@redhat.com> <mailpost.1048757677.18699@news-sj1-1> <yov5r88sbvvu.fsf@broadcom.com> <or4r5iq4ze.fsf@free.redhat.lsd.ic.unicamp.br>
On Tue, Apr 01, 2003 at 12:19:33AM -0300, Alexandre Oliva wrote:
> * real.h (EXP_BITS): Make room for...
> (struct real_value): ... added canonical bit.
> (struct real_format): Added pnan.
> (mips_single_format, mips_double_format, mips_extended_format,
> mips_quad_format): New.
> * real.c: Copy p to pnan in all formats.
> (get_canonical_qnan, get_canonical_snan): Set canonical bit.
> (real_nan): Use pnan to compute significand's shift.
> (encode_ieee_single, encode_ieee_double, encode_ieee_quad):
> Set all bits of canonical nan if !qnan_msb_set.
> (encode_ibm_extended, decode_ibm_extended): Likewise. Use
> qnan_msb_set to tell the base double format.
> (ibm_extended_format): Use 53 as pnan.
> (mips_single_format, mips_double_format, mips_extended_format,
> mips_quad_format): Copied from the corresponding ieee/ibm
> formats, with qnan_msb_set false.
Almost ok.
You've missed the needed change to real_identical. In this case,
if canonical, you should ignore the significand. This implies a
needed change to real_hash as well.
> + /* We overload qnan_msb_set here: it's only clear for
> + mips_ieee_single, which wants all mantissa bits but the
> + quiet/signalling one set in canonical NaNs (at least
> + Quiet ones). */
> + if (r->canonical && !fmt->qnan_msb_set)
> + sig |= (1 << 22) - 1;
> + else if (sig == 0)
> sig = 1 << 21;
And further implies that canonical should ignore the existing value
of sig. I.e. something like
if (r->canonical)
sig = (fmt->qnan_msb_set ? (1 << 22) - 1 : 1 << 21);
else if (sig == 0)
sig = 1 << 21;
r~