diff options
author | Szabolcs Nagy <nsz@port70.net> | 2017-10-21 21:09:02 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2019-04-17 13:04:28 -0400 |
commit | d59e504279abd3f613c2305a65fb16936f7b07f1 (patch) | |
tree | fc20dd19c49ee00a9bf849b37752ea5b2af3cda1 | |
parent | 2d72b58070bc43a727b580a46746e87215a60a33 (diff) | |
download | musl-d59e504279abd3f613c2305a65fb16936f7b07f1.tar.gz |
math: add asuint, asuint64, asfloat and asdouble
Code generation for SET_HIGH_WORD slightly changes, but it only affects
pow, otherwise the generated code is unchanged.
-rw-r--r-- | src/internal/libm.h | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/src/internal/libm.h b/src/internal/libm.h index 6e2d1900..098c7058 100644 --- a/src/internal/libm.h +++ b/src/internal/libm.h @@ -83,73 +83,55 @@ union ldshape { } \ } while(0) +#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i +#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f +#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i +#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f + /* Get two 32 bit ints from a double. */ #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; \ + uint64_t __u = asuint64(d); \ + (hi) = __u >> 32; \ + (lo) = (uint32_t)__u; \ } while (0) /* Get the more significant 32 bit int from a double. */ #define GET_HIGH_WORD(hi,d) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ + (hi) = asuint64(d) >> 32; \ } while (0) /* Get the less significant 32 bit int from a double. */ #define GET_LOW_WORD(lo,d) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (lo) = (uint32_t)__u.i; \ + (lo) = (uint32_t)asuint64(d); \ } while (0) /* Set a double from two 32 bit ints. */ #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; \ + (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \ } while (0) /* Set the more significant 32 bits of a double from an int. */ #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) + INSERT_WORDS(d, hi, (uint32_t)asuint64(d)) /* Set the less significant 32 bits of a double from an int. */ #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) + INSERT_WORDS(d, asuint64(d)>>32, lo) /* Get a 32 bit int from a float. */ #define GET_FLOAT_WORD(w,d) \ do { \ - union {float f; uint32_t i;} __u; \ - __u.f = (d); \ - (w) = __u.i; \ + (w) = asuint(d); \ } while (0) /* Set a float from a 32 bit int. */ #define SET_FLOAT_WORD(d,w) \ do { \ - union {float f; uint32_t i;} __u; \ - __u.i = (w); \ - (d) = __u.f; \ + (d) = asfloat(w); \ } while (0) /* fdlibm kernel functions */ |