Fix to doprnt.c and moded modff, modf etc
This commit is contained in:
@@ -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")));
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -1,94 +1,78 @@
|
||||
/*
|
||||
* ====================================================
|
||||
* 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 <math.h>
|
||||
|
||||
/* 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;
|
||||
long 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 */
|
||||
|
||||
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;
|
||||
i = (0x000fffff) >> j0;
|
||||
if (((i0 & i) | i1) == 0) { /* x is integral */
|
||||
*iptr = x;
|
||||
GET_HIGH_WORD(high,x);
|
||||
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
|
||||
INSERT_WORDS (x, i0 & 0x80000000, 0);
|
||||
/* return +-0 */
|
||||
return x;
|
||||
} else {
|
||||
INSERT_WORDS(*iptr,i0&(~i),0);
|
||||
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 */
|
||||
} 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 */
|
||||
unsigned long high;
|
||||
i = ((unsigned long) (0xffffffff)) >> (j0 - 20);
|
||||
if ((i1 & i) == 0) { /* x is integral */
|
||||
*iptr = x;
|
||||
GET_HIGH_WORD(high,x);
|
||||
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
|
||||
INSERT_WORDS (x, i0 & 0x80000000, 0);
|
||||
/* return +-0 */
|
||||
return x;
|
||||
} else {
|
||||
INSERT_WORDS(*iptr,i0,i1&(~i));
|
||||
INSERT_WORDS (*iptr, i0, i1 & (~i));
|
||||
return x - *iptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user