Bladeren bron

math: cosmetic cleanup (use explicit union instead of fshape and dshape)

Szabolcs Nagy 11 jaren geleden
bovenliggende
commit
8dba548628
11 gewijzigde bestanden met toevoegingen van 140 en 166 verwijderingen
  1. 56 66
      src/internal/libm.h
  2. 6 5
      src/math/__fpclassify.c
  3. 6 5
      src/math/__fpclassifyf.c
  4. 4 7
      src/math/copysign.c
  5. 8 9
      src/math/copysignf.c
  6. 5 6
      src/math/fabs.c
  7. 5 6
      src/math/fabsf.c
  8. 13 17
      src/math/nextafter.c
  9. 13 17
      src/math/nextafterf.c
  10. 12 15
      src/math/nexttoward.c
  11. 12 13
      src/math/nexttowardf.c

+ 56 - 66
src/internal/libm.h

@@ -21,16 +21,6 @@
 
 #include "libc.h"
 
-union fshape {
-	float value;
-	uint32_t bits;
-};
-
-union dshape {
-	double value;
-	uint64_t bits;
-};
-
 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
 union ldshape {
@@ -58,86 +48,86 @@ union ldshape {
 #error Unsupported long double representation
 #endif
 
-#define FORCE_EVAL(x) do {                          \
-	if (sizeof(x) == sizeof(float)) {           \
-		volatile float __x;                 \
-		__x = (x);                          \
-	} else if (sizeof(x) == sizeof(double)) {   \
-		volatile double __x;                \
-		__x = (x);                          \
-	} else {                                    \
-		volatile long double __x;           \
-		__x = (x);                          \
-	}                                           \
+#define FORCE_EVAL(x) do {                        \
+	if (sizeof(x) == sizeof(float)) {         \
+		volatile float __x;               \
+		__x = (x);                        \
+	} else if (sizeof(x) == sizeof(double)) { \
+		volatile double __x;              \
+		__x = (x);                        \
+	} else {                                  \
+		volatile long double __x;         \
+		__x = (x);                        \
+	}                                         \
 } while(0)
 
 /* Get two 32 bit ints from a double.  */
-#define EXTRACT_WORDS(hi,lo,d)                                  \
-do {                                                            \
-  union dshape __u;                                             \
-  __u.value = (d);                                              \
-  (hi) = __u.bits >> 32;                                        \
-  (lo) = (uint32_t)__u.bits;                                    \
+#define EXTRACT_WORDS(hi,lo,d)                    \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
+  (lo) = (uint32_t)__u.i;                         \
 } 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 >> 32;                                         \
+#define GET_HIGH_WORD(hi,d)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (hi) = __u.i >> 32;                             \
 } 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) = (uint32_t)__u.bits;                                     \
+#define GET_LOW_WORD(lo,d)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  (lo) = (uint32_t)__u.i;                         \
 } while (0)
 
 /* Set a double from two 32 bit ints.  */
-#define INSERT_WORDS(d,hi,lo)                                   \
-do {                                                            \
-  union dshape __u;                                             \
-  __u.bits = ((uint64_t)(hi) << 32) | (uint32_t)(lo);           \
-  (d) = __u.value;                                              \
+#define INSERT_WORDS(d,hi,lo)                     \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo);  \
+  (d) = __u.f;                                    \
 } 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 &= 0xffffffff;                                       \
-  __u.bits |= (uint64_t)(hi) << 32;                             \
-  (d) = __u.value;                                              \
+#define SET_HIGH_WORD(d,hi)                       \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff;                            \
+  __u.i |= (uint64_t)(hi) << 32;                  \
+  (d) = __u.f;                                    \
 } 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 &= 0xffffffff00000000ull;                            \
-  __u.bits |= (uint32_t)(lo);                                   \
-  (d) = __u.value;                                              \
+#define SET_LOW_WORD(d,lo)                        \
+do {                                              \
+  union {double f; uint64_t i;} __u;              \
+  __u.f = (d);                                    \
+  __u.i &= 0xffffffff00000000ull;                 \
+  __u.i |= (uint32_t)(lo);                        \
+  (d) = __u.f;                                    \
 } while (0)
 
 /* Get a 32 bit int from a float.  */
-#define GET_FLOAT_WORD(i,d)                                     \
-do {                                                            \
-  union fshape __u;                                             \
-  __u.value = (d);                                              \
-  (i) = __u.bits;                                               \
+#define GET_FLOAT_WORD(w,d)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.f = (d);                                    \
+  (w) = __u.i;                                    \
 } 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;                                              \
+#define SET_FLOAT_WORD(d,w)                       \
+do {                                              \
+  union {float f; uint32_t i;} __u;               \
+  __u.i = (w);                                    \
+  (d) = __u.f;                                    \
 } while (0)
 
 /* fdlibm kernel functions */

