0
|
1 /* Software floating-point emulation.
|
|
2 Definitions for IEEE Double Precision
|
|
3 Copyright (C) 1997, 1998, 1999, 2006, 2007, 2008, 2009
|
|
4 Free Software Foundation, Inc.
|
|
5 This file is part of the GNU C Library.
|
|
6 Contributed by Richard Henderson (rth@cygnus.com),
|
|
7 Jakub Jelinek (jj@ultra.linux.cz),
|
|
8 David S. Miller (davem@redhat.com) and
|
|
9 Peter Maydell (pmaydell@chiark.greenend.org.uk).
|
|
10
|
|
11 The GNU C Library is free software; you can redistribute it and/or
|
|
12 modify it under the terms of the GNU Lesser General Public
|
|
13 License as published by the Free Software Foundation; either
|
|
14 version 2.1 of the License, or (at your option) any later version.
|
|
15
|
|
16 In addition to the permissions in the GNU Lesser General Public
|
|
17 License, the Free Software Foundation gives you unlimited
|
|
18 permission to link the compiled version of this file into
|
|
19 combinations with other programs, and to distribute those
|
|
20 combinations without any restriction coming from the use of this
|
|
21 file. (The Lesser General Public License restrictions do apply in
|
|
22 other respects; for example, they cover modification of the file,
|
|
23 and distribution when not linked into a combine executable.)
|
|
24
|
|
25 The GNU C Library is distributed in the hope that it will be useful,
|
|
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
28 Lesser General Public License for more details.
|
|
29
|
|
30 You should have received a copy of the GNU Lesser General Public
|
|
31 License along with the GNU C Library; if not, write to the Free
|
|
32 Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
|
|
33 MA 02110-1301, USA. */
|
|
34
|
|
35 #if _FP_W_TYPE_SIZE < 32
|
|
36 #error "Here's a nickel kid. Go buy yourself a real computer."
|
|
37 #endif
|
|
38
|
|
39 #if _FP_W_TYPE_SIZE < 64
|
|
40 #define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE)
|
|
41 #else
|
|
42 #define _FP_FRACTBITS_D _FP_W_TYPE_SIZE
|
|
43 #endif
|
|
44
|
|
45 #define _FP_FRACBITS_D 53
|
|
46 #define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D)
|
|
47 #define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D)
|
|
48 #define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
|
|
49 #define _FP_EXPBITS_D 11
|
|
50 #define _FP_EXPBIAS_D 1023
|
|
51 #define _FP_EXPMAX_D 2047
|
|
52
|
|
53 #define _FP_QNANBIT_D \
|
|
54 ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
|
|
55 #define _FP_QNANBIT_SH_D \
|
|
56 ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
|
|
57 #define _FP_IMPLBIT_D \
|
|
58 ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
|
|
59 #define _FP_IMPLBIT_SH_D \
|
|
60 ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
|
|
61 #define _FP_OVERFLOW_D \
|
|
62 ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
|
|
63
|
|
64 typedef float DFtype __attribute__((mode(DF)));
|
|
65
|
|
66 #if _FP_W_TYPE_SIZE < 64
|
|
67
|
|
68 union _FP_UNION_D
|
|
69 {
|
|
70 DFtype flt;
|
|
71 struct {
|
|
72 #if __BYTE_ORDER == __BIG_ENDIAN
|
|
73 unsigned sign : 1;
|
|
74 unsigned exp : _FP_EXPBITS_D;
|
|
75 unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
|
|
76 unsigned frac0 : _FP_W_TYPE_SIZE;
|
|
77 #else
|
|
78 unsigned frac0 : _FP_W_TYPE_SIZE;
|
|
79 unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
|
|
80 unsigned exp : _FP_EXPBITS_D;
|
|
81 unsigned sign : 1;
|
|
82 #endif
|
|
83 } bits __attribute__((packed));
|
|
84 };
|
|
85
|
|
86 #define FP_DECL_D(X) _FP_DECL(2,X)
|
|
87 #define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
|
|
88 #define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val)
|
|
89 #define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X)
|
|
90 #define FP_PACK_RAW_DP(val,X) \
|
|
91 do { \
|
|
92 if (!FP_INHIBIT_RESULTS) \
|
|
93 _FP_PACK_RAW_2_P(D,val,X); \
|
|
94 } while (0)
|
|
95
|
|
96 #define FP_UNPACK_D(X,val) \
|
|
97 do { \
|
|
98 _FP_UNPACK_RAW_2(D,X,val); \
|
|
99 _FP_UNPACK_CANONICAL(D,2,X); \
|
|
100 } while (0)
|
|
101
|
|
102 #define FP_UNPACK_DP(X,val) \
|
|
103 do { \
|
|
104 _FP_UNPACK_RAW_2_P(D,X,val); \
|
|
105 _FP_UNPACK_CANONICAL(D,2,X); \
|
|
106 } while (0)
|
|
107
|
|
108 #define FP_UNPACK_SEMIRAW_D(X,val) \
|
|
109 do { \
|
|
110 _FP_UNPACK_RAW_2(D,X,val); \
|
|
111 _FP_UNPACK_SEMIRAW(D,2,X); \
|
|
112 } while (0)
|
|
113
|
|
114 #define FP_UNPACK_SEMIRAW_DP(X,val) \
|
|
115 do { \
|
|
116 _FP_UNPACK_RAW_2_P(D,X,val); \
|
|
117 _FP_UNPACK_SEMIRAW(D,2,X); \
|
|
118 } while (0)
|
|
119
|
|
120 #define FP_PACK_D(val,X) \
|
|
121 do { \
|
|
122 _FP_PACK_CANONICAL(D,2,X); \
|
|
123 _FP_PACK_RAW_2(D,val,X); \
|
|
124 } while (0)
|
|
125
|
|
126 #define FP_PACK_DP(val,X) \
|
|
127 do { \
|
|
128 _FP_PACK_CANONICAL(D,2,X); \
|
|
129 if (!FP_INHIBIT_RESULTS) \
|
|
130 _FP_PACK_RAW_2_P(D,val,X); \
|
|
131 } while (0)
|
|
132
|
|
133 #define FP_PACK_SEMIRAW_D(val,X) \
|
|
134 do { \
|
|
135 _FP_PACK_SEMIRAW(D,2,X); \
|
|
136 _FP_PACK_RAW_2(D,val,X); \
|
|
137 } while (0)
|
|
138
|
|
139 #define FP_PACK_SEMIRAW_DP(val,X) \
|
|
140 do { \
|
|
141 _FP_PACK_SEMIRAW(D,2,X); \
|
|
142 if (!FP_INHIBIT_RESULTS) \
|
|
143 _FP_PACK_RAW_2_P(D,val,X); \
|
|
144 } while (0)
|
|
145
|
|
146 #define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X)
|
|
147 #define FP_NEG_D(R,X) _FP_NEG(D,2,R,X)
|
|
148 #define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y)
|
|
149 #define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y)
|
|
150 #define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y)
|
|
151 #define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y)
|
|
152 #define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X)
|
|
153 #define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q)
|
|
154
|
|
155 #define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un)
|
|
156 #define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
|
|
157 #define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y)
|
|
158
|
|
159 #define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
|
|
160 #define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
|
|
161
|
|
162 #define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X)
|
|
163 #define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X)
|
|
164
|
|
165 #else
|
|
166
|
|
167 union _FP_UNION_D
|
|
168 {
|
|
169 DFtype flt;
|
|
170 struct {
|
|
171 #if __BYTE_ORDER == __BIG_ENDIAN
|
|
172 unsigned sign : 1;
|
|
173 unsigned exp : _FP_EXPBITS_D;
|
|
174 _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
|
|
175 #else
|
|
176 _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
|
|
177 unsigned exp : _FP_EXPBITS_D;
|
|
178 unsigned sign : 1;
|
|
179 #endif
|
|
180 } bits __attribute__((packed));
|
|
181 };
|
|
182
|
|
183 #define FP_DECL_D(X) _FP_DECL(1,X)
|
|
184 #define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
|
|
185 #define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val)
|
|
186 #define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X)
|
|
187 #define FP_PACK_RAW_DP(val,X) \
|
|
188 do { \
|
|
189 if (!FP_INHIBIT_RESULTS) \
|
|
190 _FP_PACK_RAW_1_P(D,val,X); \
|
|
191 } while (0)
|
|
192
|
|
193 #define FP_UNPACK_D(X,val) \
|
|
194 do { \
|
|
195 _FP_UNPACK_RAW_1(D,X,val); \
|
|
196 _FP_UNPACK_CANONICAL(D,1,X); \
|
|
197 } while (0)
|
|
198
|
|
199 #define FP_UNPACK_DP(X,val) \
|
|
200 do { \
|
|
201 _FP_UNPACK_RAW_1_P(D,X,val); \
|
|
202 _FP_UNPACK_CANONICAL(D,1,X); \
|
|
203 } while (0)
|
|
204
|
|
205 #define FP_UNPACK_SEMIRAW_D(X,val) \
|
|
206 do { \
|
|
207 _FP_UNPACK_RAW_1(D,X,val); \
|
|
208 _FP_UNPACK_SEMIRAW(D,1,X); \
|
|
209 } while (0)
|
|
210
|
|
211 #define FP_UNPACK_SEMIRAW_DP(X,val) \
|
|
212 do { \
|
|
213 _FP_UNPACK_RAW_1_P(D,X,val); \
|
|
214 _FP_UNPACK_SEMIRAW(D,1,X); \
|
|
215 } while (0)
|
|
216
|
|
217 #define FP_PACK_D(val,X) \
|
|
218 do { \
|
|
219 _FP_PACK_CANONICAL(D,1,X); \
|
|
220 _FP_PACK_RAW_1(D,val,X); \
|
|
221 } while (0)
|
|
222
|
|
223 #define FP_PACK_DP(val,X) \
|
|
224 do { \
|
|
225 _FP_PACK_CANONICAL(D,1,X); \
|
|
226 if (!FP_INHIBIT_RESULTS) \
|
|
227 _FP_PACK_RAW_1_P(D,val,X); \
|
|
228 } while (0)
|
|
229
|
|
230 #define FP_PACK_SEMIRAW_D(val,X) \
|
|
231 do { \
|
|
232 _FP_PACK_SEMIRAW(D,1,X); \
|
|
233 _FP_PACK_RAW_1(D,val,X); \
|
|
234 } while (0)
|
|
235
|
|
236 #define FP_PACK_SEMIRAW_DP(val,X) \
|
|
237 do { \
|
|
238 _FP_PACK_SEMIRAW(D,1,X); \
|
|
239 if (!FP_INHIBIT_RESULTS) \
|
|
240 _FP_PACK_RAW_1_P(D,val,X); \
|
|
241 } while (0)
|
|
242
|
|
243 #define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X)
|
|
244 #define FP_NEG_D(R,X) _FP_NEG(D,1,R,X)
|
|
245 #define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y)
|
|
246 #define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y)
|
|
247 #define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y)
|
|
248 #define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y)
|
|
249 #define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X)
|
|
250 #define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q)
|
|
251
|
|
252 /* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
|
|
253 the target machine. */
|
|
254
|
|
255 #define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
|
|
256 #define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
|
|
257 #define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y)
|
|
258
|
|
259 #define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
|
|
260 #define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
|
|
261
|
|
262 #define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X)
|
|
263 #define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X)
|
|
264
|
|
265 #endif /* W_TYPE_SIZE < 64 */
|