OSDN Git Service

/
[pf3gnuchains/gcc-fork.git] / libquadmath / quadmath-imp.h
1 #ifndef QUADMATH_IMP_H
2 #define QUADMATH_IMP_H
3
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include "quadmath.h"
7
8
9 // Prototypes for internal functions
10 extern int32_t rem_pio2q (__float128, __float128 *);
11 extern void __kernel_sincosq (__float128, __float128, __float128 *, __float128 *, int);
12 extern __float128 __kernel_sinq (__float128, __float128, int);
13 extern __float128 __kernel_cosq (__float128, __float128);
14
15
16
17 // Frankly, if you have __float128, you have 64-bit integers, right?
18 #ifndef UINT64_C
19 # error "No way!"
20 #endif
21
22
23 // If we don't have macros to know endianess, assume little endian
24 #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
25 # define __LITTLE_ENDIAN__ 1
26 #endif
27
28
29 // Main union type we use to manipulate the floating-point type
30 typedef union
31 {
32   __float128 value;
33
34   struct
35   {
36 #if __BIG_ENDIAN__
37     unsigned negative:1;
38     unsigned exponent:15;
39     uint64_t mant_high:48;
40     uint64_t mant_low:64;
41 #endif
42 #if __LITTLE_ENDIAN__
43     uint64_t mant_low:64;
44     uint64_t mant_high:48;
45     unsigned exponent:15;
46     unsigned negative:1;
47 #endif
48   } ieee;
49
50   struct
51   {
52 #if __BIG_ENDIAN__
53     uint64_t high;
54     uint64_t low;
55 #endif
56 #if __LITTLE_ENDIAN__
57     uint64_t low;
58     uint64_t high;
59 #endif
60   } words64;
61
62   struct
63   {
64 #if __BIG_ENDIAN__
65     uint32_t w0;
66     uint32_t w1;
67     uint32_t w2;
68     uint32_t w3;
69 #endif
70 #if __LITTLE_ENDIAN__
71     uint32_t w3;
72     uint32_t w2;
73     uint32_t w1;
74     uint32_t w0;
75 #endif
76   } words32;
77
78   struct
79   {
80 #if __BIG_ENDIAN__
81     unsigned negative:1;
82     unsigned exponent:15;
83     unsigned quiet_nan:1;
84     uint64_t mant_high:47;
85     uint64_t mant_low:64;
86 #endif
87 #if __LITTLE_ENDIAN__
88     uint64_t mant_low:64;
89     uint64_t mant_high:47;
90     unsigned quiet_nan:1;
91     unsigned exponent:15;
92     unsigned negative:1;
93 #endif
94   } nan;
95
96 } ieee854_float128;
97
98
99 /* Get two 64 bit ints from a long double.  */
100 #define GET_FLT128_WORDS64(ix0,ix1,d)  \
101 do {                                   \
102   ieee854_float128 u;                  \
103   u.value = (d);                       \
104   (ix0) = u.words64.high;              \
105   (ix1) = u.words64.low;               \
106 } while (0)
107
108 /* Set a long double from two 64 bit ints.  */
109 #define SET_FLT128_WORDS64(d,ix0,ix1)  \
110 do {                                   \
111   ieee854_float128 u;                  \
112   u.words64.high = (ix0);              \
113   u.words64.low = (ix1);               \
114   (d) = u.value;                       \
115 } while (0)
116
117 /* Get the more significant 64 bits of a long double mantissa.  */
118 #define GET_FLT128_MSW64(v,d)          \
119 do {                                   \
120   ieee854_float128 u;                  \
121   u.value = (d);                       \
122   (v) = u.words64.high;                \
123 } while (0)
124
125 /* Set the more significant 64 bits of a long double mantissa from an int.  */
126 #define SET_FLT128_MSW64(d,v)          \
127 do {                                   \
128   ieee854_float128 u;                  \
129   u.value = (d);                       \
130   u.words64.high = (v);                \
131   (d) = u.value;                       \
132 } while (0)
133
134 /* Get the least significant 64 bits of a long double mantissa.  */
135 #define GET_FLT128_LSW64(v,d)          \
136 do {                                   \
137   ieee854_float128 u;                  \
138   u.value = (d);                       \
139   (v) = u.words64.low;                 \
140 } while (0)
141
142
143 #define IEEE854_FLOAT128_BIAS 0x3fff
144
145
146 #endif