tlib9: hide uvlong/double conversions to placate gcc (John Gosset) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 66f6e2b651124387f83b9af17104a79d6d93f67b
 (DIR) parent ada24b4005504a9cc8035987cf5175940ae568a7
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 10 May 2008 13:35:54 -0400
       
       lib9: hide uvlong/double conversions to placate gcc (John Gosset)
       
       Diffstat:
         M src/lib9/fmt/nan64.c                |      57 +++++++++++++++++--------------
       
       1 file changed, 31 insertions(+), 26 deletions(-)
       ---
 (DIR) diff --git a/src/lib9/fmt/nan64.c b/src/lib9/fmt/nan64.c
       t@@ -6,6 +6,7 @@
         */
        
        #include "plan9.h"
       +#include <assert.h>
        #include "fmt.h"
        #include "fmtdef.h"
        
       t@@ -13,31 +14,43 @@ static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
        static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
        static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
        
       +/* gcc sees through the obvious casts. */
       +static uvlong
       +d2u(double d)
       +{
       +        union {
       +                uvlong v;
       +                double d;
       +        } u;
       +        assert(sizeof(u.d) == sizeof(u.v));
       +        u.d = d;
       +        return u.v;
       +}
       +
       +static double
       +u2d(uvlong v)
       +{
       +        union {
       +                uvlong v;
       +                double d;
       +        } u;
       +        assert(sizeof(u.d) == sizeof(u.v));
       +        u.v = v;
       +        return u.d;
       +}
       +
        double
        __NaN(void)
        {
       -        uvlong *p;
       -
       -        /* gcc complains about "return *(double*)&uvnan;" */
       -        p = &uvnan;
       -        return *(double*)p;
       +        return u2d(uvnan);
        }
        
        int
        __isNaN(double d)
        {
       -        /*
       -         * Used to just say x = *(uvlong*)&d,
       -         * but gcc miscompiles that!
       -         */
       -        union {
       -                uvlong i;
       -                double f;
       -        } u;
                uvlong x;
                
       -        u.f = d;
       -        x = u.i;
       +        x = d2u(d);
                /* IEEE 754: exponent bits 0x7FF and non-zero mantissa */
                return (x&uvinf) == uvinf && (x&~uvneginf) != 0;
        }
       t@@ -45,23 +58,15 @@ __isNaN(double d)
        double
        __Inf(int sign)
        {
       -        uvlong *p;
       -
       -        if(sign < 0)
       -                p = &uvinf;
       -        else
       -                p = &uvneginf;
       -        return *(double*)p;
       +        return u2d(sign < 0 ? uvneginf : uvinf);
        }
        
        int
        __isInf(double d, int sign)
        {
                uvlong x;
       -        double *p;
       -
       -        p = &d;
       -        x = *(uvlong*)p;
       +        
       +        x = d2u(d);
                if(sign == 0)
                        return x==uvinf || x==uvneginf;
                else if(sign > 0)