]> git.ipfire.org Git - thirdparty/glibc.git/blame - soft-fp/op-common.h
Consistently include Makeconfig after defining subdir.
[thirdparty/glibc.git] / soft-fp / op-common.h
CommitLineData
d876f532 1/* Software floating-point emulation. Common operations.
d4697bc9 2 Copyright (C) 1997-2014 Free Software Foundation, Inc.
d876f532
UD
3 This file is part of the GNU C Library.
4 Contributed by Richard Henderson (rth@cygnus.com),
5 Jakub Jelinek (jj@ultra.linux.cz),
6 David S. Miller (davem@redhat.com) and
7 Peter Maydell (pmaydell@chiark.greenend.org.uk).
8
9 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
d876f532 13
638a783c
RM
14 In addition to the permissions in the GNU Lesser General Public
15 License, the Free Software Foundation gives you unlimited
16 permission to link the compiled version of this file into
17 combinations with other programs, and to distribute those
18 combinations without any restriction coming from the use of this
19 file. (The Lesser General Public License restrictions do apply in
20 other respects; for example, they cover modification of the file,
21 and distribution when not linked into a combine executable.)
22
d876f532
UD
23 The GNU C Library is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 26 Lesser General Public License for more details.
d876f532 27
41bdb6e2 28 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
29 License along with the GNU C Library; if not, see
30 <http://www.gnu.org/licenses/>. */
d876f532 31
a0d7066a 32#define _FP_DECL(wc, X) \
51ca9e29
JM
33 _FP_I_TYPE X##_c __attribute__ ((unused)); \
34 _FP_I_TYPE X##_s __attribute__ ((unused)); \
ace614b8 35 _FP_I_TYPE X##_e __attribute__ ((unused)); \
51ca9e29 36 _FP_FRAC_DECL_##wc (X)
d876f532 37
2848b105 38/* Test whether the qNaN bit denotes a signaling NaN. */
51ca9e29
JM
39#define _FP_FRAC_SNANP(fs, X) \
40 ((_FP_QNANNEGATEDP) \
41 ? (_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs) \
42 : !(_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs))
43#define _FP_FRAC_SNANP_SEMIRAW(fs, X) \
44 ((_FP_QNANNEGATEDP) \
45 ? (_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs) \
46 : !(_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs))
2848b105 47
d876f532 48/*
5b60c59d 49 * Finish truly unpacking a native fp value by classifying the kind
d876f532
UD
50 * of fp value and normalizing both the exponent and the fraction.
51 */
52
1e145589
JM
53#define _FP_UNPACK_CANONICAL(fs, wc, X) \
54 do \
55 { \
56 switch (X##_e) \
57 { \
58 default: \
51ca9e29
JM
59 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \
60 _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \
1e145589
JM
61 X##_e -= _FP_EXPBIAS_##fs; \
62 X##_c = FP_CLS_NORMAL; \
63 break; \
64 \
65 case 0: \
51ca9e29 66 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589
JM
67 X##_c = FP_CLS_ZERO; \
68 else \
69 { \
70 /* a denormalized number */ \
71 _FP_I_TYPE _shift; \
51ca9e29 72 _FP_FRAC_CLZ_##wc (_shift, X); \
1e145589 73 _shift -= _FP_FRACXBITS_##fs; \
51ca9e29 74 _FP_FRAC_SLL_##wc (X, (_shift+_FP_WORKBITS)); \
1e145589
JM
75 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
76 X##_c = FP_CLS_NORMAL; \
51ca9e29 77 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
78 } \
79 break; \
80 \
81 case _FP_EXPMAX_##fs: \
51ca9e29 82 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589
JM
83 X##_c = FP_CLS_INF; \
84 else \
85 { \
86 X##_c = FP_CLS_NAN; \
87 /* Check for signaling NaN */ \
51ca9e29
JM
88 if (_FP_FRAC_SNANP (fs, X)) \
89 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
90 } \
91 break; \
92 } \
93 } \
94 while (0)
d876f532 95
fe0b1e85
RM
96/* Finish unpacking an fp value in semi-raw mode: the mantissa is
97 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
98 other classification is not done. */
51ca9e29 99#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc (X, _FP_WORKBITS)
fe0b1e85
RM
100
101/* A semi-raw value has overflowed to infinity. Adjust the mantissa
102 and exponent appropriately. */
103#define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
1e145589 104 do \
fe0b1e85 105 { \
1e145589
JM
106 if (FP_ROUNDMODE == FP_RND_NEAREST \
107 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
108 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
109 { \
110 X##_e = _FP_EXPMAX_##fs; \
51ca9e29 111 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
1e145589
JM
112 } \
113 else \
114 { \
115 X##_e = _FP_EXPMAX_##fs - 1; \
51ca9e29 116 _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \
1e145589 117 } \
51ca9e29
JM
118 FP_SET_EXCEPTION (FP_EX_INEXACT); \
119 FP_SET_EXCEPTION (FP_EX_OVERFLOW); \
fe0b1e85 120 } \
1e145589 121 while (0)
fe0b1e85
RM
122
123/* Check for a semi-raw value being a signaling NaN and raise the
124 invalid exception if so. */
1e145589
JM
125#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
126 do \
127 { \
128 if (X##_e == _FP_EXPMAX_##fs \
51ca9e29
JM
129 && !_FP_FRAC_ZEROP_##wc (X) \
130 && _FP_FRAC_SNANP_SEMIRAW (fs, X)) \
131 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
132 } \
133 while (0)
fe0b1e85
RM
134
135/* Choose a NaN result from an operation on two semi-raw NaN
136 values. */
137#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
1e145589
JM
138 do \
139 { \
140 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
51ca9e29
JM
141 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
142 _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS); \
143 _FP_CHOOSENAN (fs, wc, R, X, Y, OP); \
144 _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \
1e145589
JM
145 } \
146 while (0)
fe0b1e85 147
2848b105
MR
148/* Make the fractional part a quiet NaN, preserving the payload
149 if possible, otherwise make it the canonical quiet NaN and set
150 the sign bit accordingly. */
1e145589
JM
151#define _FP_SETQNAN(fs, wc, X) \
152 do \
153 { \
154 if (_FP_QNANNEGATEDP) \
155 { \
51ca9e29
JM
156 _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1; \
157 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589
JM
158 { \
159 X##_s = _FP_NANSIGN_##fs; \
51ca9e29 160 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
1e145589
JM
161 } \
162 } \
163 else \
51ca9e29 164 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs; \
1e145589
JM
165 } \
166 while (0)
167#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \
168 do \
169 { \
170 if (_FP_QNANNEGATEDP) \
171 { \
51ca9e29
JM
172 _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1; \
173 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589
JM
174 { \
175 X##_s = _FP_NANSIGN_##fs; \
51ca9e29
JM
176 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
177 _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \
1e145589
JM
178 } \
179 } \
180 else \
51ca9e29 181 _FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs; \
1e145589
JM
182 } \
183 while (0)
2848b105 184
fe0b1e85
RM
185/* Test whether a biased exponent is normal (not zero or maximum). */
186#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
187
188/* Prepare to pack an fp value in semi-raw mode: the mantissa is
189 rounded and shifted right, with the rounding possibly increasing
190 the exponent (including changing a finite value to infinity). */
191#define _FP_PACK_SEMIRAW(fs, wc, X) \
1e145589
JM
192 do \
193 { \
ace614b8
JM
194 int _FP_PACK_SEMIRAW_is_tiny \
195 = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X); \
196 if (_FP_TININESS_AFTER_ROUNDING \
197 && _FP_PACK_SEMIRAW_is_tiny) \
198 { \
199 FP_DECL_##fs (_FP_PACK_SEMIRAW_T); \
200 _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X); \
201 _FP_PACK_SEMIRAW_T##_s = X##_s; \
202 _FP_PACK_SEMIRAW_T##_e = X##_e; \
203 _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1); \
204 _FP_ROUND (wc, _FP_PACK_SEMIRAW_T); \
205 if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T)) \
206 _FP_PACK_SEMIRAW_is_tiny = 0; \
207 } \
51ca9e29 208 _FP_ROUND (wc, X); \
ace614b8 209 if (_FP_PACK_SEMIRAW_is_tiny) \
1e145589 210 { \
47594329
MS
211 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
212 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
51ca9e29 213 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
1e145589 214 } \
51ca9e29 215 if (_FP_FRAC_HIGH_##fs (X) \
1e145589 216 & (_FP_OVERFLOW_##fs >> 1)) \
ae251b0b 217 { \
51ca9e29 218 _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1); \
1e145589
JM
219 X##_e++; \
220 if (X##_e == _FP_EXPMAX_##fs) \
51ca9e29 221 _FP_OVERFLOW_SEMIRAW (fs, wc, X); \
1e145589 222 } \
51ca9e29
JM
223 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
224 if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1e145589
JM
225 { \
226 if (!_FP_KEEPNANFRACP) \
227 { \
51ca9e29 228 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
1e145589
JM
229 X##_s = _FP_NANSIGN_##fs; \
230 } \
231 else \
51ca9e29 232 _FP_SETQNAN (fs, wc, X); \
ae251b0b 233 } \
fe0b1e85 234 } \
1e145589 235 while (0)
fe0b1e85 236
d876f532
UD
237/*
238 * Before packing the bits back into the native fp result, take care
239 * of such mundane things as rounding and overflow. Also, for some
240 * kinds of fp values, the original parts may not have been fully
241 * extracted -- but that is ok, we can regenerate them now.
242 */
243
1e145589
JM
244#define _FP_PACK_CANONICAL(fs, wc, X) \
245 do \
246 { \
247 switch (X##_c) \
248 { \
249 case FP_CLS_NORMAL: \
250 X##_e += _FP_EXPBIAS_##fs; \
251 if (X##_e > 0) \
252 { \
51ca9e29
JM
253 _FP_ROUND (wc, X); \
254 if (_FP_FRAC_OVERP_##wc (fs, X)) \
1e145589 255 { \
51ca9e29 256 _FP_FRAC_CLEAR_OVERP_##wc (fs, X); \
1e145589
JM
257 X##_e++; \
258 } \
51ca9e29 259 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
1e145589
JM
260 if (X##_e >= _FP_EXPMAX_##fs) \
261 { \
262 /* overflow */ \
263 switch (FP_ROUNDMODE) \
264 { \
265 case FP_RND_NEAREST: \
266 X##_c = FP_CLS_INF; \
267 break; \
268 case FP_RND_PINF: \
269 if (!X##_s) \
270 X##_c = FP_CLS_INF; \
271 break; \
272 case FP_RND_MINF: \
273 if (X##_s) \
274 X##_c = FP_CLS_INF; \
275 break; \
276 } \
277 if (X##_c == FP_CLS_INF) \
278 { \
279 /* Overflow to infinity */ \
280 X##_e = _FP_EXPMAX_##fs; \
51ca9e29 281 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
1e145589
JM
282 } \
283 else \
284 { \
285 /* Overflow to maximum normal */ \
286 X##_e = _FP_EXPMAX_##fs - 1; \
51ca9e29 287 _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \
1e145589 288 } \
51ca9e29
JM
289 FP_SET_EXCEPTION (FP_EX_OVERFLOW); \
290 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1e145589
JM
291 } \
292 } \
293 else \
294 { \
295 /* we've got a denormalized number */ \
ace614b8
JM
296 int _FP_PACK_CANONICAL_is_tiny = 1; \
297 if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \
298 { \
299 FP_DECL_##fs (_FP_PACK_CANONICAL_T); \
300 _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X); \
301 _FP_PACK_CANONICAL_T##_s = X##_s; \
302 _FP_PACK_CANONICAL_T##_e = X##_e; \
303 _FP_ROUND (wc, _FP_PACK_CANONICAL_T); \
304 if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T)) \
305 _FP_PACK_CANONICAL_is_tiny = 0; \
306 } \
1e145589
JM
307 X##_e = -X##_e + 1; \
308 if (X##_e <= _FP_WFRACBITS_##fs) \
309 { \
51ca9e29
JM
310 _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs); \
311 _FP_ROUND (wc, X); \
312 if (_FP_FRAC_HIGH_##fs (X) \
1e145589
JM
313 & (_FP_OVERFLOW_##fs >> 1)) \
314 { \
315 X##_e = 1; \
51ca9e29
JM
316 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
317 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1e145589
JM
318 } \
319 else \
320 { \
321 X##_e = 0; \
51ca9e29 322 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
1e145589 323 } \
ace614b8
JM
324 if (_FP_PACK_CANONICAL_is_tiny \
325 && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
326 || (FP_TRAPPING_EXCEPTIONS \
327 & FP_EX_UNDERFLOW))) \
51ca9e29 328 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
1e145589
JM
329 } \
330 else \
331 { \
332 /* underflow to zero */ \
333 X##_e = 0; \
51ca9e29 334 if (!_FP_FRAC_ZEROP_##wc (X)) \
1e145589 335 { \
51ca9e29
JM
336 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
337 _FP_ROUND (wc, X); \
338 _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS); \
1e145589 339 } \
51ca9e29 340 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
1e145589
JM
341 } \
342 } \
343 break; \
344 \
345 case FP_CLS_ZERO: \
346 X##_e = 0; \
51ca9e29 347 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
1e145589
JM
348 break; \
349 \
350 case FP_CLS_INF: \
351 X##_e = _FP_EXPMAX_##fs; \
51ca9e29 352 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
1e145589
JM
353 break; \
354 \
355 case FP_CLS_NAN: \
356 X##_e = _FP_EXPMAX_##fs; \
357 if (!_FP_KEEPNANFRACP) \
358 { \
51ca9e29 359 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
1e145589
JM
360 X##_s = _FP_NANSIGN_##fs; \
361 } \
362 else \
51ca9e29 363 _FP_SETQNAN (fs, wc, X); \
1e145589
JM
364 break; \
365 } \
366 } \
367 while (0)
d876f532
UD
368
369/* This one accepts raw argument and not cooked, returns
370 * 1 if X is a signaling NaN.
371 */
1e145589
JM
372#define _FP_ISSIGNAN(fs, wc, X) \
373 ({ \
374 int __ret = 0; \
375 if (X##_e == _FP_EXPMAX_##fs) \
376 { \
51ca9e29
JM
377 if (!_FP_FRAC_ZEROP_##wc (X) \
378 && _FP_FRAC_SNANP (fs, X)) \
1e145589
JM
379 __ret = 1; \
380 } \
381 __ret; \
382 })
d876f532
UD
383
384
385
386
387
fe0b1e85 388/* Addition on semi-raw values. */
1e145589
JM
389#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
390 do \
391 { \
392 if (X##_s == Y##_s) \
393 { \
394 /* Addition. */ \
395 R##_s = X##_s; \
396 int ediff = X##_e - Y##_e; \
397 if (ediff > 0) \
398 { \
399 R##_e = X##_e; \
400 if (Y##_e == 0) \
401 { \
402 /* Y is zero or denormalized. */ \
51ca9e29 403 if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589 404 { \
51ca9e29
JM
405 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
406 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
407 goto add_done; \
408 } \
409 else \
410 { \
51ca9e29 411 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
412 ediff--; \
413 if (ediff == 0) \
414 { \
51ca9e29 415 _FP_FRAC_ADD_##wc (R, X, Y); \
1e145589
JM
416 goto add3; \
417 } \
418 if (X##_e == _FP_EXPMAX_##fs) \
419 { \
51ca9e29
JM
420 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
421 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
422 goto add_done; \
423 } \
424 goto add1; \
425 } \
426 } \
427 else if (X##_e == _FP_EXPMAX_##fs) \
428 { \
429 /* X is NaN or Inf, Y is normal. */ \
51ca9e29
JM
430 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
431 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
432 goto add_done; \
433 } \
434 \
435 /* Insert implicit MSB of Y. */ \
51ca9e29 436 _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \
1e145589
JM
437 \
438 add1: \
439 /* Shift the mantissa of Y to the right EDIFF steps; \
440 remember to account later for the implicit MSB of X. */ \
441 if (ediff <= _FP_WFRACBITS_##fs) \
51ca9e29
JM
442 _FP_FRAC_SRS_##wc (Y, ediff, _FP_WFRACBITS_##fs); \
443 else if (!_FP_FRAC_ZEROP_##wc (Y)) \
444 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \
445 _FP_FRAC_ADD_##wc (R, X, Y); \
1e145589
JM
446 } \
447 else if (ediff < 0) \
448 { \
449 ediff = -ediff; \
450 R##_e = Y##_e; \
451 if (X##_e == 0) \
452 { \
453 /* X is zero or denormalized. */ \
51ca9e29 454 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589 455 { \
51ca9e29
JM
456 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
457 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
458 goto add_done; \
459 } \
460 else \
461 { \
51ca9e29 462 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
463 ediff--; \
464 if (ediff == 0) \
465 { \
51ca9e29 466 _FP_FRAC_ADD_##wc (R, Y, X); \
1e145589
JM
467 goto add3; \
468 } \
469 if (Y##_e == _FP_EXPMAX_##fs) \
470 { \
51ca9e29
JM
471 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
472 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
473 goto add_done; \
474 } \
475 goto add2; \
476 } \
477 } \
478 else if (Y##_e == _FP_EXPMAX_##fs) \
479 { \
480 /* Y is NaN or Inf, X is normal. */ \
51ca9e29
JM
481 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
482 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
483 goto add_done; \
484 } \
485 \
486 /* Insert implicit MSB of X. */ \
51ca9e29 487 _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \
1e145589
JM
488 \
489 add2: \
490 /* Shift the mantissa of X to the right EDIFF steps; \
491 remember to account later for the implicit MSB of Y. */ \
492 if (ediff <= _FP_WFRACBITS_##fs) \
51ca9e29
JM
493 _FP_FRAC_SRS_##wc (X, ediff, _FP_WFRACBITS_##fs); \
494 else if (!_FP_FRAC_ZEROP_##wc (X)) \
495 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
496 _FP_FRAC_ADD_##wc (R, Y, X); \
1e145589
JM
497 } \
498 else \
499 { \
500 /* ediff == 0. */ \
51ca9e29 501 if (!_FP_EXP_NORMAL (fs, wc, X)) \
1e145589
JM
502 { \
503 if (X##_e == 0) \
504 { \
505 /* X and Y are zero or denormalized. */ \
506 R##_e = 0; \
51ca9e29 507 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589 508 { \
51ca9e29
JM
509 if (!_FP_FRAC_ZEROP_##wc (Y)) \
510 FP_SET_EXCEPTION (FP_EX_DENORM); \
511 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
512 goto add_done; \
513 } \
51ca9e29 514 else if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589 515 { \
51ca9e29
JM
516 FP_SET_EXCEPTION (FP_EX_DENORM); \
517 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
518 goto add_done; \
519 } \
520 else \
521 { \
51ca9e29
JM
522 FP_SET_EXCEPTION (FP_EX_DENORM); \
523 _FP_FRAC_ADD_##wc (R, X, Y); \
524 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
1e145589
JM
525 { \
526 /* Normalized result. */ \
51ca9e29
JM
527 _FP_FRAC_HIGH_##fs (R) \
528 &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
1e145589
JM
529 R##_e = 1; \
530 } \
531 goto add_done; \
532 } \
533 } \
534 else \
535 { \
536 /* X and Y are NaN or Inf. */ \
51ca9e29
JM
537 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
538 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
1e145589 539 R##_e = _FP_EXPMAX_##fs; \
51ca9e29
JM
540 if (_FP_FRAC_ZEROP_##wc (X)) \
541 _FP_FRAC_COPY_##wc (R, Y); \
542 else if (_FP_FRAC_ZEROP_##wc (Y)) \
543 _FP_FRAC_COPY_##wc (R, X); \
1e145589 544 else \
51ca9e29 545 _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
1e145589
JM
546 goto add_done; \
547 } \
548 } \
549 /* The exponents of X and Y, both normal, are equal. The \
550 implicit MSBs will always add to increase the \
551 exponent. */ \
51ca9e29 552 _FP_FRAC_ADD_##wc (R, X, Y); \
1e145589 553 R##_e = X##_e + 1; \
51ca9e29 554 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
1e145589
JM
555 if (R##_e == _FP_EXPMAX_##fs) \
556 /* Overflow to infinity (depending on rounding mode). */ \
51ca9e29 557 _FP_OVERFLOW_SEMIRAW (fs, wc, R); \
1e145589
JM
558 goto add_done; \
559 } \
560 add3: \
51ca9e29 561 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
1e145589
JM
562 { \
563 /* Overflow. */ \
51ca9e29 564 _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
1e145589 565 R##_e++; \
51ca9e29 566 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
1e145589
JM
567 if (R##_e == _FP_EXPMAX_##fs) \
568 /* Overflow to infinity (depending on rounding mode). */ \
51ca9e29 569 _FP_OVERFLOW_SEMIRAW (fs, wc, R); \
1e145589
JM
570 } \
571 add_done: ; \
572 } \
573 else \
574 { \
575 /* Subtraction. */ \
576 int ediff = X##_e - Y##_e; \
577 if (ediff > 0) \
578 { \
579 R##_e = X##_e; \
580 R##_s = X##_s; \
581 if (Y##_e == 0) \
582 { \
583 /* Y is zero or denormalized. */ \
51ca9e29 584 if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589 585 { \
51ca9e29
JM
586 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
587 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
588 goto sub_done; \
589 } \
590 else \
591 { \
51ca9e29 592 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
593 ediff--; \
594 if (ediff == 0) \
595 { \
51ca9e29 596 _FP_FRAC_SUB_##wc (R, X, Y); \
1e145589
JM
597 goto sub3; \
598 } \
599 if (X##_e == _FP_EXPMAX_##fs) \
600 { \
51ca9e29
JM
601 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
602 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
603 goto sub_done; \
604 } \
605 goto sub1; \
606 } \
607 } \
608 else if (X##_e == _FP_EXPMAX_##fs) \
609 { \
610 /* X is NaN or Inf, Y is normal. */ \
51ca9e29
JM
611 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
612 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
613 goto sub_done; \
614 } \
615 \
616 /* Insert implicit MSB of Y. */ \
51ca9e29 617 _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \
1e145589
JM
618 \
619 sub1: \
620 /* Shift the mantissa of Y to the right EDIFF steps; \
621 remember to account later for the implicit MSB of X. */ \
622 if (ediff <= _FP_WFRACBITS_##fs) \
51ca9e29
JM
623 _FP_FRAC_SRS_##wc (Y, ediff, _FP_WFRACBITS_##fs); \
624 else if (!_FP_FRAC_ZEROP_##wc (Y)) \
625 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \
626 _FP_FRAC_SUB_##wc (R, X, Y); \
1e145589
JM
627 } \
628 else if (ediff < 0) \
629 { \
630 ediff = -ediff; \
631 R##_e = Y##_e; \
632 R##_s = Y##_s; \
633 if (X##_e == 0) \
634 { \
635 /* X is zero or denormalized. */ \
51ca9e29 636 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589 637 { \
51ca9e29
JM
638 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
639 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
640 goto sub_done; \
641 } \
642 else \
643 { \
51ca9e29 644 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
645 ediff--; \
646 if (ediff == 0) \
647 { \
51ca9e29 648 _FP_FRAC_SUB_##wc (R, Y, X); \
1e145589
JM
649 goto sub3; \
650 } \
651 if (Y##_e == _FP_EXPMAX_##fs) \
652 { \
51ca9e29
JM
653 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
654 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
655 goto sub_done; \
656 } \
657 goto sub2; \
658 } \
659 } \
660 else if (Y##_e == _FP_EXPMAX_##fs) \
661 { \
662 /* Y is NaN or Inf, X is normal. */ \
51ca9e29
JM
663 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
664 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
665 goto sub_done; \
666 } \
667 \
668 /* Insert implicit MSB of X. */ \
51ca9e29 669 _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \
1e145589
JM
670 \
671 sub2: \
672 /* Shift the mantissa of X to the right EDIFF steps; \
673 remember to account later for the implicit MSB of Y. */ \
674 if (ediff <= _FP_WFRACBITS_##fs) \
51ca9e29
JM
675 _FP_FRAC_SRS_##wc (X, ediff, _FP_WFRACBITS_##fs); \
676 else if (!_FP_FRAC_ZEROP_##wc (X)) \
677 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
678 _FP_FRAC_SUB_##wc (R, Y, X); \
1e145589
JM
679 } \
680 else \
681 { \
682 /* ediff == 0. */ \
51ca9e29 683 if (!_FP_EXP_NORMAL (fs, wc, X)) \
1e145589
JM
684 { \
685 if (X##_e == 0) \
686 { \
687 /* X and Y are zero or denormalized. */ \
688 R##_e = 0; \
51ca9e29 689 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589 690 { \
51ca9e29
JM
691 _FP_FRAC_COPY_##wc (R, Y); \
692 if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589
JM
693 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
694 else \
695 { \
51ca9e29 696 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
697 R##_s = Y##_s; \
698 } \
699 goto sub_done; \
700 } \
51ca9e29 701 else if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589 702 { \
51ca9e29
JM
703 FP_SET_EXCEPTION (FP_EX_DENORM); \
704 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
705 R##_s = X##_s; \
706 goto sub_done; \
707 } \
708 else \
709 { \
51ca9e29
JM
710 FP_SET_EXCEPTION (FP_EX_DENORM); \
711 _FP_FRAC_SUB_##wc (R, X, Y); \
1e145589 712 R##_s = X##_s; \
51ca9e29 713 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
1e145589
JM
714 { \
715 /* |X| < |Y|, negate result. */ \
51ca9e29 716 _FP_FRAC_SUB_##wc (R, Y, X); \
1e145589
JM
717 R##_s = Y##_s; \
718 } \
51ca9e29 719 else if (_FP_FRAC_ZEROP_##wc (R)) \
1e145589
JM
720 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
721 goto sub_done; \
722 } \
723 } \
724 else \
725 { \
726 /* X and Y are NaN or Inf, of opposite signs. */ \
51ca9e29
JM
727 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
728 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
1e145589 729 R##_e = _FP_EXPMAX_##fs; \
51ca9e29 730 if (_FP_FRAC_ZEROP_##wc (X)) \
1e145589 731 { \
51ca9e29 732 if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589
JM
733 { \
734 /* Inf - Inf. */ \
735 R##_s = _FP_NANSIGN_##fs; \
51ca9e29
JM
736 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
737 _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \
738 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
739 } \
740 else \
741 { \
742 /* Inf - NaN. */ \
743 R##_s = Y##_s; \
51ca9e29 744 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
745 } \
746 } \
747 else \
748 { \
51ca9e29 749 if (_FP_FRAC_ZEROP_##wc (Y)) \
1e145589
JM
750 { \
751 /* NaN - Inf. */ \
752 R##_s = X##_s; \
51ca9e29 753 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
754 } \
755 else \
756 { \
757 /* NaN - NaN. */ \
51ca9e29 758 _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
1e145589
JM
759 } \
760 } \
761 goto sub_done; \
762 } \
763 } \
764 /* The exponents of X and Y, both normal, are equal. The \
765 implicit MSBs cancel. */ \
766 R##_e = X##_e; \
51ca9e29 767 _FP_FRAC_SUB_##wc (R, X, Y); \
1e145589 768 R##_s = X##_s; \
51ca9e29 769 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
1e145589
JM
770 { \
771 /* |X| < |Y|, negate result. */ \
51ca9e29 772 _FP_FRAC_SUB_##wc (R, Y, X); \
1e145589
JM
773 R##_s = Y##_s; \
774 } \
51ca9e29 775 else if (_FP_FRAC_ZEROP_##wc (R)) \
1e145589
JM
776 { \
777 R##_e = 0; \
778 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
779 goto sub_done; \
780 } \
781 goto norm; \
782 } \
783 sub3: \
51ca9e29 784 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
1e145589
JM
785 { \
786 int diff; \
787 /* Carry into most significant bit of larger one of X and Y, \
788 canceling it; renormalize. */ \
51ca9e29 789 _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1; \
1e145589 790 norm: \
51ca9e29 791 _FP_FRAC_CLZ_##wc (diff, R); \
1e145589 792 diff -= _FP_WFRACXBITS_##fs; \
51ca9e29 793 _FP_FRAC_SLL_##wc (R, diff); \
1e145589
JM
794 if (R##_e <= diff) \
795 { \
796 /* R is denormalized. */ \
797 diff = diff - R##_e + 1; \
51ca9e29 798 _FP_FRAC_SRS_##wc (R, diff, _FP_WFRACBITS_##fs); \
1e145589
JM
799 R##_e = 0; \
800 } \
801 else \
802 { \
803 R##_e -= diff; \
51ca9e29 804 _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
1e145589
JM
805 } \
806 } \
807 sub_done: ; \
808 } \
809 } \
810 while (0)
d876f532 811
51ca9e29 812#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+')
1e145589
JM
813#define _FP_SUB(fs, wc, R, X, Y) \
814 do \
815 { \
51ca9e29 816 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
1e145589 817 Y##_s ^= 1; \
51ca9e29 818 _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-'); \
1e145589
JM
819 } \
820 while (0)
d876f532
UD
821
822
823/*
2ae21ed2 824 * Main negation routine. The input value is raw.
d876f532
UD
825 */
826
1e145589
JM
827#define _FP_NEG(fs, wc, R, X) \
828 do \
829 { \
51ca9e29 830 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
831 R##_e = X##_e; \
832 R##_s = 1 ^ X##_s; \
833 } \
834 while (0)
d876f532
UD
835
836
837/*
838 * Main multiplication routine. The input values should be cooked.
839 */
840
1e145589
JM
841#define _FP_MUL(fs, wc, R, X, Y) \
842 do \
843 { \
844 R##_s = X##_s ^ Y##_s; \
845 R##_e = X##_e + Y##_e + 1; \
51ca9e29 846 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
1e145589 847 { \
51ca9e29 848 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
1e145589 849 R##_c = FP_CLS_NORMAL; \
77f01ab5 850 \
51ca9e29 851 _FP_MUL_MEAT_##fs (R, X, Y); \
77f01ab5 852 \
51ca9e29
JM
853 if (_FP_FRAC_OVERP_##wc (fs, R)) \
854 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
1e145589
JM
855 else \
856 R##_e--; \
857 break; \
77f01ab5 858 \
51ca9e29
JM
859 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
860 _FP_CHOOSENAN (fs, wc, R, X, Y, '*'); \
1e145589 861 break; \
77f01ab5 862 \
51ca9e29
JM
863 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
864 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
865 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1e145589 866 R##_s = X##_s; \
77f01ab5 867 \
51ca9e29
JM
868 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
869 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
870 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
871 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
872 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
873 R##_c = X##_c; \
874 break; \
77f01ab5 875 \
51ca9e29
JM
876 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
877 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
878 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1e145589 879 R##_s = Y##_s; \
77f01ab5 880 \
51ca9e29
JM
881 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
882 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
883 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
884 R##_c = Y##_c; \
885 break; \
77f01ab5 886 \
51ca9e29
JM
887 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
888 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1e145589
JM
889 R##_s = _FP_NANSIGN_##fs; \
890 R##_c = FP_CLS_NAN; \
51ca9e29
JM
891 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
892 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589 893 break; \
77f01ab5 894 \
1e145589 895 default: \
51ca9e29 896 abort (); \
1e145589
JM
897 } \
898 } \
899 while (0)
900
901
902/* Fused multiply-add. The input values should be cooked. */
903
904#define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \
905 do \
906 { \
51ca9e29 907 FP_DECL_##fs (T); \
1e145589
JM
908 T##_s = X##_s ^ Y##_s; \
909 T##_e = X##_e + Y##_e + 1; \
51ca9e29 910 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
1e145589 911 { \
51ca9e29 912 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
1e145589
JM
913 switch (Z##_c) \
914 { \
915 case FP_CLS_INF: \
916 case FP_CLS_NAN: \
917 R##_s = Z##_s; \
51ca9e29 918 _FP_FRAC_COPY_##wc (R, Z); \
1e145589
JM
919 R##_c = Z##_c; \
920 break; \
921 \
922 case FP_CLS_ZERO: \
923 R##_c = FP_CLS_NORMAL; \
924 R##_s = T##_s; \
925 R##_e = T##_e; \
926 \
51ca9e29 927 _FP_MUL_MEAT_##fs (R, X, Y); \
1e145589 928 \
51ca9e29
JM
929 if (_FP_FRAC_OVERP_##wc (fs, R)) \
930 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
1e145589
JM
931 else \
932 R##_e--; \
933 break; \
934 \
935 case FP_CLS_NORMAL:; \
51ca9e29
JM
936 _FP_FRAC_DECL_##dwc (TD); \
937 _FP_FRAC_DECL_##dwc (ZD); \
938 _FP_FRAC_DECL_##dwc (RD); \
939 _FP_MUL_MEAT_DW_##fs (TD, X, Y); \
1e145589 940 R##_e = T##_e; \
51ca9e29 941 int tsh = _FP_FRAC_HIGHBIT_DW_##dwc (fs, TD) == 0; \
1e145589
JM
942 T##_e -= tsh; \
943 int ediff = T##_e - Z##_e; \
944 if (ediff >= 0) \
945 { \
946 int shift = _FP_WFRACBITS_##fs - tsh - ediff; \
947 if (shift <= -_FP_WFRACBITS_##fs) \
51ca9e29 948 _FP_FRAC_SET_##dwc (ZD, _FP_MINFRAC_##dwc); \
1e145589
JM
949 else \
950 { \
51ca9e29 951 _FP_FRAC_COPY_##dwc##_##wc (ZD, Z); \
1e145589 952 if (shift < 0) \
51ca9e29
JM
953 _FP_FRAC_SRS_##dwc (ZD, -shift, \
954 _FP_WFRACBITS_DW_##fs); \
1e145589 955 else if (shift > 0) \
51ca9e29 956 _FP_FRAC_SLL_##dwc (ZD, shift); \
1e145589
JM
957 } \
958 R##_s = T##_s; \
959 if (T##_s == Z##_s) \
51ca9e29 960 _FP_FRAC_ADD_##dwc (RD, TD, ZD); \
1e145589
JM
961 else \
962 { \
51ca9e29
JM
963 _FP_FRAC_SUB_##dwc (RD, TD, ZD); \
964 if (_FP_FRAC_NEGP_##dwc (RD)) \
1e145589
JM
965 { \
966 R##_s = Z##_s; \
51ca9e29 967 _FP_FRAC_SUB_##dwc (RD, ZD, TD); \
1e145589
JM
968 } \
969 } \
970 } \
971 else \
972 { \
973 R##_e = Z##_e; \
974 R##_s = Z##_s; \
51ca9e29
JM
975 _FP_FRAC_COPY_##dwc##_##wc (ZD, Z); \
976 _FP_FRAC_SLL_##dwc (ZD, _FP_WFRACBITS_##fs); \
1e145589
JM
977 int shift = -ediff - tsh; \
978 if (shift >= _FP_WFRACBITS_DW_##fs) \
51ca9e29 979 _FP_FRAC_SET_##dwc (TD, _FP_MINFRAC_##dwc); \
1e145589 980 else if (shift > 0) \
51ca9e29
JM
981 _FP_FRAC_SRS_##dwc (TD, shift, \
982 _FP_WFRACBITS_DW_##fs); \
1e145589 983 if (Z##_s == T##_s) \
51ca9e29 984 _FP_FRAC_ADD_##dwc (RD, ZD, TD); \
1e145589 985 else \
51ca9e29 986 _FP_FRAC_SUB_##dwc (RD, ZD, TD); \
1e145589 987 } \
51ca9e29 988 if (_FP_FRAC_ZEROP_##dwc (RD)) \
1e145589
JM
989 { \
990 if (T##_s == Z##_s) \
991 R##_s = Z##_s; \
992 else \
993 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
51ca9e29 994 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1e145589
JM
995 R##_c = FP_CLS_ZERO; \
996 } \
997 else \
998 { \
999 int rlz; \
51ca9e29 1000 _FP_FRAC_CLZ_##dwc (rlz, RD); \
1e145589
JM
1001 rlz -= _FP_WFRACXBITS_DW_##fs; \
1002 R##_e -= rlz; \
1003 int shift = _FP_WFRACBITS_##fs - rlz; \
1004 if (shift > 0) \
51ca9e29
JM
1005 _FP_FRAC_SRS_##dwc (RD, shift, \
1006 _FP_WFRACBITS_DW_##fs); \
1e145589 1007 else if (shift < 0) \
51ca9e29
JM
1008 _FP_FRAC_SLL_##dwc (RD, -shift); \
1009 _FP_FRAC_COPY_##wc##_##dwc (R, RD); \
1e145589
JM
1010 R##_c = FP_CLS_NORMAL; \
1011 } \
1012 break; \
1013 } \
1014 goto done_fma; \
1015 \
51ca9e29
JM
1016 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1017 _FP_CHOOSENAN (fs, wc, T, X, Y, '*'); \
1e145589
JM
1018 break; \
1019 \
51ca9e29
JM
1020 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1021 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1022 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1e145589
JM
1023 T##_s = X##_s; \
1024 \
51ca9e29
JM
1025 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1026 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1027 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1028 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1029 _FP_FRAC_COPY_##wc (T, X); \
1e145589
JM
1030 T##_c = X##_c; \
1031 break; \
1032 \
51ca9e29
JM
1033 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
1034 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1035 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1e145589
JM
1036 T##_s = Y##_s; \
1037 \
51ca9e29
JM
1038 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
1039 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
1040 _FP_FRAC_COPY_##wc (T, Y); \
1e145589
JM
1041 T##_c = Y##_c; \
1042 break; \
1043 \
51ca9e29
JM
1044 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1045 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1e145589
JM
1046 T##_s = _FP_NANSIGN_##fs; \
1047 T##_c = FP_CLS_NAN; \
51ca9e29
JM
1048 _FP_FRAC_SET_##wc (T, _FP_NANFRAC_##fs); \
1049 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
1050 break; \
1051 \
1052 default: \
51ca9e29 1053 abort (); \
1e145589
JM
1054 } \
1055 \
1056 /* T = X * Y is zero, infinity or NaN. */ \
51ca9e29 1057 switch (_FP_CLS_COMBINE (T##_c, Z##_c)) \
1e145589 1058 { \
51ca9e29
JM
1059 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1060 _FP_CHOOSENAN (fs, wc, R, T, Z, '+'); \
1e145589
JM
1061 break; \
1062 \
51ca9e29
JM
1063 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1064 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1065 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1066 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1067 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1e145589 1068 R##_s = T##_s; \
51ca9e29 1069 _FP_FRAC_COPY_##wc (R, T); \
1e145589
JM
1070 R##_c = T##_c; \
1071 break; \
1072 \
51ca9e29
JM
1073 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1074 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1075 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1076 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1e145589 1077 R##_s = Z##_s; \
51ca9e29 1078 _FP_FRAC_COPY_##wc (R, Z); \
1e145589
JM
1079 R##_c = Z##_c; \
1080 break; \
1081 \
51ca9e29 1082 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1e145589
JM
1083 if (T##_s == Z##_s) \
1084 { \
1085 R##_s = Z##_s; \
51ca9e29 1086 _FP_FRAC_COPY_##wc (R, Z); \
1e145589
JM
1087 R##_c = Z##_c; \
1088 } \
1089 else \
1090 { \
1091 R##_s = _FP_NANSIGN_##fs; \
1092 R##_c = FP_CLS_NAN; \
51ca9e29
JM
1093 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1094 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
1095 } \
1096 break; \
1097 \
51ca9e29 1098 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1e145589
JM
1099 if (T##_s == Z##_s) \
1100 R##_s = Z##_s; \
1101 else \
1102 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
51ca9e29 1103 _FP_FRAC_COPY_##wc (R, Z); \
1e145589
JM
1104 R##_c = Z##_c; \
1105 break; \
1106 \
1107 default: \
51ca9e29 1108 abort (); \
1e145589
JM
1109 } \
1110 done_fma: ; \
1111 } \
1112 while (0)
1113
1114
1115/*
1116 * Main division routine. The input values should be cooked.
1117 */
1118
1119#define _FP_DIV(fs, wc, R, X, Y) \
1120 do \
1121 { \
1122 R##_s = X##_s ^ Y##_s; \
1123 R##_e = X##_e - Y##_e; \
51ca9e29 1124 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
1e145589 1125 { \
51ca9e29 1126 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
1e145589 1127 R##_c = FP_CLS_NORMAL; \
77f01ab5 1128 \
51ca9e29 1129 _FP_DIV_MEAT_##fs (R, X, Y); \
1e145589 1130 break; \
77f01ab5 1131 \
51ca9e29
JM
1132 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1133 _FP_CHOOSENAN (fs, wc, R, X, Y, '/'); \
1e145589 1134 break; \
77f01ab5 1135 \
51ca9e29
JM
1136 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1137 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1138 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1e145589 1139 R##_s = X##_s; \
51ca9e29 1140 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
1141 R##_c = X##_c; \
1142 break; \
77f01ab5 1143 \
51ca9e29
JM
1144 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
1145 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1146 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1e145589 1147 R##_s = Y##_s; \
51ca9e29 1148 _FP_FRAC_COPY_##wc (R, Y); \
1e145589
JM
1149 R##_c = Y##_c; \
1150 break; \
77f01ab5 1151 \
51ca9e29
JM
1152 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
1153 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1154 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1e145589
JM
1155 R##_c = FP_CLS_ZERO; \
1156 break; \
77f01ab5 1157 \
51ca9e29
JM
1158 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
1159 FP_SET_EXCEPTION (FP_EX_DIVZERO); \
1160 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1161 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1e145589
JM
1162 R##_c = FP_CLS_INF; \
1163 break; \
77f01ab5 1164 \
51ca9e29
JM
1165 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1166 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1e145589
JM
1167 R##_s = _FP_NANSIGN_##fs; \
1168 R##_c = FP_CLS_NAN; \
51ca9e29
JM
1169 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1170 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589 1171 break; \
77f01ab5 1172 \
1e145589 1173 default: \
51ca9e29 1174 abort (); \
1e145589
JM
1175 } \
1176 } \
1177 while (0)
d876f532
UD
1178
1179
1180/*
1181 * Main differential comparison routine. The inputs should be raw not
1182 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
1183 */
1184
1185#define _FP_CMP(fs, wc, ret, X, Y, un) \
1e145589
JM
1186 do \
1187 { \
1188 /* NANs are unordered */ \
51ca9e29
JM
1189 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1190 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
1e145589
JM
1191 { \
1192 ret = un; \
1193 } \
1194 else \
1195 { \
1196 int __is_zero_x; \
1197 int __is_zero_y; \
d876f532 1198 \
51ca9e29
JM
1199 __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0; \
1200 __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0; \
d876f532 1201 \
1e145589
JM
1202 if (__is_zero_x && __is_zero_y) \
1203 ret = 0; \
1204 else if (__is_zero_x) \
1205 ret = Y##_s ? 1 : -1; \
1206 else if (__is_zero_y) \
1207 ret = X##_s ? -1 : 1; \
1208 else if (X##_s != Y##_s) \
1209 ret = X##_s ? -1 : 1; \
1210 else if (X##_e > Y##_e) \
1211 ret = X##_s ? -1 : 1; \
1212 else if (X##_e < Y##_e) \
1213 ret = X##_s ? 1 : -1; \
51ca9e29 1214 else if (_FP_FRAC_GT_##wc (X, Y)) \
1e145589 1215 ret = X##_s ? -1 : 1; \
51ca9e29 1216 else if (_FP_FRAC_GT_##wc (Y, X)) \
1e145589
JM
1217 ret = X##_s ? 1 : -1; \
1218 else \
1219 ret = 0; \
1220 } \
1221 } \
1222 while (0)
d876f532
UD
1223
1224
1225/* Simplification for strict equality. */
1226
1e145589
JM
1227#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
1228 do \
1229 { \
1230 /* NANs are unordered */ \
51ca9e29
JM
1231 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1232 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
1e145589
JM
1233 { \
1234 ret = 1; \
1235 } \
1236 else \
1237 { \
1238 ret = !(X##_e == Y##_e \
51ca9e29
JM
1239 && _FP_FRAC_EQ_##wc (X, Y) \
1240 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc (X)))); \
1e145589
JM
1241 } \
1242 } \
1243 while (0)
d876f532 1244
e7b8c7bc
RM
1245/* Version to test unordered. */
1246
1247#define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
1e145589
JM
1248 do \
1249 { \
51ca9e29
JM
1250 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1251 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \
1e145589
JM
1252 } \
1253 while (0)
e7b8c7bc 1254
d876f532
UD
1255/*
1256 * Main square root routine. The input value should be cooked.
1257 */
1258
1e145589
JM
1259#define _FP_SQRT(fs, wc, R, X) \
1260 do \
1261 { \
51ca9e29
JM
1262 _FP_FRAC_DECL_##wc (T); \
1263 _FP_FRAC_DECL_##wc (S); \
1e145589
JM
1264 _FP_W_TYPE q; \
1265 switch (X##_c) \
1266 { \
1267 case FP_CLS_NAN: \
51ca9e29 1268 _FP_FRAC_COPY_##wc (R, X); \
1e145589
JM
1269 R##_s = X##_s; \
1270 R##_c = FP_CLS_NAN; \
1271 break; \
1272 case FP_CLS_INF: \
1273 if (X##_s) \
1274 { \
1275 R##_s = _FP_NANSIGN_##fs; \
1276 R##_c = FP_CLS_NAN; /* NAN */ \
51ca9e29
JM
1277 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1278 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
1279 } \
1280 else \
1281 { \
1282 R##_s = 0; \
1283 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
1284 } \
1285 break; \
1286 case FP_CLS_ZERO: \
1287 R##_s = X##_s; \
1288 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
1289 break; \
1290 case FP_CLS_NORMAL: \
1291 R##_s = 0; \
1292 if (X##_s) \
1293 { \
1294 R##_c = FP_CLS_NAN; /* NAN */ \
1295 R##_s = _FP_NANSIGN_##fs; \
51ca9e29
JM
1296 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1297 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589
JM
1298 break; \
1299 } \
1300 R##_c = FP_CLS_NORMAL; \
1301 if (X##_e & 1) \
51ca9e29 1302 _FP_FRAC_SLL_##wc (X, 1); \
1e145589 1303 R##_e = X##_e >> 1; \
51ca9e29
JM
1304 _FP_FRAC_SET_##wc (S, _FP_ZEROFRAC_##wc); \
1305 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1e145589 1306 q = _FP_OVERFLOW_##fs >> 1; \
51ca9e29 1307 _FP_SQRT_MEAT_##wc (R, S, T, X, q); \
1e145589
JM
1308 } \
1309 } \
1310 while (0)
d876f532
UD
1311
1312/*
fe0b1e85 1313 * Convert from FP to integer. Input is raw.
d876f532
UD
1314 */
1315
1316/* RSIGNED can have following values:
1317 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
fe0b1e85
RM
1318 * the result is either 0 or (2^rsize)-1 depending on the sign in such
1319 * case.
1320 * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
1321 * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1322 * depending on the sign in such case.
d876f532 1323 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
fe0b1e85
RM
1324 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1325 * depending on the sign in such case.
d876f532 1326 */
fe0b1e85 1327#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1e145589 1328 do \
fe0b1e85 1329 { \
1e145589 1330 if (X##_e < _FP_EXPBIAS_##fs) \
fe0b1e85 1331 { \
1e145589
JM
1332 r = 0; \
1333 if (X##_e == 0) \
fe0b1e85 1334 { \
51ca9e29 1335 if (!_FP_FRAC_ZEROP_##wc (X)) \
1e145589 1336 { \
51ca9e29
JM
1337 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1338 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589 1339 } \
fe0b1e85 1340 } \
1e145589 1341 else \
51ca9e29 1342 FP_SET_EXCEPTION (FP_EX_INEXACT); \
fe0b1e85 1343 } \
1e145589
JM
1344 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1345 || (!rsigned && X##_s)) \
fe0b1e85 1346 { \
1e145589
JM
1347 /* Overflow or converting to the most negative integer. */ \
1348 if (rsigned) \
1349 { \
1350 r = 1; \
1351 r <<= rsize - 1; \
1352 r -= 1 - X##_s; \
1353 } else { \
1354 r = 0; \
1355 if (!X##_s) \
1356 r = ~r; \
1357 } \
a334319f 1358 \
1e145589
JM
1359 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1360 { \
1361 /* Possibly converting to most negative integer; check the \
1362 mantissa. */ \
1363 int inexact = 0; \
51ca9e29
JM
1364 (void) ((_FP_FRACBITS_##fs > rsize) \
1365 ? ({ \
1366 _FP_FRAC_SRST_##wc (X, inexact, \
1367 _FP_FRACBITS_##fs - rsize, \
1368 _FP_FRACBITS_##fs); \
1369 0; \
1370 }) \
1371 : 0); \
1372 if (!_FP_FRAC_ZEROP_##wc (X)) \
1373 FP_SET_EXCEPTION (FP_EX_INVALID); \
1e145589 1374 else if (inexact) \
51ca9e29 1375 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1e145589
JM
1376 } \
1377 else \
51ca9e29 1378 FP_SET_EXCEPTION (FP_EX_INVALID); \
fe0b1e85
RM
1379 } \
1380 else \
1e145589 1381 { \
51ca9e29 1382 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \
1e145589
JM
1383 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1384 { \
51ca9e29 1385 _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \
1e145589
JM
1386 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1387 } \
1388 else \
1389 { \
1390 int inexact; \
51ca9e29
JM
1391 _FP_FRAC_SRST_##wc (X, inexact, \
1392 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1393 - X##_e), \
1394 _FP_FRACBITS_##fs); \
1e145589 1395 if (inexact) \
51ca9e29
JM
1396 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1397 _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \
1e145589
JM
1398 } \
1399 if (rsigned && X##_s) \
1400 r = -r; \
1401 } \
fe0b1e85 1402 } \
1e145589
JM
1403 while (0)
1404
1405/* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1406 input is signed. */
1407#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1408 do \
fe0b1e85 1409 { \
1e145589 1410 if (r) \
fe0b1e85 1411 { \
1e145589
JM
1412 rtype ur_; \
1413 \
1414 if ((X##_s = (r < 0))) \
51ca9e29 1415 r = -(rtype) r; \
1e145589
JM
1416 \
1417 ur_ = (rtype) r; \
51ca9e29
JM
1418 (void) ((rsize <= _FP_W_TYPE_SIZE) \
1419 ? ({ \
1420 int lz_; \
1421 __FP_CLZ (lz_, (_FP_W_TYPE) ur_); \
1422 X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
1423 }) \
1424 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1425 ? ({ \
1426 int lz_; \
1427 __FP_CLZ_2 (lz_, \
1428 (_FP_W_TYPE) (ur_ >> _FP_W_TYPE_SIZE), \
1429 (_FP_W_TYPE) ur_); \
1430 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1431 - lz_); \
1432 }) \
1433 : (abort (), 0))); \
1e145589
JM
1434 \
1435 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1436 && X##_e >= _FP_EXPMAX_##fs) \
1437 { \
1438 /* Exponent too big; overflow to infinity. (May also \
1439 happen after rounding below.) */ \
51ca9e29 1440 _FP_OVERFLOW_SEMIRAW (fs, wc, X); \
1e145589
JM
1441 goto pack_semiraw; \
1442 } \
1443 \
1444 if (rsize <= _FP_FRACBITS_##fs \
1445 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1446 { \
1447 /* Exactly representable; shift left. */ \
51ca9e29 1448 _FP_FRAC_DISASSEMBLE_##wc (X, ur_, rsize); \
1e145589 1449 if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \
51ca9e29
JM
1450 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \
1451 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1e145589
JM
1452 } \
1453 else \
1454 { \
1455 /* More bits in integer than in floating type; need to \
1456 round. */ \
1457 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1458 ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
1459 - _FP_WFRACBITS_##fs + 1)) \
1460 | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1461 - _FP_WFRACBITS_##fs + 1))) \
1462 != 0)); \
51ca9e29 1463 _FP_FRAC_DISASSEMBLE_##wc (X, ur_, rsize); \
1e145589 1464 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
51ca9e29
JM
1465 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \
1466 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1467 _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
1e145589 1468 pack_semiraw: \
51ca9e29 1469 _FP_PACK_SEMIRAW (fs, wc, X); \
1e145589 1470 } \
fe0b1e85
RM
1471 } \
1472 else \
1473 { \
1e145589
JM
1474 X##_s = 0; \
1475 X##_e = 0; \
51ca9e29 1476 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
fe0b1e85 1477 } \
fe0b1e85 1478 } \
1e145589 1479 while (0)
d876f532 1480
0ecb606c 1481
fe0b1e85
RM
1482/* Extend from a narrower floating-point format to a wider one. Input
1483 and output are raw. */
51ca9e29 1484#define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \
1e145589
JM
1485 do \
1486 { \
1487 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1488 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1489 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1490 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1491 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
51ca9e29 1492 abort (); \
1e145589 1493 D##_s = S##_s; \
51ca9e29
JM
1494 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1495 if (_FP_EXP_NORMAL (sfs, swc, S)) \
1e145589
JM
1496 { \
1497 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
51ca9e29 1498 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1e145589
JM
1499 } \
1500 else \
1501 { \
1502 if (S##_e == 0) \
1503 { \
51ca9e29 1504 if (_FP_FRAC_ZEROP_##swc (S)) \
1e145589
JM
1505 D##_e = 0; \
1506 else if (_FP_EXPBIAS_##dfs \
1507 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1508 { \
51ca9e29
JM
1509 FP_SET_EXCEPTION (FP_EX_DENORM); \
1510 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \
1511 - _FP_FRACBITS_##sfs)); \
1e145589
JM
1512 D##_e = 0; \
1513 } \
1514 else \
1515 { \
1516 int _lz; \
51ca9e29
JM
1517 FP_SET_EXCEPTION (FP_EX_DENORM); \
1518 _FP_FRAC_CLZ_##swc (_lz, S); \
1519 _FP_FRAC_SLL_##dwc (D, \
1520 _lz + _FP_FRACBITS_##dfs \
1521 - _FP_FRACTBITS_##sfs); \
1e145589
JM
1522 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1523 + _FP_FRACXBITS_##sfs - _lz); \
1524 } \
1525 } \
1526 else \
1527 { \
1528 D##_e = _FP_EXPMAX_##dfs; \
51ca9e29 1529 if (!_FP_FRAC_ZEROP_##swc (S)) \
1e145589 1530 { \
51ca9e29
JM
1531 if (_FP_FRAC_SNANP (sfs, S)) \
1532 FP_SET_EXCEPTION (FP_EX_INVALID); \
1533 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \
1534 - _FP_FRACBITS_##sfs)); \
e5c2c2d0 1535 _FP_SETQNAN (dfs, dwc, D); \
1e145589
JM
1536 } \
1537 } \
1538 } \
1539 } \
1540 while (0)
fe0b1e85
RM
1541
1542/* Truncate from a wider floating-point format to a narrower one.
1543 Input and output are semi-raw. */
51ca9e29 1544#define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \
1e145589
JM
1545 do \
1546 { \
1547 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1548 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1549 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
51ca9e29 1550 abort (); \
1e145589 1551 D##_s = S##_s; \
51ca9e29 1552 if (_FP_EXP_NORMAL (sfs, swc, S)) \
1e145589
JM
1553 { \
1554 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1555 if (D##_e >= _FP_EXPMAX_##dfs) \
51ca9e29 1556 _FP_OVERFLOW_SEMIRAW (dfs, dwc, D); \
1e145589
JM
1557 else \
1558 { \
1559 if (D##_e <= 0) \
1560 { \
1561 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1562 { \
51ca9e29
JM
1563 _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc); \
1564 _FP_FRAC_LOW_##swc (S) |= 1; \
1e145589
JM
1565 } \
1566 else \
1567 { \
51ca9e29
JM
1568 _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs; \
1569 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1570 - _FP_WFRACBITS_##dfs \
1571 + 1 - D##_e), \
1572 _FP_WFRACBITS_##sfs); \
1e145589
JM
1573 } \
1574 D##_e = 0; \
1575 } \
1576 else \
51ca9e29
JM
1577 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1578 - _FP_WFRACBITS_##dfs), \
1579 _FP_WFRACBITS_##sfs); \
1580 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1e145589
JM
1581 } \
1582 } \
1583 else \
1584 { \
1585 if (S##_e == 0) \
1586 { \
1587 D##_e = 0; \
51ca9e29
JM
1588 if (_FP_FRAC_ZEROP_##swc (S)) \
1589 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1e145589
JM
1590 else \
1591 { \
51ca9e29 1592 FP_SET_EXCEPTION (FP_EX_DENORM); \
1e145589
JM
1593 if (_FP_EXPBIAS_##sfs \
1594 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1595 { \
51ca9e29
JM
1596 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1597 - _FP_WFRACBITS_##dfs), \
1598 _FP_WFRACBITS_##sfs); \
1599 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1e145589
JM
1600 } \
1601 else \
1602 { \
51ca9e29
JM
1603 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1604 _FP_FRAC_LOW_##dwc (D) |= 1; \
1e145589
JM
1605 } \
1606 } \
1607 } \
1608 else \
1609 { \
1610 D##_e = _FP_EXPMAX_##dfs; \
51ca9e29
JM
1611 if (_FP_FRAC_ZEROP_##swc (S)) \
1612 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1e145589
JM
1613 else \
1614 { \
51ca9e29
JM
1615 _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S); \
1616 _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs \
1617 - _FP_WFRACBITS_##dfs)); \
1618 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1e145589 1619 /* Semi-raw NaN must have all workbits cleared. */ \
51ca9e29 1620 _FP_FRAC_LOW_##dwc (D) \
1e145589 1621 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
51ca9e29 1622 _FP_SETQNAN_SEMIRAW (dfs, dwc, D); \
1e145589
JM
1623 } \
1624 } \
1625 } \
1626 } \
1627 while (0)
d876f532
UD
1628
1629/*
1630 * Helper primitives.
1631 */
1632
1633/* Count leading zeros in a word. */
1634
1635#ifndef __FP_CLZ
0d86378f 1636/* GCC 3.4 and later provide the builtins for us. */
1e145589
JM
1637# define __FP_CLZ(r, x) \
1638 do \
1639 { \
1640 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1641 r = __builtin_clz (x); \
1642 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1643 r = __builtin_clzl (x); \
1644 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1645 r = __builtin_clzll (x); \
1646 else \
1647 abort (); \
1648 } \
1649 while (0)
d876f532
UD
1650#endif /* ndef __FP_CLZ */
1651
1652#define _FP_DIV_HELP_imm(q, r, n, d) \
1e145589
JM
1653 do \
1654 { \
1655 q = n / d, r = n % d; \
1656 } \
1657 while (0)
d876f532 1658
1a8aaf91
UD
1659
1660/* A restoring bit-by-bit division primitive. */
1661
1662#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1e145589
JM
1663 do \
1664 { \
1665 int count = _FP_WFRACBITS_##fs; \
1666 _FP_FRAC_DECL_##wc (u); \
1667 _FP_FRAC_DECL_##wc (v); \
1668 _FP_FRAC_COPY_##wc (u, X); \
1669 _FP_FRAC_COPY_##wc (v, Y); \
1670 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1671 /* Normalize U and V. */ \
1672 _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
1673 _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
1674 /* First round. Since the operands are normalized, either the \
1675 first or second bit will be set in the fraction. Produce a \
1676 normalized result by checking which and adjusting the loop \
1677 count and exponent accordingly. */ \
1678 if (_FP_FRAC_GE_1 (u, v)) \
1a8aaf91
UD
1679 { \
1680 _FP_FRAC_SUB_##wc (u, u, v); \
1681 _FP_FRAC_LOW_##wc (R) |= 1; \
1e145589 1682 count--; \
1a8aaf91 1683 } \
1e145589
JM
1684 else \
1685 R##_e--; \
1686 /* Subsequent rounds. */ \
1687 do \
1688 { \
1689 int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
1690 _FP_FRAC_SLL_##wc (u, 1); \
1691 _FP_FRAC_SLL_##wc (R, 1); \
1692 if (msb || _FP_FRAC_GE_1 (u, v)) \
1693 { \
1694 _FP_FRAC_SUB_##wc (u, u, v); \
1695 _FP_FRAC_LOW_##wc (R) |= 1; \
1696 } \
1697 } \
1698 while (--count > 0); \
1699 /* If there's anything left in U, the result is inexact. */ \
1700 _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
1701 } \
1702 while (0)
1a8aaf91
UD
1703
1704#define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1705#define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1706#define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)