From: Alan Cox Date: Sun, 25 Feb 2018 18:37:09 +0000 (+0000) Subject: libm: 6809 now handles double as well as float X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=75c2deb606b23d600d06a247e8aa38073791030d;p=FUZIX.git libm: 6809 now handles double as well as float Need to write a few small extra helpers to match the inline ones using uint64_t --- diff --git a/Library/include/6809/stdint.h b/Library/include/6809/stdint.h index f7667e8b..cd86d211 100644 --- a/Library/include/6809/stdint.h +++ b/Library/include/6809/stdint.h @@ -16,6 +16,4 @@ typedef uint16_t uintptr_t; #define __SIZE_T_DEFINED #define NO_64BIT -#define double float - #endif diff --git a/Library/include/math.h b/Library/include/math.h index 5d250546..3f4fd99b 100644 --- a/Library/include/math.h +++ b/Library/include/math.h @@ -75,6 +75,7 @@ extern int __signbit(double); sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \ __fpclassify(x)) +#ifndef NO_64BIT #define isinf(x) ( \ sizeof(x) == sizeof(float) ? (__float_bits(x) & 0x7fffffff) == 0x7f800000 : \ (__double_bits(x) & (__uint64_t)-1>>1) == (__uint64_t)0x7ff<<52) @@ -97,6 +98,37 @@ extern int __signbit(double); #else +extern int __isinf(double x); +extern int __isnan(double x); +extern int __isnormal(double x); +extern int __isfinite(double x); +extern int __signbit(double x); + +#define isinf(x) ( \ + sizeof(x) == sizeof(float) ? (__float_bits(x) & 0x7fffffff) == 0x7f800000 : \ + __isinf(x)) + +#define isnan(x) ( \ + sizeof(x) == sizeof(float) ? (__float_bits(x) & 0x7fffffff) > 0x7f800000 : \ + __isnan(x)) + +#define isnormal(x) ( \ + sizeof(x) == sizeof(float) ? ((__float_bits(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \ + __isnormal(x)) + +#define isfinite(x) ( \ + sizeof(x) == sizeof(float) ? (__float_bits(x) & 0x7fffffff) < 0x7f800000 : \ + __isfinite(x)) + +#define signbit(x) ( \ + sizeof(x) == sizeof(float) ? (int)(__float_bits(x)>>31) : \ + __signbit(x)) + + +#endif + +#else + /* We have double defined as float .. so fix up the support routines */ #define acos(a) acosf(a) #define asin(a) asinf(a) diff --git a/Library/libs/libm.h b/Library/libs/libm.h index b5684080..95fd0ae3 100644 --- a/Library/libs/libm.h +++ b/Library/libs/libm.h @@ -26,6 +26,7 @@ union fshape { /* Check platform actually has a real double type */ #ifndef double +#ifndef NO_64BIT union dshape { double value; uint64_t bits; @@ -100,7 +101,88 @@ do { \ (d) = __u.value; \ } while (0) -#endif +#else /* NO_64BIT */ + +/* Get a 32 bit int from a float. */ +union dshape { + double value; + uint32_t bits[2]; +}; + +/* FIXME: double check the logic here */ +#define LOBIT 0 +#define HIBIT 1 + +/* Get two 32 bit ints from a double. */ +#define EXTRACT_WORDS(hi,lo,d) \ +do { \ + union dshape __u; \ + __u.value = (d); \ + (hi) = __u.bits[HIBIT]; \ + (lo) = __u.bits[LOBIT]; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ +#define GET_HIGH_WORD(i,d) \ +do { \ + union dshape __u; \ + __u.value = (d); \ + (i) = __u.bits[HIBIT]; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ +#define GET_LOW_WORD(i,d) \ +do { \ + union dshape __u; \ + __u.value = (d); \ + (i) = __u.bits[LOBIT]; \ +} while (0) + +/* Set a double from two 32 bit ints. */ +#define INSERT_WORDS(d,hi,lo) \ +do { \ + union dshape __u; \ + __u.bits[HIBIT] = hi; \ + __u.bits[LOBIT] = lo; \ + (d) = __u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ +#define SET_HIGH_WORD(d,hi) \ +do { \ + union dshape __u; \ + __u.value = (d); \ + __u.bits[HIBIT] = hi; \ + (d) = __u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ +#define SET_LOW_WORD(d,lo) \ +do { \ + union dshape __u; \ + __u.value = (d); \ + __u.bits[LOBIT] = lo; \ + (d) = __u.value; \ +} while (0) + +#endif /* NO_64BIT */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + union fshape __u; \ + __u.value = (d); \ + (i) = __u.bits; \ +} while (0) + +/* Set a float from a 32 bit int. */ +#define SET_FLOAT_WORD(d,i) \ +do { \ + union fshape __u; \ + __u.bits = (i); \ + (d) = __u.value; \ +} while (0) + +#else /* double */ /* Get a 32 bit int from a float. */ #define GET_FLOAT_WORD(i,d) \ @@ -118,6 +200,8 @@ do { \ (d) = __u.value; \ } while (0) +#endif + /* fdlibm kernel functions */ int __rem_pio2_large(double*,double*,int,int,int);