libm: 6809 now handles double as well as float
authorAlan Cox <alan@linux.intel.com>
Sun, 25 Feb 2018 18:37:09 +0000 (18:37 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 25 Feb 2018 18:37:09 +0000 (18:37 +0000)
Need to write a few small extra helpers to match the inline ones using uint64_t

Library/include/6809/stdint.h
Library/include/math.h
Library/libs/libm.h

index f7667e8..cd86d21 100644 (file)
@@ -16,6 +16,4 @@ typedef uint16_t uintptr_t;
 #define __SIZE_T_DEFINED
 #define NO_64BIT
 
-#define double float
-
 #endif
index 5d25054..3f4fd99 100644 (file)
@@ -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)
index b568408..95fd0ae 100644 (file)
@@ -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);