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