From patchwork Fri Apr 5 00:25:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thomas Schwinge X-Patchwork-Id: 234008 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id A26792C009E for ; Fri, 5 Apr 2013 11:25:35 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:in-reply-to:references:date:message-id :mime-version:content-type; q=dns; s=default; b=BfJosOsAvvF9Sl1n ceEvDY0mENXZDIrqnaZsLXRplxz5DDeLzBhRuZIiHAkECN75kRWnorV2UbZ2pQIv t4NDMoikC9d4xviaREYQpsocKm+JsoyCzEhgWtPnZRC3k9X/b8nmz97Utco/1lrp dwUVMLzqeefXj838zrtJYwdrLwc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:in-reply-to:references:date:message-id :mime-version:content-type; s=default; bh=qX8U+oZA+oA410Sg7R+BBu TbyFs=; b=MayVVGCnAEQvI405JA3igb+ck1/9eKafijop9kLYC5aVbOaqMoYsk0 DOhyPHn237B6lBfkDkpH3KD9WtPhgbfJI2sYVOBPyhUwkifKmimtmn6IeRwF/1zb CVjkMeqfCdjp37EA+dr8eGEvWzxS69Tiwxac5lc90CeXmvJVNFvl4= Received: (qmail 4955 invoked by alias); 5 Apr 2013 00:25:25 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4943 invoked by uid 89); 5 Apr 2013 00:25:25 -0000 X-Spam-SWARE-Status: No, score=-7.7 required=5.0 tests=AWL, BAYES_00, KHOP_PGP_SIGNED, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, TW_BF autolearn=ham version=3.3.1 Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 05 Apr 2013 00:25:21 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1UNuT0-0000AQ-RC from Thomas_Schwinge@mentor.com ; Thu, 04 Apr 2013 17:25:18 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Thu, 4 Apr 2013 17:25:18 -0700 Received: from feldtkeller.schwinge.homeip.net (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Fri, 5 Apr 2013 01:25:16 +0100 From: Thomas Schwinge To: Alexandre Oliva , Richard Henderson CC: , , , , Subject: Re: mips SNaN/QNaN is swapped In-Reply-To: References: <20030327012642.GA29837@redhat.com> <20030327093138.GC16558@redhat.com> <20030401053433.GA25974@redhat.com> <20030401174232.GC26336@redhat.com> <20030401183318.GA26416@redhat.com> User-Agent: Notmuch/0.9-101-g81dad07 (http://notmuchmail.org) Emacs/23.4.1 (i486-pc-linux-gnu) Date: Fri, 5 Apr 2013 02:25:06 +0200 Message-ID: <878v4xn7rx.fsf@kepler.schwinge.homeip.net> MIME-Version: 1.0 X-Virus-Found: No Hi! Re-visiting this patch/commit after a mere ten years, ha, ha. :-) Surely everyone must still be having context on this issue... (MIPS and soft-fp maintainers CCed.) On 01 Apr 2003 18:44:53 -0300, Alexandre Oliva wrote: > Index: gcc/ChangeLog > from Alexandre Oliva > > * 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. > (real_identical): Disregard significand in canonical > NaNs. > (real_hash): Likewise. Take signalling into account. > (encode_ieee_single, encode_ieee_double, encode_ieee_quad): > Disregard significand bits in canonical NaNs. 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. > * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Use mips_extended_format. > * config/mips/linux64.h (MIPS_TFMODE_FORMAT): Use mips_quad_format. > * config/mips/mips.c (override_options): Use mips_single_format > and mips_double_format. Default TFmode to mips_quad_format. > * config/mips/t-linux64 (tp-bit.c): Define QUIET_NAN_NEGATED. > * config/mips/t-irix6: Likewise. > * config/mips/t-mips (fp-bit.c, dp-bit.c): Likewise. > * config/fp-bit.c (pack_d, unpack_d): Obey it. These days still, MIPS remains the only architecture to define QUIET_NAN_NEGATED (though, HPPA would seem to be another one to do, as Carlos recently confirmed), meaning that the topmost bit of the fraction, indicating qNaN or sNaN, has to be interpreted the other way round than for most other architectures (and as now defined in IEEE 754-2008). For a -m64 MIPS configuration (to enable the 128-bit floating-point datatype, long double), we get, with the following test program: #include extern int __issignalingf(float x); extern int __issignaling(double x); extern int __issignalingl(long double x); typedef union { long double f; int i[4]; } u_ld; typedef union { double f; int i[2]; } u_d; typedef union { float f; int i[1]; } u_f; int main(void) { volatile u_f f; f.f = __builtin_nanf(""); printf("%x\n", f.i[0]); if (__issignalingf(f.f)) printf(" sNaN\n"); volatile u_d d; d.f = __builtin_nan(""); printf("%x %x\n", d.i[0], d.i[1]); if (__issignaling(d.f)) printf(" sNaN\n"); d.f = f.f; printf("%x %x\n", d.i[0], d.i[1]); if (__issignaling(d.f)) printf(" sNaN\n"); d.f = __builtin_nanf(""); printf("%x %x\n", d.i[0], d.i[1]); if (__issignaling(d.f)) printf(" sNaN\n"); volatile u_ld ld; ld.f = __builtin_nanl(""); printf("%x %x %x %x\n", ld.i[0], ld.i[1], ld.i[2], ld.i[3]); if (__issignalingl(ld.f)) printf(" sNaN\n"); ld.f = d.f; printf("%x %x %x %x\n", ld.i[0], ld.i[1], ld.i[2], ld.i[3]); if (__issignalingl(ld.f)) printf(" sNaN\n"); ld.f = __builtin_nan(""); printf("%x %x %x %x\n", ld.i[0], ld.i[1], ld.i[2], ld.i[3]); if (__issignalingl(ld.f)) printf(" sNaN\n"); ld.f = f.f; printf("%x %x %x %x\n", ld.i[0], ld.i[1], ld.i[2], ld.i[3]); if (__issignalingl(ld.f)) printf(" sNaN\n"); ld.f = __builtin_nanf(""); printf("%x %x %x %x\n", ld.i[0], ld.i[1], ld.i[2], ld.i[3]); if (__issignalingl(ld.f)) printf(" sNaN\n"); return 0; } (The __issignaling* functions are those I recently implemented in glibc commit 572676160d5639edc0ecb663147bd291841458d1; you can leave these out and instead interpret the bit patterns.) 7fbfffff 7ff7ffff ffffffff 7ff7ffff e0000000 7ff7ffff ffffffff 7fff7fff ffffffff ffffffff ffffffff 7fffffff ffffffff ffffffff ffffffff sNaN 7fff7fff ffffffff ffffffff ffffffff 7fffffff ffffffff ffffffff ffffffff sNaN 7fff7fff ffffffff ffffffff ffffffff That is, for the cases where a float or double variable that contains a qNaN value is assigned to a long double variable (that is, »ld.f = d.f;« and »ld.f = f.f;«), the qNaN is unexpectedly turned into a sNaN during the type conversion. As I understand it (and I may add that this is the first time ever I'm looking at soft-fp internals), that appears to be a bug in soft-fp, in this very code added ten years ago ;-), which is invoked by means of _df_to_tf.o:__extenddftf2 for this conversion operation. (Forgive my ignorance of MIPS ISA floating-point details, and not looking it up myself at this late time of day -- why use soft-fp for that; isn't there anything in hardware available to do it?) > Index: gcc/config/fp-bit.c > =================================================================== > RCS file: /cvs/uberbaum/gcc/config/fp-bit.c,v > retrieving revision 1.39 > diff -u -p -r1.39 fp-bit.c > --- gcc/config/fp-bit.c 26 Jan 2003 10:06:57 -0000 1.39 > +++ gcc/config/fp-bit.c 1 Apr 2003 21:35:00 -0000 > @@ -210,7 +210,11 @@ pack_d ( fp_number_type * src) > exp = EXPMAX; > if (src->class == CLASS_QNAN || 1) > { > +#ifdef QUIET_NAN_NEGATED > + fraction |= QUIET_NAN - 1; > +#else > fraction |= QUIET_NAN; > +#endif > } > } > else if (isinf (src)) > @@ -521,7 +525,11 @@ unpack_d (FLO_union_type * src, fp_numbe > else > { > /* Nonzero fraction, means nan */ > +#ifdef QUIET_NAN_NEGATED > + if ((fraction & QUIET_NAN) == 0) > +#else > if (fraction & QUIET_NAN) > +#endif > { > dst->class = CLASS_QNAN; > } With the fix applied, we get the expected result: 7fbfffff 7ff7ffff ffffffff 7ff7ffff e0000000 7ff7ffff ffffffff 7fff7fff ffffffff ffffffff ffffffff 7fff7fff ffffffff ffffffff ffffffff 7fff7fff ffffffff ffffffff ffffffff 7fff7fff ffffffff ffffffff ffffffff 7fff7fff ffffffff ffffffff ffffffff Automated testing is still running; in case nothing turns up, does this look OK to check in? Grüße, Thomas Index: libgcc/fp-bit.c =================================================================== --- libgcc/fp-bit.c (revision 402061) +++ libgcc/fp-bit.c (working copy) @@ -217,6 +217,9 @@ pack_d (const fp_number_type *src) if (src->class == CLASS_QNAN || 1) { #ifdef QUIET_NAN_NEGATED + /* Mask out the quiet/signaling bit. */ + fraction &= ~QUIET_NAN; + /* Set the remainder of the fraction to a non-zero value. */ fraction |= QUIET_NAN - 1; #else fraction |= QUIET_NAN;