1 /* Software floating-point emulation.
2 Basic two-word fraction declaration and manipulation.
3 Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Richard Henderson (rth@cygnus.com),
6 Jakub Jelinek (jj@ultra.linux.cz),
7 David S. Miller (davem@redhat.com) and
8 Peter Maydell (pmaydell@chiark.greenend.org.uk).
10 The GNU C Library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
15 The GNU C Library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
20 You should have received a copy of the GNU Library General Public
21 License along with the GNU C Library; see the file COPYING.LIB. If
22 not, write to the Free Software Foundation, Inc.,
23 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #ifndef __MATH_EMU_OP_2_H__
26 #define __MATH_EMU_OP_2_H__
28 #define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
29 #define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
30 #define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
31 #define _FP_FRAC_HIGH_2(X) (X##_f1)
32 #define _FP_FRAC_LOW_2(X) (X##_f0)
33 #define _FP_FRAC_WORD_2(X,w) (X##_f##w)
35 #define _FP_FRAC_SLL_2(X,N) \
37 if ((N) < _FP_W_TYPE_SIZE) \
39 if (__builtin_constant_p(N) && (N) == 1) \
41 X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \
46 X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
52 X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \
57 #define _FP_FRAC_SRL_2(X,N) \
59 if ((N) < _FP_W_TYPE_SIZE) \
61 X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
66 X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \
71 /* Right shift with sticky-lsb. */
72 #define _FP_FRAC_SRS_2(X,N,sz) \
74 if ((N) < _FP_W_TYPE_SIZE) \
76 X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
77 (__builtin_constant_p(N) && (N) == 1 \
79 : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \
84 X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
85 (((X##_f1 << (2*_FP_W_TYPE_SIZE - (N))) | X##_f0) != 0)); \
90 #define _FP_FRAC_ADDI_2(X,I) \
91 __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
93 #define _FP_FRAC_ADD_2(R,X,Y) \
94 __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
96 #define _FP_FRAC_SUB_2(R,X,Y) \
97 __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
99 #define _FP_FRAC_DEC_2(X,Y) \
100 __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)
102 #define _FP_FRAC_CLZ_2(R,X) \
105 __FP_CLZ(R,X##_f1); \
108 __FP_CLZ(R,X##_f0); \
109 R += _FP_W_TYPE_SIZE; \
114 #define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)
115 #define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)
116 #define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
117 #define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
118 #define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
119 #define _FP_FRAC_GT_2(X, Y) \
120 (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
121 #define _FP_FRAC_GE_2(X, Y) \
122 (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
124 #define _FP_ZEROFRAC_2 0, 0
125 #define _FP_MINFRAC_2 0, 1
126 #define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
132 #define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)
134 #define __FP_CLZ_2(R, xh, xl) \
141 R += _FP_W_TYPE_SIZE; \
147 #ifndef __FP_FRAC_ADDI_2
148 #define __FP_FRAC_ADDI_2(xh, xl, i) \
149 (xh += ((xl += i) < i))
151 #ifndef __FP_FRAC_ADD_2
152 #define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
153 (rh = xh + yh + ((rl = xl + yl) < xl))
155 #ifndef __FP_FRAC_SUB_2
156 #define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
157 (rh = xh - yh - ((rl = xl - yl) > xl))
159 #ifndef __FP_FRAC_DEC_2
160 #define __FP_FRAC_DEC_2(xh, xl, yh, yl) \
163 xh -= yh + ((xl -= yl) > _t); \
169 #undef __FP_FRAC_ADDI_2
170 #define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)
171 #undef __FP_FRAC_ADD_2
172 #define __FP_FRAC_ADD_2 add_ssaaaa
173 #undef __FP_FRAC_SUB_2
174 #define __FP_FRAC_SUB_2 sub_ddmmss
175 #undef __FP_FRAC_DEC_2
176 #define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl)
181 * Unpack the raw bits of a native fp value. Do not classify or
182 * normalize the data.
185 #define _FP_UNPACK_RAW_2(fs, X, val) \
187 union _FP_UNION_##fs _flo; _flo.flt = (val); \
189 X##_f0 = _flo.bits.frac0; \
190 X##_f1 = _flo.bits.frac1; \
191 X##_e = _flo.bits.exp; \
192 X##_s = _flo.bits.sign; \
195 #define _FP_UNPACK_RAW_2_P(fs, X, val) \
197 union _FP_UNION_##fs *_flo = \
198 (union _FP_UNION_##fs *)(val); \
200 X##_f0 = _flo->bits.frac0; \
201 X##_f1 = _flo->bits.frac1; \
202 X##_e = _flo->bits.exp; \
203 X##_s = _flo->bits.sign; \
208 * Repack the raw bits of a native fp value.
211 #define _FP_PACK_RAW_2(fs, val, X) \
213 union _FP_UNION_##fs _flo; \
215 _flo.bits.frac0 = X##_f0; \
216 _flo.bits.frac1 = X##_f1; \
217 _flo.bits.exp = X##_e; \
218 _flo.bits.sign = X##_s; \
223 #define _FP_PACK_RAW_2_P(fs, val, X) \
225 union _FP_UNION_##fs *_flo = \
226 (union _FP_UNION_##fs *)(val); \
228 _flo->bits.frac0 = X##_f0; \
229 _flo->bits.frac1 = X##_f1; \
230 _flo->bits.exp = X##_e; \
231 _flo->bits.sign = X##_s; \
236 * Multiplication algorithms:
239 /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
241 #define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \
243 _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
245 doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
246 doit(_b_f1, _b_f0, X##_f0, Y##_f1); \
247 doit(_c_f1, _c_f0, X##_f1, Y##_f0); \
248 doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
250 __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
251 _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \
252 _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
253 _FP_FRAC_WORD_4(_z,1)); \
254 __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
255 _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \
256 _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
257 _FP_FRAC_WORD_4(_z,1)); \
259 /* Normalize since we know where the msb of the multiplicands \
260 were (bit B), we know that the msb of the of the product is \
261 at either 2B or 2B-1. */ \
262 _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
263 R##_f0 = _FP_FRAC_WORD_4(_z,0); \
264 R##_f1 = _FP_FRAC_WORD_4(_z,1); \
267 /* Given a 1W * 1W => 2W primitive, do the extended multiplication.
268 Do only 3 multiplications instead of four. This one is for machines
269 where multiplication is much more expensive than subtraction. */
271 #define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \
273 _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
277 _b_f0 = X##_f0 + X##_f1; \
278 _c1 = _b_f0 < X##_f0; \
279 _b_f1 = Y##_f0 + Y##_f1; \
280 _c2 = _b_f1 < Y##_f0; \
281 doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
282 doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \
283 doit(_c_f1, _c_f0, X##_f1, Y##_f1); \
287 __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
288 _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \
289 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \
290 __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
292 __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
294 __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
295 _FP_FRAC_WORD_4(_z,1), \
296 0, _d, _FP_FRAC_WORD_4(_z,0)); \
297 __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
298 _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \
299 __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \
301 _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \
303 /* Normalize since we know where the msb of the multiplicands \
304 were (bit B), we know that the msb of the of the product is \
305 at either 2B or 2B-1. */ \
306 _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
307 R##_f0 = _FP_FRAC_WORD_4(_z,0); \
308 R##_f1 = _FP_FRAC_WORD_4(_z,1); \
311 #define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \
313 _FP_FRAC_DECL_4(_z); \
314 _FP_W_TYPE _x[2], _y[2]; \
315 _x[0] = X##_f0; _x[1] = X##_f1; \
316 _y[0] = Y##_f0; _y[1] = Y##_f1; \
318 mpn_mul_n(_z_f, _x, _y, 2); \
320 /* Normalize since we know where the msb of the multiplicands \
321 were (bit B), we know that the msb of the of the product is \
322 at either 2B or 2B-1. */ \
323 _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \
328 /* Do at most 120x120=240 bits multiplication using double floating
329 point multiplication. This is useful if floating point
330 multiplication has much bigger throughput than integer multiply.
331 It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits
332 between 106 and 120 only.
333 Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set.
334 SETFETZ is a macro which will disable all FPU exceptions and set rounding
335 towards zero, RESETFE should optionally reset it back. */
337 #define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \
339 static const double _const[] = { \
340 /* 2^-24 */ 5.9604644775390625e-08, \
341 /* 2^-48 */ 3.5527136788005009e-15, \
342 /* 2^-72 */ 2.1175823681357508e-22, \
343 /* 2^-96 */ 1.2621774483536189e-29, \
344 /* 2^28 */ 2.68435456e+08, \
345 /* 2^4 */ 1.600000e+01, \
346 /* 2^-20 */ 9.5367431640625e-07, \
347 /* 2^-44 */ 5.6843418860808015e-14, \
348 /* 2^-68 */ 3.3881317890172014e-21, \
349 /* 2^-92 */ 2.0194839173657902e-28, \
350 /* 2^-116 */ 1.2037062152420224e-35}; \
351 double _a240, _b240, _c240, _d240, _e240, _f240, \
352 _g240, _h240, _i240, _j240, _k240; \
353 union { double d; UDItype i; } _l240, _m240, _n240, _o240, \
354 _p240, _q240, _r240, _s240; \
355 UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \
357 if (wfracbits < 106 || wfracbits > 120) \
362 _e240 = (double)(long)(X##_f0 & 0xffffff); \
363 _j240 = (double)(long)(Y##_f0 & 0xffffff); \
364 _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \
365 _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \
366 _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \
367 _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \
368 _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \
369 _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \
370 _a240 = (double)(long)(X##_f1 >> 32); \
371 _f240 = (double)(long)(Y##_f1 >> 32); \
372 _e240 *= _const[3]; \
373 _j240 *= _const[3]; \
374 _d240 *= _const[2]; \
375 _i240 *= _const[2]; \
376 _c240 *= _const[1]; \
377 _h240 *= _const[1]; \
378 _b240 *= _const[0]; \
379 _g240 *= _const[0]; \
380 _s240.d = _e240*_j240;\
381 _r240.d = _d240*_j240 + _e240*_i240;\
382 _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\
383 _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\
384 _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\
385 _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \
386 _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \
387 _l240.d = _a240*_g240 + _b240*_f240; \
388 _k240 = _a240*_f240; \
389 _r240.d += _s240.d; \
390 _q240.d += _r240.d; \
391 _p240.d += _q240.d; \
392 _o240.d += _p240.d; \
393 _n240.d += _o240.d; \
394 _m240.d += _n240.d; \
395 _l240.d += _m240.d; \
397 _s240.d -= ((_const[10]+_s240.d)-_const[10]); \
398 _r240.d -= ((_const[9]+_r240.d)-_const[9]); \
399 _q240.d -= ((_const[8]+_q240.d)-_const[8]); \
400 _p240.d -= ((_const[7]+_p240.d)-_const[7]); \
401 _o240.d += _const[7]; \
402 _n240.d += _const[6]; \
403 _m240.d += _const[5]; \
404 _l240.d += _const[4]; \
405 if (_s240.d != 0.0) _y240 = 1; \
406 if (_r240.d != 0.0) _y240 = 1; \
407 if (_q240.d != 0.0) _y240 = 1; \
408 if (_p240.d != 0.0) _y240 = 1; \
409 _t240 = (DItype)_k240; \
414 R##_f1 = (_t240 << (128 - (wfracbits - 1))) \
415 | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \
416 R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \
417 | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \
418 | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \
419 | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \
425 * Division algorithms:
428 #define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \
430 _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \
431 if (_FP_FRAC_GT_2(X, Y)) \
433 _n_f2 = X##_f1 >> 1; \
434 _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
435 _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \
445 /* Normalize, i.e. make the most significant bit of the \
446 denominator set. */ \
447 _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \
449 udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \
450 umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \
452 if (_FP_FRAC_GT_2(_m, _r)) \
455 _FP_FRAC_ADD_2(_r, Y, _r); \
456 if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
459 _FP_FRAC_ADD_2(_r, Y, _r); \
462 _FP_FRAC_DEC_2(_r, _m); \
464 if (_r_f1 == Y##_f1) \
466 /* This is a special case, not an optimization \
467 (_r/Y##_f1 would not fit into UWtype). \
468 As _r is guaranteed to be < Y, R##_f0 can be either \
469 (UWtype)-1 or (UWtype)-2. But as we know what kind \
470 of bits it is (sticky, guard, round), we don't care. \
471 We also don't care what the reminder is, because the \
472 guard bit will be set anyway. -jj */ \
477 udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \
478 umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \
480 if (_FP_FRAC_GT_2(_m, _r)) \
483 _FP_FRAC_ADD_2(_r, Y, _r); \
484 if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
487 _FP_FRAC_ADD_2(_r, Y, _r); \
490 if (!_FP_FRAC_EQ_2(_r, _m)) \
491 R##_f0 |= _FP_WORK_STICKY; \
496 #define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \
498 _FP_W_TYPE _x[4], _y[2], _z[4]; \
499 _y[0] = Y##_f0; _y[1] = Y##_f1; \
501 if (_FP_FRAC_GT_2(X, Y)) \
504 _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \
505 X##_f1 >> (_FP_W_TYPE_SIZE - \
506 (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \
507 _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \
511 _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \
512 X##_f1 >> (_FP_W_TYPE_SIZE - \
513 (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \
514 _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \
517 (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \
519 R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \
524 * Square root algorithms:
525 * We have just one right now, maybe Newton approximation
526 * should be added for those machines where division is fast.
529 #define _FP_SQRT_MEAT_2(R, S, T, X, q) \
533 T##_f1 = S##_f1 + q; \
534 if (T##_f1 <= X##_f1) \
536 S##_f1 = T##_f1 + q; \
540 _FP_FRAC_SLL_2(X, 1); \
543 q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
544 while (q != _FP_WORK_ROUND) \
546 T##_f0 = S##_f0 + q; \
548 if (T##_f1 < X##_f1 || \
549 (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \
551 S##_f0 = T##_f0 + q; \
552 S##_f1 += (T##_f0 > S##_f0); \
553 _FP_FRAC_DEC_2(X, T); \
556 _FP_FRAC_SLL_2(X, 1); \
559 if (X##_f0 | X##_f1) \
561 if (S##_f1 < X##_f1 || \
562 (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \
563 R##_f0 |= _FP_WORK_ROUND; \
564 R##_f0 |= _FP_WORK_STICKY; \
570 * Assembly/disassembly for converting to/from integral types.
571 * No shifting or overflow handled here.
574 #define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
576 if (rsize <= _FP_W_TYPE_SIZE) \
581 r <<= _FP_W_TYPE_SIZE; \
586 #define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \
589 X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
593 * Convert FP values between word sizes
596 #define _FP_FRAC_CONV_1_2(dfs, sfs, D, S) \
598 if (S##_c != FP_CLS_NAN) \
599 _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
600 _FP_WFRACBITS_##sfs); \
602 _FP_FRAC_SRL_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \
606 #define _FP_FRAC_CONV_2_1(dfs, sfs, D, S) \
610 _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \