math: rewrite rounding functions (ceil, floor, trunc, round, rint)
[musl] / src / internal / longdbl.h
1 #ifndef _LDHACK_H
2 #define _LDHACK_H
3
4 #include <float.h>
5 #include <stdint.h>
6
7 // FIXME: hacks to make freebsd+openbsd long double code happy
8
9 // union and macros for freebsd
10
11 #if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
12
13 union IEEEl2bits {
14         long double e;
15         struct {
16                 uint32_t manl:32;
17                 uint32_t manh:32;
18                 uint32_t exp:15;
19                 uint32_t sign:1;
20                 uint32_t pad:16;
21         } bits;
22         struct {
23                 uint64_t man:64;
24                 uint32_t expsign:16;
25                 uint32_t pad:16;
26         } xbits;
27 };
28
29 #define LDBL_MANL_SIZE 32
30 #define LDBL_MANH_SIZE 32
31 #define LDBL_NBIT (1ull << LDBL_MANH_SIZE-1)
32 #undef LDBL_IMPLICIT_NBIT
33 #define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
34
35 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
36 /*
37 // ld128 float.h
38 //#define LDBL_MAX 1.189731495357231765085759326628007016E+4932L
39 #define LDBL_MAX 0x1.ffffffffffffffffffffffffffffp+16383
40 #define LDBL_MAX_EXP 16384
41 #define LDBL_HAS_INFINITY 1
42 //#define LDBL_MIN 3.362103143112093506262677817321752603E-4932L
43 #define LDBL_MIN 0x1p-16382
44 #define LDBL_HAS_QUIET_NAN 1
45 #define LDBL_HAS_DENORM 1
46 //#define LDBL_EPSILON 1.925929944387235853055977942584927319E-34L
47 #define LDBL_EPSILON 0x1p-112
48 #define LDBL_MANT_DIG 113
49 #define LDBL_MIN_EXP (-16381)
50 #define LDBL_MAX_10_EXP 4932
51 #define LDBL_DENORM_MIN 0x0.0000000000000000000000000001p-16381
52 #define LDBL_MIN_10_EXP (-4931)
53 #define LDBL_DIG 33
54 */
55
56 union IEEEl2bits {
57         long double e;
58         struct {
59                 uint64_t manl:64;
60                 uint64_t manh:48;
61                 uint32_t exp:15;
62                 uint32_t sign:1;
63         } bits;
64         struct {
65                 uint64_t unused0:64;
66                 uint64_t unused1:48;
67                 uint32_t expsign:16;
68         } xbits;
69 };
70
71 #define LDBL_MANL_SIZE 64
72 #define LDBL_MANH_SIZE 48
73 #define LDBL_NBIT (1ull << LDBL_MANH_SIZE)
74 #define LDBL_IMPLICIT_NBIT 1
75 #define mask_nbit_l(u)
76
77 #endif
78
79
80 // macros for openbsd
81
82 #define GET_LDOUBLE_WORDS(se,mh,ml, f) do{ \
83         union IEEEl2bits u; \
84         u.e = (f); \
85         (se) = u.xbits.expsign; \
86         (mh) = u.bits.manh; \
87         (ml) = u.bits.manl; \
88 }while(0)
89
90 #define SET_LDOUBLE_WORDS(f,  se,mh,ml) do{ \
91         union IEEEl2bits u; \
92         u.xbits.expsign = (se); \
93         u.bits.manh = (mh); \
94         u.bits.manl = (ml); \
95         (f) = u.e; \
96 }while(0)
97
98 #define GET_LDOUBLE_EXP(se, f) do{ \
99         union IEEEl2bits u; \
100         u.e = (f); \
101         (se) = u.xbits.expsign; \
102 }while(0)
103
104 #define SET_LDOUBLE_EXP(f, se) do{ \
105         union IEEEl2bits u; \
106         u.e = (f); \
107         u.xbits.expsign = (se); \
108         (f) = u.e; \
109 }while(0)
110
111 #endif