Fixes with aliasing
This commit is contained in:
@@ -36,7 +36,7 @@ STDOBJ = abort.o alarm.o atof.o atoi.o atol.o calloc.o closedir.o crypt.o \
|
|||||||
getpass.o getpwent.o getloadavg.o getmntinfo.o \
|
getpass.o getpwent.o getloadavg.o getmntinfo.o \
|
||||||
getttyent.o getttynam.o getusershell.o getwd.o \
|
getttyent.o getttynam.o getusershell.o getwd.o \
|
||||||
initgroups.o isatty.o isinff.o isnanf.o ldexp.o malloc.o mktemp.o \
|
initgroups.o isatty.o isinff.o isnanf.o ldexp.o malloc.o mktemp.o \
|
||||||
modff.o modf.c ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \
|
modff.o modf.o ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \
|
||||||
psignal.o qsort.o random.o readdir.o regex.o scandir.o \
|
psignal.o qsort.o random.o readdir.o regex.o scandir.o \
|
||||||
seekdir.o setmode.o sethostname.o setenv.o siglist.o \
|
seekdir.o setmode.o sethostname.o setenv.o siglist.o \
|
||||||
signal.o siginterrupt.o sigsetops.o \
|
signal.o siginterrupt.o sigsetops.o \
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ int isinff (float x)
|
|||||||
/*
|
/*
|
||||||
* For PIC32, double is the same as float.
|
* For PIC32, double is the same as float.
|
||||||
*/
|
*/
|
||||||
int isinf (double x) __attribute__((alias ("isinff")));
|
//int isinf (double x) __attribute__((alias ("isinff")));
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ int isnanf (float x)
|
|||||||
/*
|
/*
|
||||||
* For PIC32, double is the same as float.
|
* For PIC32, double is the same as float.
|
||||||
*/
|
*/
|
||||||
int isnan (double x) __attribute__((alias ("isnanf")));
|
//int isnan (double x) __attribute__((alias ("isnanf")));
|
||||||
|
|||||||
@@ -8,12 +8,20 @@
|
|||||||
*/
|
*/
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
// IM: dereferencing type-punned pointer will break strict-aliasing rules
|
||||||
|
// TODO check Endiannes
|
||||||
|
union {
|
||||||
|
double d64;
|
||||||
|
struct { long i32h;
|
||||||
|
long i32l;
|
||||||
|
};
|
||||||
|
} ew;
|
||||||
|
|
||||||
/* Get two 32 bit ints from a double. */
|
/* Get two 32 bit ints from a double. */
|
||||||
|
|
||||||
#define EXTRACT_WORDS(high,low,d) \
|
//#define EXTRACT_WORDS(high,low,d)
|
||||||
high = *(unsigned long long*) &d; \
|
// high = *(unsigned long long*) &d;
|
||||||
low = (*(unsigned long long*) &d) >> 32
|
// low = (*(unsigned long long*) &d) >> 32
|
||||||
|
|
||||||
|
|
||||||
/* Set a double from two 32 bit ints. */
|
/* Set a double from two 32 bit ints. */
|
||||||
|
|
||||||
@@ -36,22 +44,30 @@ double modf (double x, double *iptr)
|
|||||||
long i0, i1, j0;
|
long i0, i1, j0;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
EXTRACT_WORDS (i0, i1, x);
|
//EXTRACT_WORDS (i0, i1, x);
|
||||||
|
ew.d64 = x; i0 = ew.i32h; i1 = ew.i32l;
|
||||||
|
//
|
||||||
j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */
|
j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */
|
||||||
if (j0 < 20) { /* integer part in high x */
|
if (j0 < 20) { /* integer part in high x */
|
||||||
if (j0 < 0) { /* |x|<1 */
|
if (j0 < 0) { /* |x|<1 */
|
||||||
INSERT_WORDS (*iptr, i0 & 0x80000000, 0);
|
//INSERT_WORDS (*iptr, i0 & 0x80000000, 0);
|
||||||
|
ew.i32h = i0 & 0x80000000; ew.i32l = 0; *iptr = ew.d64;
|
||||||
|
//
|
||||||
/* *iptr = +-0 */
|
/* *iptr = +-0 */
|
||||||
return x;
|
return x;
|
||||||
} else {
|
} else {
|
||||||
i = (0x000fffff) >> j0;
|
i = (0x000fffff) >> j0;
|
||||||
if (((i0 & i) | i1) == 0) { /* x is integral */
|
if (((i0 & i) | i1) == 0) { /* x is integral */
|
||||||
*iptr = x;
|
*iptr = x;
|
||||||
INSERT_WORDS (x, i0 & 0x80000000, 0);
|
//INSERT_WORDS (x, i0 & 0x80000000, 0);
|
||||||
|
ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64;
|
||||||
|
//
|
||||||
/* return +-0 */
|
/* return +-0 */
|
||||||
return x;
|
return x;
|
||||||
} else {
|
} else {
|
||||||
INSERT_WORDS (*iptr, i0 & (~i), 0);
|
//INSERT_WORDS (*iptr, i0 & (~i), 0);
|
||||||
|
ew.i32h = i0 & (~i); ew.i32l = 0; *iptr = ew.d64;
|
||||||
|
//
|
||||||
return x - *iptr;
|
return x - *iptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,18 +77,24 @@ double modf (double x, double *iptr)
|
|||||||
if (j0 == 0x400 && ((i0 & 0xfffff) | i1))
|
if (j0 == 0x400 && ((i0 & 0xfffff) | i1))
|
||||||
return x * one;
|
return x * one;
|
||||||
|
|
||||||
INSERT_WORDS (x, i0 & 0x80000000, 0);
|
//INSERT_WORDS (x, i0 & 0x80000000, 0);
|
||||||
|
ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64;
|
||||||
|
//
|
||||||
/* return +-0 */
|
/* return +-0 */
|
||||||
return x;
|
return x;
|
||||||
} else { /* fraction part in low x */
|
} else { /* fraction part in low x */
|
||||||
i = ((unsigned long) (0xffffffff)) >> (j0 - 20);
|
i = ((unsigned long) (0xffffffff)) >> (j0 - 20);
|
||||||
if ((i1 & i) == 0) { /* x is integral */
|
if ((i1 & i) == 0) { /* x is integral */
|
||||||
*iptr = x;
|
*iptr = x;
|
||||||
INSERT_WORDS (x, i0 & 0x80000000, 0);
|
//INSERT_WORDS (x, i0 & 0x80000000, 0);
|
||||||
|
ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64;
|
||||||
|
//
|
||||||
/* return +-0 */
|
/* return +-0 */
|
||||||
return x;
|
return x;
|
||||||
} else {
|
} else {
|
||||||
INSERT_WORDS (*iptr, i0, i1 & (~i));
|
//INSERT_WORDS (*iptr, i0, i1 & (~i));
|
||||||
|
ew.i32h = i0; ew.i32l = i1 & (~i); *iptr = ew.d64;
|
||||||
|
//
|
||||||
return x - *iptr;
|
return x - *iptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,4 +52,4 @@ float modff (float fx, float *iptr)
|
|||||||
/*
|
/*
|
||||||
* For PIC32, double is the same as float.
|
* 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")));
|
||||||
|
|||||||
Reference in New Issue
Block a user