+ 6 - 5
src/math/__fpclassify.c

@@ -1,10 +1,11 @@
-#include "libm.h"
+#include <math.h>
+#include <stdint.h>
 
 int __fpclassify(double x)
 {
-	union dshape u = { x };
-	int e = u.bits>>52 & 0x7ff;
-	if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
-	if (e==0x7ff) return u.bits<<12 ? FP_NAN : FP_INFINITE;
+	union {double f; uint64_t i;} u = {x};
+	int e = u.i>>52 & 0x7ff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
 	return FP_NORMAL;
 }

+ 6 - 5
src/math/__fpclassifyf.c

@@ -1,10 +1,11 @@
-#include "libm.h"
+#include <math.h>
+#include <stdint.h>
 
 int __fpclassifyf(float x)
 {
-	union fshape u = { x };
-	int e = u.bits>>23 & 0xff;
-	if (!e) return u.bits<<1 ? FP_SUBNORMAL : FP_ZERO;
-	if (e==0xff) return u.bits<<9 ? FP_NAN : FP_INFINITE;
+	union {float f; uint32_t i;} u = {x};
+	int e = u.i>>23 & 0xff;
+	if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
+	if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
 	return FP_NORMAL;
 }

+ 4 - 7
src/math/copysign.c

@@ -1,11 +1,8 @@
 #include "libm.h"
 
 double copysign(double x, double y) {
-	union dshape ux, uy;
-
-	ux.value = x;
-	uy.value = y;
-	ux.bits &= (uint64_t)-1>>1;
-	ux.bits |= uy.bits & (uint64_t)1<<63;
-	return ux.value;
+	union {double f; uint64_t i;} ux={x}, uy={y};
+	ux.i &= -1ULL/2;
+	ux.i |= uy.i & 1ULL<<63;
+	return ux.f;
 }

+ 8 - 9
src/math/copysignf.c

@@ -1,11 +1,10 @@
-#include "libm.h"
+#include <math.h>
+#include <stdint.h>
 
