]>
Commit | Line | Data |
---|---|---|
545a5cb6 TB |
1 | /* GCC Quad-Precision Math Library |
2 | Copyright (C) 2010 Free Software Foundation, Inc. | |
3 | Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | |
4 | ||
5 | This file is part of the libiberty library. | |
6 | Libiberty is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Library General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2 of the License, or (at your option) any later version. | |
10 | ||
11 | Libiberty is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Library General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Library General Public | |
17 | License along with libiberty; see the file COPYING.LIB. If | |
18 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, | |
19 | Boston, MA 02110-1301, USA. */ | |
20 | ||
1ec601bf FXC |
21 | #ifndef QUADMATH_IMP_H |
22 | #define QUADMATH_IMP_H | |
23 | ||
24 | #include <stdint.h> | |
25 | #include <stdlib.h> | |
26 | #include "quadmath.h" | |
27 | ||
28 | ||
29 | // Prototypes for internal functions | |
f0c2df63 TB |
30 | extern int32_t __quadmath_rem_pio2q (__float128, __float128 *); |
31 | extern void __quadmath_kernel_sincosq (__float128, __float128, __float128 *, | |
32 | __float128 *, int); | |
33 | extern __float128 __quadmath_kernel_sinq (__float128, __float128, int); | |
34 | extern __float128 __quadmath_kernel_cosq (__float128, __float128); | |
1ec601bf FXC |
35 | |
36 | ||
37 | ||
38 | // Frankly, if you have __float128, you have 64-bit integers, right? | |
39 | #ifndef UINT64_C | |
40 | # error "No way!" | |
41 | #endif | |
42 | ||
43 | ||
44 | // If we don't have macros to know endianess, assume little endian | |
45 | #if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) | |
46 | # define __LITTLE_ENDIAN__ 1 | |
47 | #endif | |
48 | ||
49 | ||
50 | // Main union type we use to manipulate the floating-point type | |
51 | typedef union | |
52 | { | |
53 | __float128 value; | |
54 | ||
55 | struct | |
56 | { | |
57 | #if __BIG_ENDIAN__ | |
58 | unsigned negative:1; | |
59 | unsigned exponent:15; | |
60 | uint64_t mant_high:48; | |
61 | uint64_t mant_low:64; | |
62 | #endif | |
63 | #if __LITTLE_ENDIAN__ | |
64 | uint64_t mant_low:64; | |
65 | uint64_t mant_high:48; | |
66 | unsigned exponent:15; | |
67 | unsigned negative:1; | |
68 | #endif | |
69 | } ieee; | |
70 | ||
71 | struct | |
72 | { | |
73 | #if __BIG_ENDIAN__ | |
74 | uint64_t high; | |
75 | uint64_t low; | |
76 | #endif | |
77 | #if __LITTLE_ENDIAN__ | |
78 | uint64_t low; | |
79 | uint64_t high; | |
80 | #endif | |
81 | } words64; | |
82 | ||
83 | struct | |
84 | { | |
85 | #if __BIG_ENDIAN__ | |
86 | uint32_t w0; | |
87 | uint32_t w1; | |
88 | uint32_t w2; | |
89 | uint32_t w3; | |
90 | #endif | |
91 | #if __LITTLE_ENDIAN__ | |
92 | uint32_t w3; | |
93 | uint32_t w2; | |
94 | uint32_t w1; | |
95 | uint32_t w0; | |
96 | #endif | |
97 | } words32; | |
98 | ||
99 | struct | |
100 | { | |
101 | #if __BIG_ENDIAN__ | |
102 | unsigned negative:1; | |
103 | unsigned exponent:15; | |
104 | unsigned quiet_nan:1; | |
105 | uint64_t mant_high:47; | |
106 | uint64_t mant_low:64; | |
107 | #endif | |
108 | #if __LITTLE_ENDIAN__ | |
109 | uint64_t mant_low:64; | |
110 | uint64_t mant_high:47; | |
111 | unsigned quiet_nan:1; | |
112 | unsigned exponent:15; | |
113 | unsigned negative:1; | |
114 | #endif | |
115 | } nan; | |
116 | ||
117 | } ieee854_float128; | |
118 | ||
119 | ||
120 | /* Get two 64 bit ints from a long double. */ | |
121 | #define GET_FLT128_WORDS64(ix0,ix1,d) \ | |
122 | do { \ | |
123 | ieee854_float128 u; \ | |
124 | u.value = (d); \ | |
125 | (ix0) = u.words64.high; \ | |
126 | (ix1) = u.words64.low; \ | |
127 | } while (0) | |
128 | ||
129 | /* Set a long double from two 64 bit ints. */ | |
130 | #define SET_FLT128_WORDS64(d,ix0,ix1) \ | |
131 | do { \ | |
132 | ieee854_float128 u; \ | |
133 | u.words64.high = (ix0); \ | |
134 | u.words64.low = (ix1); \ | |
135 | (d) = u.value; \ | |
136 | } while (0) | |
137 | ||
138 | /* Get the more significant 64 bits of a long double mantissa. */ | |
139 | #define GET_FLT128_MSW64(v,d) \ | |
140 | do { \ | |
141 | ieee854_float128 u; \ | |
142 | u.value = (d); \ | |
143 | (v) = u.words64.high; \ | |
144 | } while (0) | |
145 | ||
146 | /* Set the more significant 64 bits of a long double mantissa from an int. */ | |
147 | #define SET_FLT128_MSW64(d,v) \ | |
148 | do { \ | |
149 | ieee854_float128 u; \ | |
150 | u.value = (d); \ | |
151 | u.words64.high = (v); \ | |
152 | (d) = u.value; \ | |
153 | } while (0) | |
154 | ||
155 | /* Get the least significant 64 bits of a long double mantissa. */ | |
156 | #define GET_FLT128_LSW64(v,d) \ | |
157 | do { \ | |
158 | ieee854_float128 u; \ | |
159 | u.value = (d); \ | |
160 | (v) = u.words64.low; \ | |
161 | } while (0) | |
162 | ||
163 | ||
164 | #define IEEE854_FLOAT128_BIAS 0x3fff | |
165 | ||
166 | ||
167 | #endif |