diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 0ad88eb..1755a65 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -11,30 +11,20 @@ * isinff(x) returns 1 is x is inf, -1 if x is -inf, else 0; * no branching! */ -typedef union { - float x; - struct { - long lxx; - }; -} ival; - -//int isinff (float x) -//{ -// long lx = *(long*) &x; -// long v = (lx & 0x7fffffff) ^ 0x7f800000; -// return ~((v | -v) >> 31) & (lx >> 30); -//} - -int isinff (float xx) +int isinff (float x) { - ival temp; - temp.x = xx; - long lx = temp.lxx; - long v = (lx & 0x7fffffff) ^ 0x7f800000; - return ~((v | -v) >> 31) & (lx >> 30); + union { + long s32; + float f32; + } u; + long v; + + u.f32 = x; + v = (u.s32 & 0x7fffffff) ^ 0x7f800000; + return ~((v | -v) >> 31) & (u.s32 >> 30); } /* * For PIC32, double is the same as float. */ -//int isinf (double x) __attribute__((alias ("isinff"))); +int isinf (double x) __attribute__((alias ("isinff"))); diff --git a/src/libc/gen/isnanf.c b/src/libc/gen/isnanf.c index 2b298fe..dda3938 100644 --- a/src/libc/gen/isnanf.c +++ b/src/libc/gen/isnanf.c @@ -11,31 +11,20 @@ * isnan(x) returns 1 is x is nan, else 0; * no branching! */ +int isnanf (float x) +{ + union { + long s32; + float f32; + } u; + unsigned long ul; -typedef union { - float x; - struct { - long lxx; - }; -} ival; - -//int isnanf (float x) -//{ -// long lx = *(long*) &x; -// lx = 0x7f800000 - (lx & 0x7fffffff); -// return (int) (((unsigned long) lx) >> 31); -//} -int isnanf (float xx) { - ival temp; - temp.x = xx; - long lx = temp.lxx; - lx = 0x7f800000 - (lx & 0x7fffffff); - return (int) (((unsigned long) lx) >> 31); + u.f32 = x; + ul = 0x7f800000 - (u.s32 & 0x7fffffff); + return ul >> 31; } - - /* * For PIC32, double is the same as float. */ -//int isnan (double x) __attribute__((alias ("isnanf"))); +int isnan (double x) __attribute__((alias ("isnanf"))); diff --git a/src/libc/gen/modf.c b/src/libc/gen/modf.c index f226091..a331a26 100644 --- a/src/libc/gen/modf.c +++ b/src/libc/gen/modf.c @@ -1,95 +1,79 @@ /* - * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. - * ==================================================== */ -// *** modified by Pito 11/2013 for RetroBSD *** - -typedef union // LITTLE ENDIAN -{ - double value; - struct - { - unsigned long lsw; - unsigned long msw; - } parts; -} ieee_double_shape_type; +#include /* Get two 32 bit ints from a double. */ -#define EXTRACT_WORDS(ix0,ix1,d) \ -do { \ - ieee_double_shape_type ew_u; \ - ew_u.value = (d); \ - (ix0) = ew_u.parts.msw; \ - (ix1) = ew_u.parts.lsw; \ -} while (0) +#define EXTRACT_WORDS(high,low,d) \ + high = *(unsigned long long*) &d; \ + low = (*(unsigned long long*) &d) >> 32 -/* Get the more significant 32 bit int from a double. */ - -#define GET_HIGH_WORD(i,d) \ -do { \ - ieee_double_shape_type gh_u; \ - gh_u.value = (d); \ - (i) = gh_u.parts.msw; \ -} while (0) /* Set a double from two 32 bit ints. */ -#define INSERT_WORDS(d,ix0,ix1) \ -do { \ - ieee_double_shape_type iw_u; \ - iw_u.parts.msw = (ix0); \ - iw_u.parts.lsw = (ix1); \ - (d) = iw_u.value; \ -} while (0) +#define INSERT_WORDS(d,high,low) \ + *(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low) -double modf(double x, double *iptr) +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ +static const double one = 1.0; + +double modf (double x, double *iptr) { - long int i0,i1,j0; - unsigned long i; - double one = 1.0; - EXTRACT_WORDS(i0,i1,x); - j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ - if(j0<20) { /* integer part in high x */ - if(j0<0) { /* |x|<1 */ - INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ - return x; - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) { /* x is integral */ - unsigned long high; - *iptr = x; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0&(~i),0); - return x - *iptr; - } - } - } else if (j0>51) { /* no fraction part */ - unsigned long high; - *iptr = x*one; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { /* fraction part in low x */ - i = ((unsigned long)(0xffffffff))>>(j0-20); - if((i1&i)==0) { /* x is integral */ - unsigned long high; - *iptr = x; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0,i1&(~i)); - return x - *iptr; - } - } + long i0, i1, j0; + unsigned long i; + + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) { /* integer part in high x */ + if (j0 < 0) { /* |x|<1 */ + INSERT_WORDS (*iptr, i0 & 0x80000000, 0); + /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { + INSERT_WORDS (*iptr, i0 & (~i), 0); + return x - *iptr; + } + } + } else if (j0 > 51) { /* no fraction part */ + *iptr = x * one; + /* We must handle NaNs separately. */ + if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) + return x * one; + + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((unsigned long) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { + INSERT_WORDS (*iptr, i0, i1 & (~i)); + return x - *iptr; + } + } } diff --git a/src/libc/gen/modff.c b/src/libc/gen/modff.c index 4e099da..7eeac60 100644 --- a/src/libc/gen/modff.c +++ b/src/libc/gen/modff.c @@ -13,35 +13,43 @@ */ static const float one = 1.0; -float modff (float x, float *iptr) +float modff (float fx, float *iptr) { - unsigned hx = *(unsigned*) &x & ~0x80000000; - unsigned s; + union { + unsigned u32; + float f32; + } x; + unsigned hx, s; + x.f32 = fx; + hx = x.u32 & ~0x80000000; if (hx >= 0x4b000000) { /* x is NaN, infinite, or integral */ - *iptr = x; + *iptr = x.f32; if (hx <= 0x7f800000) - *(unsigned*) &x &= 0x80000000; - return x; + x.u32 &= 0x80000000; + return x.f32; } if (hx < 0x3f800000) { /* |x| < 1 */ - *iptr = x; - *(unsigned*) iptr &= 0x80000000; - return x; + float ret = x.f32; + x.u32 &= 0x80000000; + *iptr = x.f32; + return ret; } /* split x at the binary point */ - s = *(unsigned*) &x & 0x80000000; - *(unsigned*) iptr = *(unsigned*) &x & ~((1 << (0x96 - (hx >> 23))) - 1); - x -= *iptr; + s = x.u32 & 0x80000000; + fx = x.f32; + x.u32 &= ~((1 << (0x96 - (hx >> 23))) - 1); + *iptr = x.f32; + x.f32 = fx - *iptr; /* restore sign in case difference is 0 */ - *(unsigned*) &x = (*(unsigned*) &x & ~0x80000000) | s; - return x; + x.u32 = (x.u32 & ~0x80000000) | s; + return x.f32; } /* * For PIC32, double is the same as float. */ -//double modf (double x, double *iptr) __attribute__((alias ("modff"))); +double modf (double x, double *iptr) __attribute__((alias ("modff"))); diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index 9d3c7c3..78b7751 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -367,7 +367,7 @@ number: if (sign && ((long) ul != 0L)) { double d; unsigned long *l = (unsigned long *) &d; - if (*(unsigned long*)&ap & 4) { + if (*(unsigned long*)&ap & 4L) { l[0]= va_arg(ap, unsigned long); l[1]= va_arg(ap, unsigned long); }