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