X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Finternal%2Flibm.h;h=a2505f7ece62ba2cc494201f234c457c7b37ed4b;hb=056f9d818eaf1dbe9e9d63b64b109fd9b608fa36;hp=a71c4c05ab092b77bfd2c24e8a6eaab569745bea;hpb=6ab8136b4477fd75381c06fa0e7fa93c89c712a1;p=musl diff --git a/src/internal/libm.h b/src/internal/libm.h index a71c4c05..a2505f7e 100644 --- a/src/internal/libm.h +++ b/src/internal/libm.h @@ -17,119 +17,154 @@ #include #include #include - -#include "longdbl.h" - -#include "libc.h" - -union fshape { - float value; - uint32_t bits; +#include + +#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 +#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN +union ldshape { + long double f; + struct { + uint64_t m; + uint16_t se; + } i; }; - -union dshape { - double value; - uint64_t bits; +#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN +/* This is the m68k variant of 80-bit long double, and this definition only works + * on archs where the alignment requirement of uint64_t is <= 4. */ +union ldshape { + long double f; + struct { + uint16_t se; + uint16_t pad; + uint64_t m; + } i; }; +#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN +union ldshape { + long double f; + struct { + uint64_t lo; + uint32_t mid; + uint16_t top; + uint16_t se; + } i; + struct { + uint64_t lo; + uint64_t hi; + } i2; +}; +#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN +union ldshape { + long double f; + struct { + uint16_t se; + uint16_t top; + uint32_t mid; + uint64_t lo; + } i; + struct { + uint64_t hi; + uint64_t lo; + } i2; +}; +#else +#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; \ -} while (0) - -/* Get a 64 bit int from a double. */ -#define EXTRACT_WORD64(i,d) \ -do { \ - union dshape __u; \ - __u.value = (d); \ - (i) = __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; \ -} while (0) - -/* Set a double from a 64 bit int. */ -#define INSERT_WORD64(d,i) \ -do { \ - union dshape __u; \ - __u.bits = (i); \ - (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) +#undef __CMPLX +#undef CMPLX +#undef CMPLXF +#undef CMPLXL + +#define __CMPLX(x, y, t) \ + ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) + +#define CMPLX(x, y) __CMPLX(x, y, double) +#define CMPLXF(x, y) __CMPLX(x, y, float) +#define CMPLXL(x, y) __CMPLX(x, y, long double) + /* fdlibm kernel functions */ int __rem_pio2_large(double*,double*,int,int,int); @@ -157,38 +192,4 @@ long double __tanl(long double, long double, int); long double __polevll(long double, const long double *, int); long double __p1evll(long double, const long double *, int); -// FIXME: not needed when -fexcess-precision=standard is supported (>=gcc4.5) -/* - * Attempt to get strict C99 semantics for assignment with non-C99 compilers. - */ -#if 1 -#define STRICT_ASSIGN(type, lval, rval) do { \ - volatile type __v = (rval); \ - (lval) = __v; \ -} while (0) -#else -#define STRICT_ASSIGN(type, lval, rval) ((lval) = (type)(rval)) -#endif - - -/* complex */ - -union dcomplex { - double complex z; - double a[2]; -}; -union fcomplex { - float complex z; - float a[2]; -}; -union lcomplex { - long double complex z; - long double a[2]; -}; - -/* x + y*I is not supported properly by gcc */ -#define cpack(x,y) ((union dcomplex){.a={(x),(y)}}.z) -#define cpackf(x,y) ((union fcomplex){.a={(x),(y)}}.z) -#define cpackl(x,y) ((union lcomplex){.a={(x),(y)}}.z) - #endif