-float copysignf(float x, float y) {
-	union fshape ux, uy;
-
-	ux.value = x;
-	uy.value = y;
-	ux.bits &= (uint32_t)-1>>1;
-	ux.bits |= uy.bits & (uint32_t)1<<31;
-	return ux.value;
+float copysignf(float x, float y)
+{
+	union {float f; uint32_t i;} ux={x}, uy={y};
+	ux.i &= 0x7fffffff;
+	ux.i |= uy.i & 0x80000000;
+	return ux.f;
 }

+ 5 - 6
src/math/fabs.c

@@ -1,10 +1,9 @@
-#include "libm.h"
+#include <math.h>
+#include <stdint.h>
 
 double fabs(double x)
 {
-	union dshape u;
-
-	u.value = x;
-	u.bits &= (uint64_t)-1 / 2;
-	return u.value;
+	union {double f; uint64_t i;} u = {x};
+	u.i &= -1ULL/2;
+	return u.f;
 }

+ 5 - 6
src/math/fabsf.c

@@ -1,10 +1,9 @@
-#include "libm.h"
+#include <math.h>
+#include <stdint.h>
 
 float fabsf(float x)
 {
-	union fshape u;
-
-	u.value = x;
-	u.bits &= (uint32_t)-1 / 2;
-	return u.value;
+	union {float f; uint32_t i;} u = {x};
+	u.i &= 0x7fffffff;
+	return u.f;
 }

+ 13 - 17
src/math/nextafter.c

@@ -1,35 +1,31 @@
 #include "libm.h"
 
-#define SIGN ((uint64_t)1<<63)
-
 double nextafter(double x, double y)
 {
-	union dshape ux, uy;
+	union {double f; uint64_t i;} ux={x}, uy={y};
 	uint64_t ax, ay;
 	int e;
 
 	if (isnan(x) || isnan(y))
 		return x + y;
-	ux.value = x;
-	uy.value = y;
-	if (ux.bits == uy.bits)
+	if (ux.i == uy.i)
 		return y;
-	ax = ux.bits & ~SIGN;
-	ay = uy.bits & ~SIGN;
+	ax = ux.i & -1ULL/2;
+	ay = uy.i & -1ULL/2;
 	if (ax == 0) {
 		if (ay == 0)
 			return y;
-		ux.bits = (uy.bits & SIGN) | 1;
-	} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
-		ux.bits--;
+		ux.i = (uy.i & 1ULL<<63) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
+		ux.i--;
 	else
-		ux.bits++;
-	e = ux.bits >> 52 & 0x7ff;
-	/* raise overflow if ux.value is infinite and x is finite */
+		ux.i++;
+	e = ux.i >> 52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
 	if (e == 0x7ff)
 		FORCE_EVAL(x+x);
-	/* raise underflow if ux.value is subnormal or zero */
+	/* raise underflow if ux.f is subnormal or zero */
 	if (e == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }

+ 13 - 17
src/math/nextafterf.c

@@ -1,34 +1,30 @@
 #include "libm.h"
 
-#define SIGN 0x80000000
-
 float nextafterf(float x, float y)
 {
-	union fshape ux, uy;
+	union {float f; uint32_t i;} ux={x}, uy={y};
 	uint32_t ax, ay, e;
 
 	if (isnan(x) || isnan(y))
 		return x + y;
-	ux.value = x;
-	uy.value = y;
-	if (ux.bits == uy.bits)
+	if (ux.i == uy.i)
 		return y;
-	ax = ux.bits & ~SIGN;
-	ay = uy.bits & ~SIGN;
+	ax = ux.i & 0x7fffffff;
+	ay = uy.i & 0x7fffffff;
 	if (ax == 0) {
 		if (ay == 0)
 			return y;
-		ux.bits = (uy.bits & SIGN) | 1;
-	} else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
-		ux.bits--;
+		ux.i = (uy.i & 0x80000000) | 1;
+	} else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
+		ux.i--;
 	else
-		ux.bits++;
-	e = ux.bits & 0x7f800000;
-	/* raise overflow if ux.value is infinite and x is finite */
+		ux.i++;
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
 	if (e == 0x7f800000)
 		FORCE_EVAL(x+x);
-	/* raise underflow if ux.value is subnormal or zero */
+	/* raise underflow if ux.f is subnormal or zero */
 	if (e == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }

+ 12 - 15
src/math/nexttoward.c

@@ -6,40 +6,37 @@ double nexttoward(double x, long double y)
 	return nextafter(x, y);
 }
 #else
-#define SIGN ((uint64_t)1<<63)
-
 double nexttoward(double x, long double y)
 {
-	union dshape ux;
+	union {double f; uint64_t i;} ux = {x};
 	int e;
 
 	if (isnan(x) || isnan(y))
 		return x + y;
 	if (x == y)
 		return y;
-	ux.value = x;
 	if (x == 0) {
-		ux.bits = 1;
+		ux.i = 1;
 		if (signbit(y))
-			ux.bits |= SIGN;
+			ux.i |= 1ULL<<63;
 	} else if (x < y) {
 		if (signbit(x))
-			ux.bits--;
+			ux.i--;
 		else
-			ux.bits++;
+			ux.i++;
 	} else {
 		if (signbit(x))
-			ux.bits++;
+			ux.i++;
 		else
-			ux.bits--;
+			ux.i--;
 	}
-	e = ux.bits>>52 & 0x7ff;
-	/* raise overflow if ux.value is infinite and x is finite */
+	e = ux.i>>52 & 0x7ff;
+	/* raise overflow if ux.f is infinite and x is finite */
 	if (e == 0x7ff)
 		FORCE_EVAL(x+x);
-	/* raise underflow if ux.value is subnormal or zero */
+	/* raise underflow if ux.f is subnormal or zero */
 	if (e == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }
 #endif

+ 12 - 13
src/math/nexttowardf.c

@@ -2,35 +2,34 @@
 
 float nexttowardf(float x, long double y)
 {
-	union fshape ux;
+	union {float f; uint32_t i;} ux = {x};
 	uint32_t e;
 
 	if (isnan(x) || isnan(y))
 		return x + y;
 	if (x == y)
 		return y;
-	ux.value = x;
 	if (x == 0) {
-		ux.bits = 1;
+		ux.i = 1;
 		if (signbit(y))
-			ux.bits |= 0x80000000;
+			ux.i |= 0x80000000;
 	} else if (x < y) {
 		if (signbit(x))
-			ux.bits--;
+			ux.i--;
 		else
-			ux.bits++;
+			ux.i++;
 	} else {
 		if (signbit(x))
-			ux.bits++;
+			ux.i++;
 		else
-			ux.bits--;
+			ux.i--;
 	}
-	e = ux.bits & 0x7f800000;
-	/* raise overflow if ux.value is infinite and x is finite */
+	e = ux.i & 0x7f800000;
+	/* raise overflow if ux.f is infinite and x is finite */
 	if (e == 0x7f800000)
 		FORCE_EVAL(x+x);
-	/* raise underflow if ux.value is subnormal or zero */
+	/* raise underflow if ux.f is subnormal or zero */
 	if (e == 0)
-		FORCE_EVAL(x*x + ux.value*ux.value);
-	return ux.value;
+		FORCE_EVAL(x*x + ux.f*ux.f);
+	return ux.f;
 }