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