1 /* Software floating-point emulation.
2    Definitions for IEEE Quad 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_QUAD_H
30 #define SOFT_FP_QUAD_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_Q	(4*_FP_W_TYPE_SIZE)
38 # define _FP_FRACTBITS_DW_Q	(8*_FP_W_TYPE_SIZE)
39 #else
40 # define _FP_FRACTBITS_Q		(2*_FP_W_TYPE_SIZE)
41 # define _FP_FRACTBITS_DW_Q	(4*_FP_W_TYPE_SIZE)
42 #endif
43 
44 #define _FP_FRACBITS_Q		113
45 #define _FP_FRACXBITS_Q		(_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
46 #define _FP_WFRACBITS_Q		(_FP_WORKBITS + _FP_FRACBITS_Q)
47 #define _FP_WFRACXBITS_Q	(_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
48 #define _FP_EXPBITS_Q		15
49 #define _FP_EXPBIAS_Q		16383
50 #define _FP_EXPMAX_Q		32767
51 
52 #define _FP_QNANBIT_Q		\
53 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
54 #define _FP_QNANBIT_SH_Q		\
55 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
56 #define _FP_IMPLBIT_Q		\
57 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
58 #define _FP_IMPLBIT_SH_Q		\
59 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
60 #define _FP_OVERFLOW_Q		\
61 	((_FP_W_TYPE) 1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
62 
63 #define _FP_WFRACBITS_DW_Q	(2 * _FP_WFRACBITS_Q)
64 #define _FP_WFRACXBITS_DW_Q	(_FP_FRACTBITS_DW_Q - _FP_WFRACBITS_DW_Q)
65 #define _FP_HIGHBIT_DW_Q	\
66   ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_Q - 1) % _FP_W_TYPE_SIZE)
67 
68 typedef float TFtype __attribute__ ((mode (TF)));
69 
70 #if _FP_W_TYPE_SIZE < 64
71 
72 union _FP_UNION_Q
73 {
74   TFtype flt;
75   struct _FP_STRUCT_LAYOUT
76   {
77 # if __BYTE_ORDER == __BIG_ENDIAN
78     unsigned sign : 1;
79     unsigned exp : _FP_EXPBITS_Q;
80     unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
81     unsigned long frac2 : _FP_W_TYPE_SIZE;
82     unsigned long frac1 : _FP_W_TYPE_SIZE;
83     unsigned long frac0 : _FP_W_TYPE_SIZE;
84 # else
85     unsigned long frac0 : _FP_W_TYPE_SIZE;
86     unsigned long frac1 : _FP_W_TYPE_SIZE;
87     unsigned long frac2 : _FP_W_TYPE_SIZE;
88     unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
89     unsigned exp : _FP_EXPBITS_Q;
90     unsigned sign : 1;
91 # endif /* not bigendian */
92   } bits;
93 };
94 
95 
96 # define FP_DECL_Q(X)		_FP_DECL (4, X)
97 # define FP_UNPACK_RAW_Q(X, val)	_FP_UNPACK_RAW_4 (Q, X, (val))
98 # define FP_UNPACK_RAW_QP(X, val)	_FP_UNPACK_RAW_4_P (Q, X, (val))
99 # define FP_PACK_RAW_Q(val, X)	_FP_PACK_RAW_4 (Q, (val), X)
100 # define FP_PACK_RAW_QP(val, X)			\
101   do						\
102     {						\
103       if (!FP_INHIBIT_RESULTS)			\
104 	_FP_PACK_RAW_4_P (Q, (val), X);		\
105     }						\
106   while (0)
107 
108 # define FP_UNPACK_Q(X, val)			\
109   do						\
110     {						\
111       _FP_UNPACK_RAW_4 (Q, X, (val));		\
112       _FP_UNPACK_CANONICAL (Q, 4, X);		\
113     }						\
114   while (0)
115 
116 # define FP_UNPACK_QP(X, val)			\
117   do						\
118     {						\
119       _FP_UNPACK_RAW_4_P (Q, X, (val));		\
120       _FP_UNPACK_CANONICAL (Q, 4, X);		\
121     }						\
122   while (0)
123 
124 # define FP_UNPACK_SEMIRAW_Q(X, val)		\
125   do						\
126     {						\
127       _FP_UNPACK_RAW_4 (Q, X, (val));		\
128       _FP_UNPACK_SEMIRAW (Q, 4, X);		\
129     }						\
130   while (0)
131 
132 # define FP_UNPACK_SEMIRAW_QP(X, val)		\
133   do						\
134     {						\
135       _FP_UNPACK_RAW_4_P (Q, X, (val));		\
136       _FP_UNPACK_SEMIRAW (Q, 4, X);		\
137     }						\
138   while (0)
139 
140 # define FP_PACK_Q(val, X)			\
141   do						\
142     {						\
143       _FP_PACK_CANONICAL (Q, 4, X);		\
144       _FP_PACK_RAW_4 (Q, (val), X);		\
145     }						\
146   while (0)
147 
148 # define FP_PACK_QP(val, X)			\
149   do						\
150     {						\
151       _FP_PACK_CANONICAL (Q, 4, X);		\
152       if (!FP_INHIBIT_RESULTS)			\
153 	_FP_PACK_RAW_4_P (Q, (val), X);		\
154     }						\
155   while (0)
156 
157 # define FP_PACK_SEMIRAW_Q(val, X)		\
158   do						\
159     {						\
160       _FP_PACK_SEMIRAW (Q, 4, X);		\
161       _FP_PACK_RAW_4 (Q, (val), X);		\
162     }						\
163   while (0)
164 
165 # define FP_PACK_SEMIRAW_QP(val, X)		\
166   do						\
167     {						\
168       _FP_PACK_SEMIRAW (Q, 4, X);		\
169       if (!FP_INHIBIT_RESULTS)			\
170 	_FP_PACK_RAW_4_P (Q, (val), X);		\
171     }						\
172   while (0)
173 
174 # define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN (Q, 4, X)
175 # define FP_NEG_Q(R, X)			_FP_NEG (Q, 4, R, X)
176 # define FP_ADD_Q(R, X, Y)		_FP_ADD (Q, 4, R, X, Y)
177 # define FP_SUB_Q(R, X, Y)		_FP_SUB (Q, 4, R, X, Y)
178 # define FP_MUL_Q(R, X, Y)		_FP_MUL (Q, 4, R, X, Y)
179 # define FP_DIV_Q(R, X, Y)		_FP_DIV (Q, 4, R, X, Y)
180 # define FP_SQRT_Q(R, X)		_FP_SQRT (Q, 4, R, X)
181 # define _FP_SQRT_MEAT_Q(R, S, T, X, Q)	_FP_SQRT_MEAT_4 (R, S, T, X, (Q))
182 # define FP_FMA_Q(R, X, Y, Z)		_FP_FMA (Q, 4, 8, R, X, Y, Z)
183 
184 # define FP_CMP_Q(r, X, Y, un, ex)	_FP_CMP (Q, 4, (r), X, Y, (un), (ex))
185 # define FP_CMP_EQ_Q(r, X, Y, ex)	_FP_CMP_EQ (Q, 4, (r), X, Y, (ex))
186 # define FP_CMP_UNORD_Q(r, X, Y, ex)	_FP_CMP_UNORD (Q, 4, (r), X, Y, (ex))
187 
188 # define FP_TO_INT_Q(r, X, rsz, rsg)	_FP_TO_INT (Q, 4, (r), X, (rsz), (rsg))
189 # define FP_TO_INT_ROUND_Q(r, X, rsz, rsg)	\
190   _FP_TO_INT_ROUND (Q, 4, (r), X, (rsz), (rsg))
191 # define FP_FROM_INT_Q(X, r, rs, rt)	_FP_FROM_INT (Q, 4, X, (r), (rs), rt)
192 
193 # define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_4 (X)
194 # define _FP_FRAC_HIGH_RAW_Q(X)	_FP_FRAC_HIGH_4 (X)
195 
196 # define _FP_FRAC_HIGH_DW_Q(X)	_FP_FRAC_HIGH_8 (X)
197 
198 #else   /* not _FP_W_TYPE_SIZE < 64 */
199 union _FP_UNION_Q
200 {
201   TFtype flt /* __attribute__ ((mode (TF))) */ ;
202   struct _FP_STRUCT_LAYOUT
203   {
204     _FP_W_TYPE a, b;
205   } longs;
206   struct _FP_STRUCT_LAYOUT
207   {
208 # if __BYTE_ORDER == __BIG_ENDIAN
209     unsigned sign    : 1;
210     unsigned exp     : _FP_EXPBITS_Q;
211     _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE;
212     _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE;
213 # else
214     _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE;
215     _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE;
216     unsigned exp     : _FP_EXPBITS_Q;
217     unsigned sign    : 1;
218 # endif
219   } bits;
220 };
221 
222 # define FP_DECL_Q(X)		_FP_DECL (2, X)
223 # define FP_UNPACK_RAW_Q(X, val)	_FP_UNPACK_RAW_2 (Q, X, (val))
224 # define FP_UNPACK_RAW_QP(X, val)	_FP_UNPACK_RAW_2_P (Q, X, (val))
225 # define FP_PACK_RAW_Q(val, X)	_FP_PACK_RAW_2 (Q, (val), X)
226 # define FP_PACK_RAW_QP(val, X)			\
227   do						\
228     {						\
229       if (!FP_INHIBIT_RESULTS)			\
230 	_FP_PACK_RAW_2_P (Q, (val), X);		\
231     }						\
232   while (0)
233 
234 # define FP_UNPACK_Q(X, val)			\
235   do						\
236     {						\
237       _FP_UNPACK_RAW_2 (Q, X, (val));		\
238       _FP_UNPACK_CANONICAL (Q, 2, X);		\
239     }						\
240   while (0)
241 
242 # define FP_UNPACK_QP(X, val)			\
243   do						\
244     {						\
245       _FP_UNPACK_RAW_2_P (Q, X, (val));		\
246       _FP_UNPACK_CANONICAL (Q, 2, X);		\
247     }						\
248   while (0)
249 
250 # define FP_UNPACK_SEMIRAW_Q(X, val)		\
251   do						\
252     {						\
253       _FP_UNPACK_RAW_2 (Q, X, (val));		\
254       _FP_UNPACK_SEMIRAW (Q, 2, X);		\
255     }						\
256   while (0)
257 
258 # define FP_UNPACK_SEMIRAW_QP(X, val)		\
259   do						\
260     {						\
261       _FP_UNPACK_RAW_2_P (Q, X, (val));		\
262       _FP_UNPACK_SEMIRAW (Q, 2, X);		\
263     }						\
264   while (0)
265 
266 # define FP_PACK_Q(val, X)			\
267   do						\
268     {						\
269       _FP_PACK_CANONICAL (Q, 2, X);		\
270       _FP_PACK_RAW_2 (Q, (val), X);		\
271     }						\
272   while (0)
273 
274 # define FP_PACK_QP(val, X)			\
275   do						\
276     {						\
277       _FP_PACK_CANONICAL (Q, 2, X);		\
278       if (!FP_INHIBIT_RESULTS)			\
279 	_FP_PACK_RAW_2_P (Q, (val), X);		\
280     }						\
281   while (0)
282 
283 # define FP_PACK_SEMIRAW_Q(val, X)		\
284   do						\
285     {						\
286       _FP_PACK_SEMIRAW (Q, 2, X);		\
287       _FP_PACK_RAW_2 (Q, (val), X);		\
288     }						\
289   while (0)
290 
291 # define FP_PACK_SEMIRAW_QP(val, X)		\
292   do						\
293     {						\
294       _FP_PACK_SEMIRAW (Q, 2, X);		\
295       if (!FP_INHIBIT_RESULTS)			\
296 	_FP_PACK_RAW_2_P (Q, (val), X);		\
297     }						\
298   while (0)
299 
300 # define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN (Q, 2, X)
301 # define FP_NEG_Q(R, X)			_FP_NEG (Q, 2, R, X)
302 # define FP_ADD_Q(R, X, Y)		_FP_ADD (Q, 2, R, X, Y)
303 # define FP_SUB_Q(R, X, Y)		_FP_SUB (Q, 2, R, X, Y)
304 # define FP_MUL_Q(R, X, Y)		_FP_MUL (Q, 2, R, X, Y)
305 # define FP_DIV_Q(R, X, Y)		_FP_DIV (Q, 2, R, X, Y)
306 # define FP_SQRT_Q(R, X)		_FP_SQRT (Q, 2, R, X)
307 # define _FP_SQRT_MEAT_Q(R, S, T, X, Q)	_FP_SQRT_MEAT_2 (R, S, T, X, (Q))
308 # define FP_FMA_Q(R, X, Y, Z)		_FP_FMA (Q, 2, 4, R, X, Y, Z)
309 
310 # define FP_CMP_Q(r, X, Y, un, ex)	_FP_CMP (Q, 2, (r), X, Y, (un), (ex))
311 # define FP_CMP_EQ_Q(r, X, Y, ex)	_FP_CMP_EQ (Q, 2, (r), X, Y, (ex))
312 # define FP_CMP_UNORD_Q(r, X, Y, ex)	_FP_CMP_UNORD (Q, 2, (r), X, Y, (ex))
313 
314 # define FP_TO_INT_Q(r, X, rsz, rsg)	_FP_TO_INT (Q, 2, (r), X, (rsz), (rsg))
315 # define FP_TO_INT_ROUND_Q(r, X, rsz, rsg)	\
316   _FP_TO_INT_ROUND (Q, 2, (r), X, (rsz), (rsg))
317 # define FP_FROM_INT_Q(X, r, rs, rt)	_FP_FROM_INT (Q, 2, X, (r), (rs), rt)
318 
319 # define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_2 (X)
320 # define _FP_FRAC_HIGH_RAW_Q(X)	_FP_FRAC_HIGH_2 (X)
321 
322 # define _FP_FRAC_HIGH_DW_Q(X)	_FP_FRAC_HIGH_4 (X)
323 
324 #endif /* not _FP_W_TYPE_SIZE < 64 */
325 
326 #endif /* !SOFT_FP_QUAD_H */
327