VirtualBox

source: vbox/trunk/src/libs/softfloat-3e/testfloat/source/slowfloat.c@ 107044

Last change on this file since 107044 was 94551, checked in by vboxsync, 3 years ago

libs/softfloat: Copied TestFloat-3e from vendor branch and to testfloat subdir. bugref:9898

  • Property svn:eol-style set to native
File size: 85.1 KB
Line 
1
2/*============================================================================
3
4This C source file is part of TestFloat, Release 3e, a package of programs for
5testing the correctness of floating-point arithmetic complying with the IEEE
6Standard for Floating-Point, by John R. Hauser.
7
8Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
9University of California. All rights reserved.
10
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions are met:
13
14 1. Redistributions of source code must retain the above copyright notice,
15 this list of conditions, and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright notice,
18 this list of conditions, and the following disclaimer in the documentation
19 and/or other materials provided with the distribution.
20
21 3. Neither the name of the University nor the names of its contributors may
22 be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
26EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
28DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
29DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36=============================================================================*/
37
38#include <stdbool.h>
39#include <stdint.h>
40#include "platform.h"
41#include "uint128.h"
42#include "softfloat.h"
43#include "slowfloat.h"
44
45uint_fast8_t slowfloat_roundingMode;
46uint_fast8_t slowfloat_detectTininess;
47uint_fast8_t slowfloat_exceptionFlags;
48#ifdef EXTFLOAT80
49uint_fast8_t slow_extF80_roundingPrecision;
50#endif
51
52#ifdef FLOAT16
53union ui16_f16 { uint16_t ui; float16_t f; };
54#endif
55union ui32_f32 { uint32_t ui; float32_t f; };
56#ifdef FLOAT64
57union ui64_f64 { uint64_t ui; float64_t f; };
58#endif
59
60/*----------------------------------------------------------------------------
61*----------------------------------------------------------------------------*/
62
63struct floatX {
64 bool isNaN;
65 bool isInf;
66 bool isZero;
67 bool sign;
68 int_fast32_t exp;
69 struct uint128 sig;
70};
71
72static const struct floatX floatXNaN =
73 { true, false, false, false, 0, { 0, 0 } };
74static const struct floatX floatXPositiveZero =
75 { false, false, true, false, 0, { 0, 0 } };
76static const struct floatX floatXNegativeZero =
77 { false, false, true, true, 0, { 0, 0 } };
78
79static
80void
81 roundFloatXTo11(
82 bool isTiny, struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
83{
84 uint_fast64_t roundBits, sigX64;
85
86 sigX64 = xPtr->sig.v64;
87 roundBits = (sigX64 & UINT64_C( 0x1FFFFFFFFFFF )) | (xPtr->sig.v0 != 0);
88 if ( roundBits ) {
89 sigX64 &= UINT64_C( 0xFFFFE00000000000 );
90 if ( exact ) slowfloat_exceptionFlags |= softfloat_flag_inexact;
91 if ( isTiny ) slowfloat_exceptionFlags |= softfloat_flag_underflow;
92 switch ( roundingMode ) {
93 case softfloat_round_near_even:
94 if ( roundBits < UINT64_C( 0x100000000000 ) ) goto noIncrement;
95 if (
96 (roundBits == UINT64_C( 0x100000000000 ))
97 && !(sigX64 & UINT64_C( 0x200000000000 ))
98 ) {
99 goto noIncrement;
100 }
101 break;
102 case softfloat_round_minMag:
103 goto noIncrement;
104 case softfloat_round_min:
105 if ( !xPtr->sign ) goto noIncrement;
106 break;
107 case softfloat_round_max:
108 if ( xPtr->sign ) goto noIncrement;
109 break;
110 case softfloat_round_near_maxMag:
111 if ( roundBits < UINT64_C( 0x100000000000 ) ) goto noIncrement;
112 break;
113#ifdef FLOAT_ROUND_ODD
114 case softfloat_round_odd:
115 sigX64 |= UINT64_C( 0x200000000000 );
116 goto noIncrement;
117#endif
118 }
119 sigX64 += UINT64_C( 0x200000000000 );
120 if ( sigX64 == UINT64_C( 0x0100000000000000 ) ) {
121 ++xPtr->exp;
122 sigX64 = UINT64_C( 0x0080000000000000 );
123 }
124 noIncrement:
125 xPtr->sig.v64 = sigX64;
126 xPtr->sig.v0 = 0;
127 }
128
129}
130
131static
132void
133 roundFloatXTo24(
134 bool isTiny, struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
135{
136 uint_fast64_t sigX64;
137 uint_fast32_t roundBits;
138
139 sigX64 = xPtr->sig.v64;
140 roundBits = (uint32_t) sigX64 | (xPtr->sig.v0 != 0);
141 if ( roundBits ) {
142 sigX64 &= UINT64_C( 0xFFFFFFFF00000000 );
143 if ( exact ) slowfloat_exceptionFlags |= softfloat_flag_inexact;
144 if ( isTiny ) slowfloat_exceptionFlags |= softfloat_flag_underflow;
145 switch ( roundingMode ) {
146 case softfloat_round_near_even:
147 if ( roundBits < 0x80000000 ) goto noIncrement;
148 if (
149 (roundBits == 0x80000000)
150 && !(sigX64 & UINT64_C( 0x100000000 ))
151 ) {
152 goto noIncrement;
153 }
154 break;
155 case softfloat_round_minMag:
156 goto noIncrement;
157 case softfloat_round_min:
158 if ( !xPtr->sign ) goto noIncrement;
159 break;
160 case softfloat_round_max:
161 if ( xPtr->sign ) goto noIncrement;
162 break;
163 case softfloat_round_near_maxMag:
164 if ( roundBits < 0x80000000 ) goto noIncrement;
165 break;
166#ifdef FLOAT_ROUND_ODD
167 case softfloat_round_odd:
168 sigX64 |= UINT64_C( 0x100000000 );
169 goto noIncrement;
170#endif
171 }
172 sigX64 += UINT64_C( 0x100000000 );
173 if ( sigX64 == UINT64_C( 0x0100000000000000 ) ) {
174 ++xPtr->exp;
175 sigX64 = UINT64_C( 0x0080000000000000 );
176 }
177 noIncrement:
178 xPtr->sig.v64 = sigX64;
179 xPtr->sig.v0 = 0;
180 }
181
182}
183
184static
185void
186 roundFloatXTo53(
187 bool isTiny, struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
188{
189 uint_fast64_t sigX64;
190 uint_fast8_t roundBits;
191
192 sigX64 = xPtr->sig.v64;
193 roundBits = (sigX64 & 7) | (xPtr->sig.v0 != 0);
194 if ( roundBits ) {
195 sigX64 &= UINT64_C( 0xFFFFFFFFFFFFFFF8 );
196 if ( exact ) slowfloat_exceptionFlags |= softfloat_flag_inexact;
197 if ( isTiny ) slowfloat_exceptionFlags |= softfloat_flag_underflow;
198 switch ( roundingMode ) {
199 case softfloat_round_near_even:
200 if ( roundBits < 4 ) goto noIncrement;
201 if ( (roundBits == 4) && !(sigX64 & 8) ) goto noIncrement;
202 break;
203 case softfloat_round_minMag:
204 goto noIncrement;
205 case softfloat_round_min:
206 if ( !xPtr->sign ) goto noIncrement;
207 break;
208 case softfloat_round_max:
209 if ( xPtr->sign ) goto noIncrement;
210 break;
211 case softfloat_round_near_maxMag:
212 if ( roundBits < 4 ) goto noIncrement;
213 break;
214#ifdef FLOAT_ROUND_ODD
215 case softfloat_round_odd:
216 sigX64 |= 8;
217 goto noIncrement;
218#endif
219 }
220 sigX64 += 8;
221 if ( sigX64 == UINT64_C( 0x0100000000000000 ) ) {
222 ++xPtr->exp;
223 sigX64 = UINT64_C( 0x0080000000000000 );
224 }
225 noIncrement:
226 xPtr->sig.v64 = sigX64;
227 xPtr->sig.v0 = 0;
228 }
229
230}
231
232static
233void
234 roundFloatXTo64(
235 bool isTiny, struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
236{
237 uint_fast64_t sigX0, roundBits, sigX64;
238
239 sigX0 = xPtr->sig.v0;
240 roundBits = sigX0 & UINT64_C( 0x00FFFFFFFFFFFFFF );
241 if ( roundBits ) {
242 sigX0 &= UINT64_C( 0xFF00000000000000 );
243 if ( exact ) slowfloat_exceptionFlags |= softfloat_flag_inexact;
244 if ( isTiny ) slowfloat_exceptionFlags |= softfloat_flag_underflow;
245 switch ( roundingMode ) {
246 case softfloat_round_near_even:
247 if ( roundBits < UINT64_C( 0x0080000000000000 ) ) goto noIncrement;
248 if (
249 (roundBits == UINT64_C( 0x0080000000000000 ))
250 && !(sigX0 & UINT64_C( 0x0100000000000000 ))
251 ) {
252 goto noIncrement;
253 }
254 break;
255 case softfloat_round_minMag:
256 goto noIncrement;
257 case softfloat_round_min:
258 if ( !xPtr->sign ) goto noIncrement;
259 break;
260 case softfloat_round_max:
261 if ( xPtr->sign ) goto noIncrement;
262 break;
263 case softfloat_round_near_maxMag:
264 if ( roundBits < UINT64_C( 0x0080000000000000 ) ) goto noIncrement;
265 break;
266#ifdef FLOAT_ROUND_ODD
267 case softfloat_round_odd:
268 sigX0 |= UINT64_C( 0x100000000000000 );
269 goto noIncrement;
270#endif
271 }
272 sigX0 += UINT64_C( 0x100000000000000 );
273 sigX64 = xPtr->sig.v64 + !sigX0;
274 if ( sigX64 == UINT64_C( 0x0100000000000000 ) ) {
275 ++xPtr->exp;
276 sigX64 = UINT64_C( 0x0080000000000000 );
277 }
278 xPtr->sig.v64 = sigX64;
279 noIncrement:
280 xPtr->sig.v0 = sigX0;
281 }
282
283}
284
285static
286void
287 roundFloatXTo113(
288 bool isTiny, struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
289{
290 uint_fast64_t sigX0;
291 uint_fast8_t roundBits;
292 uint_fast64_t sigX64;
293
294 sigX0 = xPtr->sig.v0;
295 roundBits = sigX0 & 0x7F;
296 if ( roundBits ) {
297 sigX0 &= UINT64_C( 0xFFFFFFFFFFFFFF80 );
298 if ( exact ) slowfloat_exceptionFlags |= softfloat_flag_inexact;
299 if ( isTiny ) slowfloat_exceptionFlags |= softfloat_flag_underflow;
300 switch ( roundingMode ) {
301 case softfloat_round_near_even:
302 if ( roundBits < 0x40 ) goto noIncrement;
303 if ( (roundBits == 0x40) && !(sigX0 & 0x80) ) goto noIncrement;
304 break;
305 case softfloat_round_minMag:
306 goto noIncrement;
307 case softfloat_round_min:
308 if ( !xPtr->sign ) goto noIncrement;
309 break;
310 case softfloat_round_max:
311 if ( xPtr->sign ) goto noIncrement;
312 break;
313 case softfloat_round_near_maxMag:
314 if ( roundBits < 0x40 ) goto noIncrement;
315 break;
316#ifdef FLOAT_ROUND_ODD
317 case softfloat_round_odd:
318 sigX0 |= 0x80;
319 goto noIncrement;
320#endif
321 }
322 sigX0 += 0x80;
323 sigX64 = xPtr->sig.v64 + !sigX0;
324 if ( sigX64 == UINT64_C( 0x0100000000000000 ) ) {
325 ++xPtr->exp;
326 sigX64 = UINT64_C( 0x0080000000000000 );
327 }
328 xPtr->sig.v64 = sigX64;
329 noIncrement:
330 xPtr->sig.v0 = sigX0;
331 }
332
333}
334
335static void ui32ToFloatX( uint_fast32_t a, struct floatX *xPtr )
336{
337 uint_fast64_t sig64;
338 int_fast32_t exp;
339
340 xPtr->isNaN = false;
341 xPtr->isInf = false;
342 xPtr->sign = false;
343 sig64 = a;
344 if ( a ) {
345 xPtr->isZero = false;
346 exp = 31;
347 sig64 <<= 24;
348 while ( sig64 < UINT64_C( 0x0080000000000000 ) ) {
349 --exp;
350 sig64 <<= 1;
351 }
352 xPtr->exp = exp;
353 } else {
354 xPtr->isZero = true;
355 }
356 xPtr->sig.v64 = sig64;
357 xPtr->sig.v0 = 0;
358
359}
360
361static
362uint_fast32_t
363 floatXToUI32(
364 const struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
365{
366 uint_fast8_t savedExceptionFlags;
367 struct floatX x;
368 int_fast32_t shiftDist;
369 uint_fast32_t z;
370
371 if ( xPtr->isInf || xPtr->isNaN ) {
372 slowfloat_exceptionFlags |= softfloat_flag_invalid;
373 return (xPtr->isInf && xPtr->sign) ? 0 : 0xFFFFFFFF;
374 }
375 if ( xPtr->isZero ) return 0;
376 savedExceptionFlags = slowfloat_exceptionFlags;
377 x = *xPtr;
378 shiftDist = 52 - x.exp;
379 if ( 56 < shiftDist ) {
380 x.sig.v64 = 0;
381 x.sig.v0 = 1;
382 } else {
383 while ( 0 < shiftDist ) {
384 x.sig = shortShiftRightJam128( x.sig, 1 );
385 --shiftDist;
386 }
387 }
388 roundFloatXTo53( false, &x, roundingMode, exact );
389 x.sig = shortShiftRightJam128( x.sig, 3 );
390 z = x.sig.v64;
391 if ( (shiftDist < 0) || x.sig.v64>>32 || (x.sign && z) ) {
392 slowfloat_exceptionFlags =
393 savedExceptionFlags | softfloat_flag_invalid;
394 return x.sign ? 0 : 0xFFFFFFFF;
395 }
396 return z;
397
398}
399
400static void ui64ToFloatX( uint_fast64_t a, struct floatX *xPtr )
401{
402 struct uint128 sig;
403 int_fast32_t exp;
404
405 xPtr->isNaN = false;
406 xPtr->isInf = false;
407 xPtr->sign = false;
408 sig.v64 = 0;
409 sig.v0 = a;
410 if ( a ) {
411 xPtr->isZero = false;
412 exp = 63;
413 sig = shortShiftLeft128( sig, 56 );
414 while ( sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
415 --exp;
416 sig = shortShiftLeft128( sig, 1 );
417 }
418 xPtr->exp = exp;
419 } else {
420 xPtr->isZero = true;
421 }
422 xPtr->sig = sig;
423
424}
425
426static
427uint_fast64_t
428 floatXToUI64(
429 const struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
430{
431 uint_fast8_t savedExceptionFlags;
432 struct floatX x;
433 int_fast32_t shiftDist;
434 uint_fast64_t z;
435
436 if ( xPtr->isInf || xPtr->isNaN ) {
437 slowfloat_exceptionFlags |= softfloat_flag_invalid;
438 return
439 (xPtr->isInf && xPtr->sign) ? 0 : UINT64_C( 0xFFFFFFFFFFFFFFFF );
440 }
441 if ( xPtr->isZero ) return 0;
442 savedExceptionFlags = slowfloat_exceptionFlags;
443 x = *xPtr;
444 shiftDist = 112 - x.exp;
445 if ( 116 < shiftDist ) {
446 x.sig.v64 = 0;
447 x.sig.v0 = 1;
448 } else {
449 while ( 0 < shiftDist ) {
450 x.sig = shortShiftRightJam128( x.sig, 1 );
451 --shiftDist;
452 }
453 }
454 roundFloatXTo113( false, &x, roundingMode, exact );
455 x.sig = shortShiftRightJam128( x.sig, 7 );
456 z = x.sig.v0;
457 if ( (shiftDist < 0) || x.sig.v64 || (x.sign && z) ) {
458 slowfloat_exceptionFlags =
459 savedExceptionFlags | softfloat_flag_invalid;
460 return x.sign ? 0 : UINT64_C( 0xFFFFFFFFFFFFFFFF );
461 }
462 return z;
463
464}
465
466static void i32ToFloatX( int_fast32_t a, struct floatX *xPtr )
467{
468 bool sign;
469 uint_fast64_t sig64;
470 int_fast32_t exp;
471
472 xPtr->isNaN = false;
473 xPtr->isInf = false;
474 sign = (a < 0);
475 xPtr->sign = sign;
476 sig64 = sign ? -(uint64_t) a : a;
477 if ( a ) {
478 xPtr->isZero = false;
479 exp = 31;
480 sig64 <<= 24;
481 while ( sig64 < UINT64_C( 0x0080000000000000 ) ) {
482 --exp;
483 sig64 <<= 1;
484 }
485 xPtr->exp = exp;
486 } else {
487 xPtr->isZero = true;
488 }
489 xPtr->sig.v64 = sig64;
490 xPtr->sig.v0 = 0;
491
492}
493
494static
495int_fast32_t
496 floatXToI32(
497 const struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
498{
499 uint_fast8_t savedExceptionFlags;
500 struct floatX x;
501 int_fast32_t shiftDist;
502 union { uint32_t ui; int32_t i; } uZ;
503
504 if ( xPtr->isInf || xPtr->isNaN ) {
505 slowfloat_exceptionFlags |= softfloat_flag_invalid;
506 return (xPtr->isInf && xPtr->sign) ? -0x7FFFFFFF - 1 : 0x7FFFFFFF;
507 }
508 if ( xPtr->isZero ) return 0;
509 savedExceptionFlags = slowfloat_exceptionFlags;
510 x = *xPtr;
511 shiftDist = 52 - x.exp;
512 if ( 56 < shiftDist ) {
513 x.sig.v64 = 0;
514 x.sig.v0 = 1;
515 } else {
516 while ( 0 < shiftDist ) {
517 x.sig = shortShiftRightJam128( x.sig, 1 );
518 --shiftDist;
519 }
520 }
521 roundFloatXTo53( false, &x, roundingMode, exact );
522 x.sig = shortShiftRightJam128( x.sig, 3 );
523 uZ.ui = x.sig.v64;
524 if ( x.sign ) uZ.ui = -uZ.ui;
525 if (
526 (shiftDist < 0) || x.sig.v64>>32
527 || ((uZ.i != 0) && (x.sign != (uZ.i < 0)))
528 ) {
529 slowfloat_exceptionFlags =
530 savedExceptionFlags | softfloat_flag_invalid;
531 return x.sign ? -0x7FFFFFFF - 1 : 0x7FFFFFFF;
532 }
533 return uZ.i;
534
535}
536
537static void i64ToFloatX( int_fast64_t a, struct floatX *xPtr )
538{
539 bool sign;
540 struct uint128 sig;
541 int_fast32_t exp;
542
543 xPtr->isNaN = false;
544 xPtr->isInf = false;
545 sign = (a < 0);
546 xPtr->sign = sign;
547 sig.v64 = 0;
548 sig.v0 = sign ? -(uint_fast64_t) a : a;
549 if ( a ) {
550 xPtr->isZero = false;
551 exp = 63;
552 sig = shortShiftLeft128( sig, 56 );
553 while ( sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
554 --exp;
555 sig = shortShiftLeft128( sig, 1 );
556 }
557 xPtr->exp = exp;
558 } else {
559 xPtr->isZero = true;
560 }
561 xPtr->sig = sig;
562
563}
564
565static
566int_fast64_t
567 floatXToI64(
568 const struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
569{
570 uint_fast8_t savedExceptionFlags;
571 struct floatX x;
572 int_fast32_t shiftDist;
573 union { uint64_t ui; int64_t i; } uZ;
574
575 if ( xPtr->isInf || xPtr->isNaN ) {
576 slowfloat_exceptionFlags |= softfloat_flag_invalid;
577 return
578 (xPtr->isInf && xPtr->sign) ? -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1
579 : INT64_C( 0x7FFFFFFFFFFFFFFF );
580 }
581 if ( xPtr->isZero ) return 0;
582 savedExceptionFlags = slowfloat_exceptionFlags;
583 x = *xPtr;
584 shiftDist = 112 - x.exp;
585 if ( 116 < shiftDist ) {
586 x.sig.v64 = 0;
587 x.sig.v0 = 1;
588 } else {
589 while ( 0 < shiftDist ) {
590 x.sig = shortShiftRightJam128( x.sig, 1 );
591 --shiftDist;
592 }
593 }
594 roundFloatXTo113( false, &x, roundingMode, exact );
595 x.sig = shortShiftRightJam128( x.sig, 7 );
596 uZ.ui = x.sig.v0;
597 if ( x.sign ) uZ.ui = -uZ.ui;
598 if (
599 (shiftDist < 0) || x.sig.v64 || ((uZ.i != 0) && (x.sign != (uZ.i < 0)))
600 ) {
601 slowfloat_exceptionFlags =
602 savedExceptionFlags | softfloat_flag_invalid;
603 return
604 x.sign ? -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1
605 : INT64_C( 0x7FFFFFFFFFFFFFFF );
606 }
607 return uZ.i;
608
609}
610
611#ifdef FLOAT16
612
613static void f16ToFloatX( float16_t a, struct floatX *xPtr )
614{
615 union ui16_f16 uA;
616 uint_fast16_t uiA;
617 int_fast8_t exp;
618 uint_fast64_t sig64;
619
620 uA.f = a;
621 uiA = uA.ui;
622 xPtr->isNaN = false;
623 xPtr->isInf = false;
624 xPtr->isZero = false;
625 xPtr->sign = ((uiA & 0x8000) != 0);
626 exp = uiA>>10 & 0x1F;
627 sig64 = uiA & 0x03FF;
628 sig64 <<= 45;
629 if ( exp == 0x1F ) {
630 if ( sig64 ) {
631 xPtr->isNaN = true;
632 } else {
633 xPtr->isInf = true;
634 }
635 } else if ( !exp ) {
636 if ( !sig64 ) {
637 xPtr->isZero = true;
638 } else {
639 exp = 1 - 0xF;
640 do {
641 --exp;
642 sig64 <<= 1;
643 } while ( sig64 < UINT64_C( 0x0080000000000000 ) );
644 xPtr->exp = exp;
645 }
646 } else {
647 xPtr->exp = exp - 0xF;
648 sig64 |= UINT64_C( 0x0080000000000000 );
649 }
650 xPtr->sig.v64 = sig64;
651 xPtr->sig.v0 = 0;
652
653}
654
655static float16_t floatXToF16( const struct floatX *xPtr )
656{
657 uint_fast16_t uiZ;
658 struct floatX x, savedX;
659 bool isTiny;
660 int_fast32_t exp;
661 union ui16_f16 uZ;
662
663 if ( xPtr->isNaN ) {
664 uiZ = 0xFFFF;
665 goto uiZ;
666 }
667 if ( xPtr->isInf ) {
668 uiZ = xPtr->sign ? 0xFC00 : 0x7C00;
669 goto uiZ;
670 }
671 if ( xPtr->isZero ) {
672 uiZ = xPtr->sign ? 0x8000 : 0;
673 goto uiZ;
674 }
675 x = *xPtr;
676 while ( UINT64_C( 0x0100000000000000 ) <= x.sig.v64 ) {
677 ++x.exp;
678 x.sig = shortShiftRightJam128( x.sig, 1 );
679 }
680 while ( x.sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
681 --x.exp;
682 x.sig = shortShiftLeft128( x.sig, 1 );
683 }
684 savedX = x;
685 isTiny =
686 (slowfloat_detectTininess == softfloat_tininess_beforeRounding)
687 && (x.exp + 0xF <= 0);
688 roundFloatXTo11( isTiny, &x, slowfloat_roundingMode, true );
689 exp = x.exp + 0xF;
690 if ( 0x1F <= exp ) {
691 slowfloat_exceptionFlags |=
692 softfloat_flag_overflow | softfloat_flag_inexact;
693 if ( x.sign ) {
694 switch ( slowfloat_roundingMode ) {
695 case softfloat_round_near_even:
696 case softfloat_round_min:
697 case softfloat_round_near_maxMag:
698 uiZ = 0xFC00;
699 break;
700 case softfloat_round_minMag:
701 case softfloat_round_max:
702 case softfloat_round_odd:
703 uiZ = 0xFBFF;
704 break;
705 }
706 } else {
707 switch ( slowfloat_roundingMode ) {
708 case softfloat_round_near_even:
709 case softfloat_round_max:
710 case softfloat_round_near_maxMag:
711 uiZ = 0x7C00;
712 break;
713 case softfloat_round_minMag:
714 case softfloat_round_min:
715 case softfloat_round_odd:
716 uiZ = 0x7BFF;
717 break;
718 }
719 }
720 goto uiZ;
721 }
722 if ( exp <= 0 ) {
723 isTiny = true;
724 x = savedX;
725 exp = x.exp + 0xF;
726 if ( exp < -14 ) {
727 x.sig.v0 = (x.sig.v64 != 0) || (x.sig.v0 != 0);
728 x.sig.v64 = 0;
729 } else {
730 while ( exp <= 0 ) {
731 ++exp;
732 x.sig = shortShiftRightJam128( x.sig, 1 );
733 }
734 }
735 roundFloatXTo11( isTiny, &x, slowfloat_roundingMode, true );
736 exp = (UINT64_C( 0x0080000000000000 ) <= x.sig.v64) ? 1 : 0;
737 }
738 uiZ = (uint_fast16_t) exp<<10;
739 if ( x.sign ) uiZ |= 0x8000;
740 uiZ |= x.sig.v64>>45 & 0x03FF;
741 uiZ:
742 uZ.ui = uiZ;
743 return uZ.f;
744
745}
746
747#endif
748
749static void f32ToFloatX( float32_t a, struct floatX *xPtr )
750{
751 union ui32_f32 uA;
752 uint_fast32_t uiA;
753 int_fast16_t exp;
754 uint_fast64_t sig64;
755
756 uA.f = a;
757 uiA = uA.ui;
758 xPtr->isNaN = false;
759 xPtr->isInf = false;
760 xPtr->isZero = false;
761 xPtr->sign = ((uiA & 0x80000000) != 0);
762 exp = uiA>>23 & 0xFF;
763 sig64 = uiA & 0x007FFFFF;
764 sig64 <<= 32;
765 if ( exp == 0xFF ) {
766 if ( sig64 ) {
767 xPtr->isNaN = true;
768 } else {
769 xPtr->isInf = true;
770 }
771 } else if ( !exp ) {
772 if ( !sig64 ) {
773 xPtr->isZero = true;
774 } else {
775 exp = 1 - 0x7F;
776 do {
777 --exp;
778 sig64 <<= 1;
779 } while ( sig64 < UINT64_C( 0x0080000000000000 ) );
780 xPtr->exp = exp;
781 }
782 } else {
783 xPtr->exp = exp - 0x7F;
784 sig64 |= UINT64_C( 0x0080000000000000 );
785 }
786 xPtr->sig.v64 = sig64;
787 xPtr->sig.v0 = 0;
788
789}
790
791static float32_t floatXToF32( const struct floatX *xPtr )
792{
793 uint_fast32_t uiZ;
794 struct floatX x, savedX;
795 bool isTiny;
796 int_fast32_t exp;
797 union ui32_f32 uZ;
798
799 if ( xPtr->isNaN ) {
800 uiZ = 0xFFFFFFFF;
801 goto uiZ;
802 }
803 if ( xPtr->isInf ) {
804 uiZ = xPtr->sign ? 0xFF800000 : 0x7F800000;
805 goto uiZ;
806 }
807 if ( xPtr->isZero ) {
808 uiZ = xPtr->sign ? 0x80000000 : 0;
809 goto uiZ;
810 }
811 x = *xPtr;
812 while ( UINT64_C( 0x0100000000000000 ) <= x.sig.v64 ) {
813 ++x.exp;
814 x.sig = shortShiftRightJam128( x.sig, 1 );
815 }
816 while ( x.sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
817 --x.exp;
818 x.sig = shortShiftLeft128( x.sig, 1 );
819 }
820 savedX = x;
821 isTiny =
822 (slowfloat_detectTininess == softfloat_tininess_beforeRounding)
823 && (x.exp + 0x7F <= 0);
824 roundFloatXTo24( isTiny, &x, slowfloat_roundingMode, true );
825 exp = x.exp + 0x7F;
826 if ( 0xFF <= exp ) {
827 slowfloat_exceptionFlags |=
828 softfloat_flag_overflow | softfloat_flag_inexact;
829 if ( x.sign ) {
830 switch ( slowfloat_roundingMode ) {
831 case softfloat_round_near_even:
832 case softfloat_round_min:
833 case softfloat_round_near_maxMag:
834 uiZ = 0xFF800000;
835 break;
836 case softfloat_round_minMag:
837 case softfloat_round_max:
838 case softfloat_round_odd:
839 uiZ = 0xFF7FFFFF;
840 break;
841 }
842 } else {
843 switch ( slowfloat_roundingMode ) {
844 case softfloat_round_near_even:
845 case softfloat_round_max:
846 case softfloat_round_near_maxMag:
847 uiZ = 0x7F800000;
848 break;
849 case softfloat_round_minMag:
850 case softfloat_round_min:
851 case softfloat_round_odd:
852 uiZ = 0x7F7FFFFF;
853 break;
854 }
855 }
856 goto uiZ;
857 }
858 if ( exp <= 0 ) {
859 isTiny = true;
860 x = savedX;
861 exp = x.exp + 0x7F;
862 if ( exp < -27 ) {
863 x.sig.v0 = (x.sig.v64 != 0) || (x.sig.v0 != 0);
864 x.sig.v64 = 0;
865 } else {
866 while ( exp <= 0 ) {
867 ++exp;
868 x.sig = shortShiftRightJam128( x.sig, 1 );
869 }
870 }
871 roundFloatXTo24( isTiny, &x, slowfloat_roundingMode, true );
872 exp = (UINT64_C( 0x0080000000000000 ) <= x.sig.v64) ? 1 : 0;
873 }
874 uiZ = (uint_fast32_t) exp<<23;
875 if ( x.sign ) uiZ |= 0x80000000;
876 uiZ |= x.sig.v64>>32 & 0x007FFFFF;
877 uiZ:
878 uZ.ui = uiZ;
879 return uZ.f;
880
881}
882
883#ifdef FLOAT64
884
885static void f64ToFloatX( float64_t a, struct floatX *xPtr )
886{
887 union ui64_f64 uA;
888 uint_fast64_t uiA;
889 int_fast16_t exp;
890 uint_fast64_t sig64;
891
892 uA.f = a;
893 uiA = uA.ui;
894 xPtr->isNaN = false;
895 xPtr->isInf = false;
896 xPtr->isZero = false;
897 xPtr->sign = ((uiA & UINT64_C( 0x8000000000000000 )) != 0);
898 exp = uiA>>52 & 0x7FF;
899 sig64 = uiA & UINT64_C( 0x000FFFFFFFFFFFFF );
900 if ( exp == 0x7FF ) {
901 if ( sig64 ) {
902 xPtr->isNaN = true;
903 } else {
904 xPtr->isInf = true;
905 }
906 } else if ( !exp ) {
907 if ( !sig64 ) {
908 xPtr->isZero = true;
909 } else {
910 exp = 1 - 0x3FF;
911 do {
912 --exp;
913 sig64 <<= 1;
914 } while ( sig64 < UINT64_C( 0x0010000000000000 ) );
915 xPtr->exp = exp;
916 }
917 } else {
918 xPtr->exp = exp - 0x3FF;
919 sig64 |= UINT64_C( 0x0010000000000000 );
920 }
921 xPtr->sig.v64 = sig64<<3;
922 xPtr->sig.v0 = 0;
923
924}
925
926static float64_t floatXToF64( const struct floatX *xPtr )
927{
928 uint_fast64_t uiZ;
929 struct floatX x, savedX;
930 bool isTiny;
931 int_fast32_t exp;
932 union ui64_f64 uZ;
933
934 if ( xPtr->isNaN ) {
935 uiZ = UINT64_C( 0xFFFFFFFFFFFFFFFF );
936 goto uiZ;
937 }
938 if ( xPtr->isInf ) {
939 uiZ =
940 xPtr->sign ? UINT64_C( 0xFFF0000000000000 )
941 : UINT64_C( 0x7FF0000000000000 );
942 goto uiZ;
943 }
944 if ( xPtr->isZero ) {
945 uiZ = xPtr->sign ? UINT64_C( 0x8000000000000000 ) : 0;
946 goto uiZ;
947 }
948 x = *xPtr;
949 while ( UINT64_C( 0x0100000000000000 ) <= x.sig.v64 ) {
950 ++x.exp;
951 x.sig = shortShiftRightJam128( x.sig, 1 );
952 }
953 while ( x.sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
954 --x.exp;
955 x.sig = shortShiftLeft128( x.sig, 1 );
956 }
957 savedX = x;
958 isTiny =
959 (slowfloat_detectTininess == softfloat_tininess_beforeRounding)
960 && (x.exp + 0x3FF <= 0);
961 roundFloatXTo53( isTiny, &x, slowfloat_roundingMode, true );
962 exp = x.exp + 0x3FF;
963 if ( 0x7FF <= exp ) {
964 slowfloat_exceptionFlags |=
965 softfloat_flag_overflow | softfloat_flag_inexact;
966 if ( x.sign ) {
967 switch ( slowfloat_roundingMode ) {
968 case softfloat_round_near_even:
969 case softfloat_round_min:
970 case softfloat_round_near_maxMag:
971 uiZ = UINT64_C( 0xFFF0000000000000 );
972 break;
973 case softfloat_round_minMag:
974 case softfloat_round_max:
975 case softfloat_round_odd:
976 uiZ = UINT64_C( 0xFFEFFFFFFFFFFFFF );
977 break;
978 }
979 } else {
980 switch ( slowfloat_roundingMode ) {
981 case softfloat_round_near_even:
982 case softfloat_round_max:
983 case softfloat_round_near_maxMag:
984 uiZ = UINT64_C( 0x7FF0000000000000 );
985 break;
986 case softfloat_round_minMag:
987 case softfloat_round_min:
988 case softfloat_round_odd:
989 uiZ = UINT64_C( 0x7FEFFFFFFFFFFFFF );
990 break;
991 }
992 }
993 goto uiZ;
994 }
995 if ( exp <= 0 ) {
996 isTiny = true;
997 x = savedX;
998 exp = x.exp + 0x3FF;
999 if ( exp < -56 ) {
1000 x.sig.v0 = (x.sig.v64 != 0) || (x.sig.v0 != 0);
1001 x.sig.v64 = 0;
1002 } else {
1003 while ( exp <= 0 ) {
1004 ++exp;
1005 x.sig = shortShiftRightJam128( x.sig, 1 );
1006 }
1007 }
1008 roundFloatXTo53( isTiny, &x, slowfloat_roundingMode, true );
1009 exp = (UINT64_C( 0x0080000000000000 ) <= x.sig.v64) ? 1 : 0;
1010 }
1011 uiZ = (uint_fast64_t) exp<<52;
1012 if ( x.sign ) uiZ |= UINT64_C( 0x8000000000000000 );
1013 uiZ |= x.sig.v64>>3 & UINT64_C( 0x000FFFFFFFFFFFFF );
1014 uiZ:
1015 uZ.ui = uiZ;
1016 return uZ.f;
1017
1018}
1019
1020#endif
1021
1022#ifdef EXTFLOAT80
1023
1024static void extF80MToFloatX( const extFloat80_t *aPtr, struct floatX *xPtr )
1025{
1026 const struct extFloat80M *aSPtr;
1027 uint_fast16_t uiA64;
1028 int_fast32_t exp;
1029 struct uint128 sig;
1030
1031 aSPtr = (const struct extFloat80M *) aPtr;
1032 xPtr->isNaN = false;
1033 xPtr->isInf = false;
1034 xPtr->isZero = false;
1035 uiA64 = aSPtr->signExp;
1036 xPtr->sign = ((uiA64 & 0x8000) != 0);
1037 exp = uiA64 & 0x7FFF;
1038 sig.v64 = 0;
1039 sig.v0 = aSPtr->signif;
1040 if ( exp == 0x7FFF ) {
1041 if ( sig.v0 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) {
1042 xPtr->isNaN = true;
1043 } else {
1044 xPtr->isInf = true;
1045 }
1046 } else {
1047 if ( !exp ) ++exp;
1048 exp -= 0x3FFF;
1049 if ( !(sig.v0 & UINT64_C( 0x8000000000000000 )) ) {
1050 if ( !sig.v0 ) {
1051 xPtr->isZero = true;
1052 } else {
1053 do {
1054 --exp;
1055 sig.v0 <<= 1;
1056 } while ( sig.v0 < UINT64_C( 0x8000000000000000 ) );
1057 }
1058 }
1059 xPtr->exp = exp;
1060 }
1061 xPtr->sig = shortShiftLeft128( sig, 56 );
1062
1063}
1064
1065static void floatXToExtF80M( const struct floatX *xPtr, extFloat80_t *zPtr )
1066{
1067 struct extFloat80M *zSPtr;
1068 struct floatX x, savedX;
1069 bool isTiny;
1070 int_fast32_t exp;
1071 uint_fast64_t uiZ0;
1072 uint_fast16_t uiZ64;
1073
1074 zSPtr = (struct extFloat80M *) zPtr;
1075 if ( xPtr->isNaN ) {
1076 zSPtr->signExp = 0xFFFF;
1077 zSPtr->signif = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1078 return;
1079 }
1080 if ( xPtr->isInf ) {
1081 zSPtr->signExp = xPtr->sign ? 0xFFFF : 0x7FFF;
1082 zSPtr->signif = UINT64_C( 0x8000000000000000 );
1083 return;
1084 }
1085 if ( xPtr->isZero ) {
1086 zSPtr->signExp = xPtr->sign ? 0x8000 : 0;
1087 zSPtr->signif = 0;
1088 return;
1089 }
1090 x = *xPtr;
1091 while ( UINT64_C( 0x0100000000000000 ) <= x.sig.v64 ) {
1092 ++x.exp;
1093 x.sig = shortShiftRightJam128( x.sig, 1 );
1094 }
1095 while ( x.sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
1096 --x.exp;
1097 x.sig = shortShiftLeft128( x.sig, 1 );
1098 }
1099 savedX = x;
1100 isTiny =
1101 (slowfloat_detectTininess == softfloat_tininess_beforeRounding)
1102 && (x.exp + 0x3FFF <= 0);
1103 switch ( slow_extF80_roundingPrecision ) {
1104 case 32:
1105 roundFloatXTo24( isTiny, &x, slowfloat_roundingMode, true );
1106 break;
1107 case 64:
1108 roundFloatXTo53( isTiny, &x, slowfloat_roundingMode, true );
1109 break;
1110 default:
1111 roundFloatXTo64( isTiny, &x, slowfloat_roundingMode, true );
1112 break;
1113 }
1114 exp = x.exp + 0x3FFF;
1115 if ( 0x7FFF <= exp ) {
1116 slowfloat_exceptionFlags |=
1117 softfloat_flag_overflow | softfloat_flag_inexact;
1118 if ( x.sign ) {
1119 switch ( slowfloat_roundingMode ) {
1120 case softfloat_round_near_even:
1121 case softfloat_round_min:
1122 case softfloat_round_near_maxMag:
1123 zSPtr->signExp = 0xFFFF;
1124 zSPtr->signif = UINT64_C( 0x8000000000000000 );
1125 break;
1126 case softfloat_round_minMag:
1127 case softfloat_round_max:
1128 case softfloat_round_odd:
1129 switch ( slow_extF80_roundingPrecision ) {
1130 case 32:
1131 uiZ0 = UINT64_C( 0xFFFFFF0000000000 );
1132 break;
1133 case 64:
1134 uiZ0 = UINT64_C( 0xFFFFFFFFFFFFF800 );
1135 break;
1136 default:
1137 uiZ0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1138 break;
1139 }
1140 zSPtr->signExp = 0xFFFE;
1141 zSPtr->signif = uiZ0;
1142 break;
1143 }
1144 } else {
1145 switch ( slowfloat_roundingMode ) {
1146 case softfloat_round_near_even:
1147 case softfloat_round_max:
1148 case softfloat_round_near_maxMag:
1149 zSPtr->signExp = 0x7FFF;
1150 zSPtr->signif = UINT64_C( 0x8000000000000000 );
1151 break;
1152 case softfloat_round_minMag:
1153 case softfloat_round_min:
1154 case softfloat_round_odd:
1155 switch ( slow_extF80_roundingPrecision ) {
1156 case 32:
1157 uiZ0 = UINT64_C( 0xFFFFFF0000000000 );
1158 break;
1159 case 64:
1160 uiZ0 = UINT64_C( 0xFFFFFFFFFFFFF800 );
1161 break;
1162 default:
1163 uiZ0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1164 break;
1165 }
1166 zSPtr->signExp = 0x7FFE;
1167 zSPtr->signif = uiZ0;
1168 break;
1169 }
1170 }
1171 return;
1172 }
1173 if ( exp <= 0 ) {
1174 isTiny = true;
1175 x = savedX;
1176 exp = x.exp + 0x3FFF;
1177 if ( exp < -70 ) {
1178 x.sig.v0 = (x.sig.v64 != 0) || (x.sig.v0 != 0);
1179 x.sig.v64 = 0;
1180 } else {
1181 while ( exp <= 0 ) {
1182 ++exp;
1183 x.sig = shortShiftRightJam128( x.sig, 1 );
1184 }
1185 }
1186 switch ( slow_extF80_roundingPrecision ) {
1187 case 32:
1188 roundFloatXTo24( isTiny, &x, slowfloat_roundingMode, true );
1189 break;
1190 case 64:
1191 roundFloatXTo53( isTiny, &x, slowfloat_roundingMode, true );
1192 break;
1193 default:
1194 roundFloatXTo64( isTiny, &x, slowfloat_roundingMode, true );
1195 break;
1196 }
1197 exp = (UINT64_C( 0x0080000000000000 ) <= x.sig.v64) ? 1 : 0;
1198 }
1199 uiZ64 = exp;
1200 if ( x.sign ) uiZ64 |= 0x8000;
1201 zSPtr->signExp = uiZ64;
1202 zSPtr->signif = shortShiftRightJam128( x.sig, 56 ).v0;
1203
1204}
1205
1206#endif
1207
1208#ifdef FLOAT128
1209
1210static void f128MToFloatX( const float128_t *aPtr, struct floatX *xPtr )
1211{
1212 const struct uint128 *uiAPtr;
1213 uint_fast64_t uiA64;
1214 int_fast32_t exp;
1215 struct uint128 sig;
1216
1217 uiAPtr = (const struct uint128 *) aPtr;
1218 xPtr->isNaN = false;
1219 xPtr->isInf = false;
1220 xPtr->isZero = false;
1221 uiA64 = uiAPtr->v64;
1222 xPtr->sign = ((uiA64 & UINT64_C( 0x8000000000000000 )) != 0);
1223 exp = uiA64>>48 & 0x7FFF;
1224 sig.v64 = uiA64 & UINT64_C( 0x0000FFFFFFFFFFFF );
1225 sig.v0 = uiAPtr->v0;
1226 if ( exp == 0x7FFF ) {
1227 if ( sig.v64 || sig.v0 ) {
1228 xPtr->isNaN = true;
1229 } else {
1230 xPtr->isInf = true;
1231 }
1232 } else if ( !exp ) {
1233 if ( !sig.v64 && !sig.v0 ) {
1234 xPtr->isZero = true;
1235 } else {
1236 exp = 1 - 0x3FFF;
1237 do {
1238 --exp;
1239 sig = shortShiftLeft128( sig, 1 );
1240 } while ( sig.v64 < UINT64_C( 0x0001000000000000 ) );
1241 xPtr->exp = exp;
1242 }
1243 } else {
1244 xPtr->exp = exp - 0x3FFF;
1245 sig.v64 |= UINT64_C( 0x0001000000000000 );
1246 }
1247 xPtr->sig = shortShiftLeft128( sig, 7 );
1248
1249}
1250
1251static void floatXToF128M( const struct floatX *xPtr, float128_t *zPtr )
1252{
1253 struct uint128 *uiZPtr;
1254 struct floatX x, savedX;
1255 bool isTiny;
1256 int_fast32_t exp;
1257 uint_fast64_t uiZ64;
1258
1259 uiZPtr = (struct uint128 *) zPtr;
1260 if ( xPtr->isNaN ) {
1261 uiZPtr->v64 = uiZPtr->v0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1262 return;
1263 }
1264 if ( xPtr->isInf ) {
1265 uiZPtr->v64 =
1266 xPtr->sign ? UINT64_C( 0xFFFF000000000000 )
1267 : UINT64_C( 0x7FFF000000000000 );
1268 uiZPtr->v0 = 0;
1269 return;
1270 }
1271 if ( xPtr->isZero ) {
1272 uiZPtr->v64 = xPtr->sign ? UINT64_C( 0x8000000000000000 ) : 0;
1273 uiZPtr->v0 = 0;
1274 return;
1275 }
1276 x = *xPtr;
1277 while ( UINT64_C( 0x0100000000000000 ) <= x.sig.v64 ) {
1278 ++x.exp;
1279 x.sig = shortShiftRightJam128( x.sig, 1 );
1280 }
1281 while ( x.sig.v64 < UINT64_C( 0x0080000000000000 ) ) {
1282 --x.exp;
1283 x.sig = shortShiftLeft128( x.sig, 1 );
1284 }
1285 savedX = x;
1286 isTiny =
1287 (slowfloat_detectTininess == softfloat_tininess_beforeRounding)
1288 && (x.exp + 0x3FFF <= 0);
1289 roundFloatXTo113( isTiny, &x, slowfloat_roundingMode, true );
1290 exp = x.exp + 0x3FFF;
1291 if ( 0x7FFF <= exp ) {
1292 slowfloat_exceptionFlags |=
1293 softfloat_flag_overflow | softfloat_flag_inexact;
1294 if ( x.sign ) {
1295 switch ( slowfloat_roundingMode ) {
1296 case softfloat_round_near_even:
1297 case softfloat_round_min:
1298 case softfloat_round_near_maxMag:
1299 uiZPtr->v64 = UINT64_C( 0xFFFF000000000000 );
1300 uiZPtr->v0 = 0;
1301 break;
1302 case softfloat_round_minMag:
1303 case softfloat_round_max:
1304 case softfloat_round_odd:
1305 uiZPtr->v64 = UINT64_C( 0xFFFEFFFFFFFFFFFF );
1306 uiZPtr->v0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1307 break;
1308 }
1309 } else {
1310 switch ( slowfloat_roundingMode ) {
1311 case softfloat_round_near_even:
1312 case softfloat_round_max:
1313 case softfloat_round_near_maxMag:
1314 uiZPtr->v64 = UINT64_C( 0x7FFF000000000000 );
1315 uiZPtr->v0 = 0;
1316 break;
1317 case softfloat_round_minMag:
1318 case softfloat_round_min:
1319 case softfloat_round_odd:
1320 uiZPtr->v64 = UINT64_C( 0x7FFEFFFFFFFFFFFF );
1321 uiZPtr->v0 = UINT64_C( 0xFFFFFFFFFFFFFFFF );
1322 break;
1323 }
1324 }
1325 return;
1326 }
1327 if ( exp <= 0 ) {
1328 isTiny = true;
1329 x = savedX;
1330 exp = x.exp + 0x3FFF;
1331 if ( exp < -120 ) {
1332 x.sig.v0 = (x.sig.v64 != 0) || (x.sig.v0 != 0);
1333 x.sig.v64 = 0;
1334 } else {
1335 while ( exp <= 0 ) {
1336 ++exp;
1337 x.sig = shortShiftRightJam128( x.sig, 1 );
1338 }
1339 }
1340 roundFloatXTo113( isTiny, &x, slowfloat_roundingMode, true );
1341 exp = (UINT64_C( 0x0080000000000000 ) <= x.sig.v64) ? 1 : 0;
1342 }
1343 uiZ64 = (uint_fast64_t) exp<<48;
1344 if ( x.sign ) uiZ64 |= UINT64_C( 0x8000000000000000 );
1345 x.sig = shortShiftRightJam128( x.sig, 7 );
1346 uiZPtr->v64 = uiZ64 | (x.sig.v64 & UINT64_C( 0x0000FFFFFFFFFFFF ));
1347 uiZPtr->v0 = x.sig.v0;
1348
1349}
1350
1351#endif
1352
1353static void floatXInvalid( struct floatX *xPtr )
1354{
1355
1356 slowfloat_exceptionFlags |= softfloat_flag_invalid;
1357 *xPtr = floatXNaN;
1358
1359}
1360
1361static
1362void
1363 floatXRoundToInt( struct floatX *xPtr, uint_fast8_t roundingMode, bool exact )
1364{
1365 int_fast32_t exp, shiftDist;
1366 struct uint128 sig;
1367
1368 if ( xPtr->isNaN || xPtr->isInf ) return;
1369 exp = xPtr->exp;
1370 shiftDist = 112 - exp;
1371 if ( shiftDist <= 0 ) return;
1372 if ( 119 < shiftDist ) {
1373 xPtr->exp = 112;
1374 xPtr->sig.v64 = 0;
1375 xPtr->sig.v0 = !xPtr->isZero;
1376 } else {
1377 sig = xPtr->sig;
1378 while ( 0 < shiftDist ) {
1379 ++exp;
1380 sig = shortShiftRightJam128( sig, 1 );
1381 --shiftDist;
1382 }
1383 xPtr->exp = exp;
1384 xPtr->sig = sig;
1385 }
1386 roundFloatXTo113( false, xPtr, roundingMode, exact );
1387 if ( !xPtr->sig.v64 && !xPtr->sig.v0 ) xPtr->isZero = true;
1388
1389}
1390
1391static void floatXAdd( struct floatX *xPtr, const struct floatX *yPtr )
1392{
1393 int_fast32_t expX, expY, expDiff;
1394 struct uint128 sigY;
1395
1396 if ( xPtr->isNaN ) return;
1397 if ( yPtr->isNaN ) goto copyY;
1398 if ( xPtr->isInf && yPtr->isInf ) {
1399 if ( xPtr->sign != yPtr->sign ) floatXInvalid( xPtr );
1400 return;
1401 }
1402 if ( xPtr->isInf ) return;
1403 if ( yPtr->isInf ) goto copyY;
1404 if ( xPtr->isZero && yPtr->isZero ) {
1405 if ( xPtr->sign == yPtr->sign ) return;
1406 goto completeCancellation;
1407 }
1408 expX = xPtr->exp;
1409 expY = yPtr->exp;
1410 if (
1411 (xPtr->sign != yPtr->sign) && (expX == expY)
1412 && eq128( xPtr->sig, yPtr->sig )
1413 ) {
1414 completeCancellation:
1415 if (slowfloat_roundingMode == softfloat_round_min) {
1416 *xPtr = floatXNegativeZero;
1417 } else {
1418 *xPtr = floatXPositiveZero;
1419 }
1420 return;
1421 }
1422 if ( xPtr->isZero ) goto copyY;
1423 if ( yPtr->isZero ) return;
1424 expDiff = expX - expY;
1425 if ( expDiff < 0 ) {
1426 xPtr->exp = expY;
1427 if ( expDiff < -120 ) {
1428 xPtr->sig.v64 = 0;
1429 xPtr->sig.v0 = 1;
1430 } else {
1431 while ( expDiff < 0 ) {
1432 ++expDiff;
1433 xPtr->sig = shortShiftRightJam128( xPtr->sig, 1 );
1434 }
1435 }
1436 if ( xPtr->sign != yPtr->sign ) xPtr->sig = neg128( xPtr->sig );
1437 xPtr->sign = yPtr->sign;
1438 xPtr->sig = add128( xPtr->sig, yPtr->sig );
1439 } else {
1440 sigY = yPtr->sig;
1441 if ( 120 < expDiff ) {
1442 sigY.v64 = 0;
1443 sigY.v0 = 1;
1444 } else {
1445 while ( 0 < expDiff ) {
1446 --expDiff;
1447 sigY = shortShiftRightJam128( sigY, 1 );
1448 }
1449 }
1450 if ( xPtr->sign != yPtr->sign ) sigY = neg128( sigY );
1451 xPtr->sig = add128( xPtr->sig, sigY );
1452 }
1453 if ( xPtr->sig.v64 & UINT64_C( 0x8000000000000000 ) ) {
1454 xPtr->sign = !xPtr->sign;
1455 xPtr->sig = neg128( xPtr->sig );
1456 }
1457 return;
1458 copyY:
1459 *xPtr = *yPtr;
1460
1461}
1462
1463static void floatXMul( struct floatX *xPtr, const struct floatX *yPtr )
1464{
1465 struct uint128 sig;
1466 int bitNum;
1467
1468 if ( xPtr->isNaN ) return;
1469 if ( yPtr->isNaN ) {
1470 xPtr->isNaN = true;
1471 xPtr->isInf = false;
1472 xPtr->isZero = false;
1473 xPtr->sign = yPtr->sign;
1474 return;
1475 }
1476 if ( yPtr->sign ) xPtr->sign = !xPtr->sign;
1477 if ( xPtr->isInf ) {
1478 if ( yPtr->isZero ) floatXInvalid( xPtr );
1479 return;
1480 }
1481 if ( yPtr->isInf ) {
1482 if ( xPtr->isZero ) {
1483 floatXInvalid( xPtr );
1484 return;
1485 }
1486 xPtr->isInf = true;
1487 return;
1488 }
1489 if ( xPtr->isZero || yPtr->isZero ) {
1490 if ( xPtr->sign ) {
1491 *xPtr = floatXNegativeZero;
1492 } else {
1493 *xPtr = floatXPositiveZero;
1494 }
1495 return;
1496 }
1497 xPtr->exp += yPtr->exp;
1498 sig.v64 = 0;
1499 sig.v0 = 0;
1500 for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1501 sig = shortShiftRightJam128( sig, 1 );
1502 if ( xPtr->sig.v0 & 1 ) sig = add128( sig, yPtr->sig );
1503 xPtr->sig = shortShiftRight128( xPtr->sig, 1 );
1504 }
1505 if ( UINT64_C( 0x0100000000000000 ) <= sig.v64 ) {
1506 ++xPtr->exp;
1507 sig = shortShiftRightJam128( sig, 1 );
1508 }
1509 xPtr->sig = sig;
1510
1511}
1512
1513static void floatXDiv( struct floatX *xPtr, const struct floatX *yPtr )
1514{
1515 struct uint128 sig, negSigY;
1516 int bitNum;
1517
1518 if ( xPtr->isNaN ) return;
1519 if ( yPtr->isNaN ) {
1520 xPtr->isNaN = true;
1521 xPtr->isInf = false;
1522 xPtr->isZero = false;
1523 xPtr->sign = yPtr->sign;
1524 return;
1525 }
1526 if ( yPtr->sign ) xPtr->sign = !xPtr->sign;
1527 if ( xPtr->isInf ) {
1528 if ( yPtr->isInf ) floatXInvalid( xPtr );
1529 return;
1530 }
1531 if ( yPtr->isZero ) {
1532 if ( xPtr->isZero ) {
1533 floatXInvalid( xPtr );
1534 return;
1535 }
1536 slowfloat_exceptionFlags |= softfloat_flag_infinite;
1537 xPtr->isInf = true;
1538 return;
1539 }
1540 if ( xPtr->isZero || yPtr->isInf ) {
1541 if ( xPtr->sign ) {
1542 *xPtr = floatXNegativeZero;
1543 } else {
1544 *xPtr = floatXPositiveZero;
1545 }
1546 return;
1547 }
1548 xPtr->exp -= yPtr->exp + 1;
1549 sig.v64 = 0;
1550 sig.v0 = 0;
1551 negSigY = neg128( yPtr->sig );
1552 for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1553 if ( le128( yPtr->sig, xPtr->sig ) ) {
1554 sig.v0 |= 1;
1555 xPtr->sig = add128( xPtr->sig, negSigY );
1556 }
1557 xPtr->sig = shortShiftLeft128( xPtr->sig, 1 );
1558 sig = shortShiftLeft128( sig, 1 );
1559 }
1560 if ( xPtr->sig.v64 || xPtr->sig.v0 ) sig.v0 |= 1;
1561 xPtr->sig = sig;
1562
1563}
1564
1565static void floatXRem( struct floatX *xPtr, const struct floatX *yPtr )
1566{
1567 int_fast32_t expX, expY;
1568 struct uint128 sigY, negSigY;
1569 bool lastQuotientBit;
1570 struct uint128 savedSigX;
1571
1572 if ( xPtr->isNaN ) return;
1573 if ( yPtr->isNaN ) {
1574 xPtr->isNaN = true;
1575 xPtr->isInf = false;
1576 xPtr->isZero = false;
1577 xPtr->sign = yPtr->sign;
1578 return;
1579 }
1580 if ( xPtr->isInf || yPtr->isZero ) {
1581 floatXInvalid( xPtr );
1582 return;
1583 }
1584 if ( xPtr->isZero || yPtr->isInf ) return;
1585 expX = xPtr->exp;
1586 expY = yPtr->exp - 1;
1587 if ( expX < expY ) return;
1588 sigY = shortShiftLeft128( yPtr->sig, 1 );
1589 negSigY = neg128( sigY );
1590 while ( expY < expX ) {
1591 --expX;
1592 if ( le128( sigY, xPtr->sig ) ) {
1593 xPtr->sig = add128( xPtr->sig, negSigY );
1594 }
1595 xPtr->sig = shortShiftLeft128( xPtr->sig, 1 );
1596 }
1597 xPtr->exp = expX;
1598 lastQuotientBit = le128( sigY, xPtr->sig );
1599 if ( lastQuotientBit ) xPtr->sig = add128( xPtr->sig, negSigY );
1600 savedSigX = xPtr->sig;
1601 xPtr->sig = neg128( add128( xPtr->sig, negSigY ) );
1602 if ( lt128( xPtr->sig, savedSigX ) ) {
1603 xPtr->sign = !xPtr->sign;
1604 } else if ( lt128( savedSigX, xPtr->sig ) ) {
1605 goto restoreSavedSigX;
1606 } else {
1607 if ( lastQuotientBit ) {
1608 xPtr->sign = !xPtr->sign;
1609 } else {
1610 restoreSavedSigX:
1611 xPtr->sig = savedSigX;
1612 }
1613 }
1614 if ( !xPtr->sig.v64 && !xPtr->sig.v0 ) xPtr->isZero = true;
1615
1616}
1617
1618static void floatXSqrt( struct floatX *xPtr )
1619{
1620 struct uint128 sig, bitSig;
1621 int bitNum;
1622 struct uint128 savedSigX;
1623
1624 if ( xPtr->isNaN || xPtr->isZero ) return;
1625 if ( xPtr->sign ) {
1626 floatXInvalid( xPtr );
1627 return;
1628 }
1629 if ( xPtr->isInf ) return;
1630 if ( !(xPtr->exp & 1) ) xPtr->sig = shortShiftRightJam128( xPtr->sig, 1 );
1631 xPtr->exp >>= 1;
1632 sig.v64 = 0;
1633 sig.v0 = 0;
1634 bitSig.v64 = UINT64_C( 0x0080000000000000 );
1635 bitSig.v0 = 0;
1636 for ( bitNum = 0; bitNum < 120; ++bitNum ) {
1637 savedSigX = xPtr->sig;
1638 xPtr->sig = add128( xPtr->sig, neg128( sig ) );
1639 xPtr->sig = shortShiftLeft128( xPtr->sig, 1 );
1640 xPtr->sig = add128( xPtr->sig, neg128( bitSig ) );
1641 if ( xPtr->sig.v64 & UINT64_C( 0x8000000000000000 ) ) {
1642 xPtr->sig = shortShiftLeft128( savedSigX, 1 );
1643 } else {
1644 sig.v64 |= bitSig.v64;
1645 sig.v0 |= bitSig.v0;
1646 }
1647 bitSig = shortShiftRightJam128( bitSig, 1 );
1648 }
1649 if ( xPtr->sig.v64 || xPtr->sig.v0 ) sig.v0 |= 1;
1650 xPtr->sig = sig;
1651
1652}
1653
1654static bool floatXEq( const struct floatX *xPtr, const struct floatX *yPtr )
1655{
1656
1657 if ( xPtr->isNaN || yPtr->isNaN ) return false;
1658 if ( xPtr->isZero && yPtr->isZero ) return true;
1659 if ( xPtr->sign != yPtr->sign ) return false;
1660 if ( xPtr->isInf || yPtr->isInf ) return xPtr->isInf && yPtr->isInf;
1661 return ( xPtr->exp == yPtr->exp ) && eq128( xPtr->sig, yPtr->sig );
1662
1663}
1664
1665static bool floatXLe( const struct floatX *xPtr, const struct floatX *yPtr )
1666{
1667
1668 if ( xPtr->isNaN || yPtr->isNaN ) return false;
1669 if ( xPtr->isZero && yPtr->isZero ) return true;
1670 if ( xPtr->sign != yPtr->sign ) return xPtr->sign;
1671 if ( xPtr->sign ) {
1672 if ( xPtr->isInf || yPtr->isZero ) return true;
1673 if ( yPtr->isInf || xPtr->isZero ) return false;
1674 if ( yPtr->exp < xPtr->exp ) return true;
1675 if ( xPtr->exp < yPtr->exp ) return false;
1676 return le128( yPtr->sig, xPtr->sig );
1677 } else {
1678 if ( yPtr->isInf || xPtr->isZero ) return true;
1679 if ( xPtr->isInf || yPtr->isZero ) return false;
1680 if ( xPtr->exp < yPtr->exp ) return true;
1681 if ( yPtr->exp < xPtr->exp ) return false;
1682 return le128( xPtr->sig, yPtr->sig );
1683 }
1684
1685}
1686
1687static bool floatXLt( const struct floatX *xPtr, const struct floatX *yPtr )
1688{
1689
1690 if ( xPtr->isNaN || yPtr->isNaN ) return false;
1691 if ( xPtr->isZero && yPtr->isZero ) return false;
1692 if ( xPtr->sign != yPtr->sign ) return xPtr->sign;
1693 if ( xPtr->isInf && yPtr->isInf ) return false;
1694 if ( xPtr->sign ) {
1695 if ( xPtr->isInf || yPtr->isZero ) return true;
1696 if ( yPtr->isInf || xPtr->isZero ) return false;
1697 if ( yPtr->exp < xPtr->exp ) return true;
1698 if ( xPtr->exp < yPtr->exp ) return false;
1699 return lt128( yPtr->sig, xPtr->sig );
1700 } else {
1701 if ( yPtr->isInf || xPtr->isZero ) return true;
1702 if ( xPtr->isInf || yPtr->isZero ) return false;
1703 if ( xPtr->exp < yPtr->exp ) return true;
1704 if ( yPtr->exp < xPtr->exp ) return false;
1705 return lt128( xPtr->sig, yPtr->sig );
1706 }
1707
1708}
1709
1710/*----------------------------------------------------------------------------
1711*----------------------------------------------------------------------------*/
1712
1713#if defined EXTFLOAT80 || defined FLOAT128
1714
1715#ifdef LITTLEENDIAN
1716struct uint256 { uint64_t v0, v64, v128, v192; };
1717#else
1718struct uint256 { uint64_t v192, v128, v64, v0; };
1719#endif
1720
1721static bool eq256M( const struct uint256 *aPtr, const struct uint256 *bPtr )
1722{
1723
1724 return
1725 (aPtr->v192 == bPtr->v192) && (aPtr->v128 == bPtr->v128)
1726 && (aPtr->v64 == bPtr->v64) && (aPtr->v0 == bPtr->v0);
1727
1728}
1729
1730static void shiftLeft1256M( struct uint256 *ptr )
1731{
1732 uint64_t dword1, dword2;
1733
1734 dword1 = ptr->v128;
1735 ptr->v192 = ptr->v192<<1 | dword1>>63;
1736 dword2 = ptr->v64;
1737 ptr->v128 = dword1<<1 | dword2>>63;
1738 dword1 = ptr->v0;
1739 ptr->v64 = dword2<<1 | dword1>>63;
1740 ptr->v0 = dword1<<1;
1741
1742}
1743
1744static void shiftRight1256M( struct uint256 *ptr )
1745{
1746 uint64_t dword1, dword2;
1747
1748 dword1 = ptr->v64;
1749 ptr->v0 = dword1<<63 | ptr->v0>>1;
1750 dword2 = ptr->v128;
1751 ptr->v64 = dword2<<63 | dword1>>1;
1752 dword1 = ptr->v192;
1753 ptr->v128 = dword1<<63 | dword2>>1;
1754 ptr->v192 = dword1>>1;
1755
1756}
1757
1758static void shiftRight1Jam256M( struct uint256 *ptr )
1759{
1760 int extra;
1761
1762 extra = ptr->v0 & 1;
1763 shiftRight1256M( ptr );
1764 ptr->v0 |= extra;
1765
1766}
1767
1768static void neg256M( struct uint256 *ptr )
1769{
1770 uint64_t v64, v0, v128;
1771
1772 v64 = ptr->v64;
1773 v0 = ptr->v0;
1774 if ( v64 | v0 ) {
1775 ptr->v192 = ~ptr->v192;
1776 ptr->v128 = ~ptr->v128;
1777 if ( v0 ) {
1778 ptr->v64 = ~v64;
1779 ptr->v0 = -v0;
1780 } else {
1781 ptr->v64 = -v64;
1782 }
1783 } else {
1784 v128 = ptr->v128;
1785 if ( v128 ) {
1786 ptr->v192 = ~ptr->v192;
1787 ptr->v128 = -v128;
1788 } else {
1789 ptr->v192 = -ptr->v192;
1790 }
1791 }
1792
1793}
1794
1795static void add256M( struct uint256 *aPtr, const struct uint256 *bPtr )
1796{
1797 uint64_t dwordA, dwordZ;
1798 unsigned int carry1, carry2;
1799
1800 dwordA = aPtr->v0;
1801 dwordZ = dwordA + bPtr->v0;
1802 carry1 = (dwordZ < dwordA);
1803 aPtr->v0 = dwordZ;
1804 dwordA = aPtr->v64;
1805 dwordZ = dwordA + bPtr->v64;
1806 carry2 = (dwordZ < dwordA);
1807 dwordZ += carry1;
1808 carry2 += (dwordZ < carry1);
1809 aPtr->v64 = dwordZ;
1810 dwordA = aPtr->v128;
1811 dwordZ = dwordA + bPtr->v128;
1812 carry1 = (dwordZ < dwordA);
1813 dwordZ += carry2;
1814 carry1 += (dwordZ < carry2);
1815 aPtr->v128 = dwordZ;
1816 aPtr->v192 = aPtr->v192 + bPtr->v192 + carry1;
1817
1818}
1819
1820struct floatX256 {
1821 bool isNaN;
1822 bool isInf;
1823 bool isZero;
1824 bool sign;
1825 int_fast32_t exp;
1826 struct uint256 sig;
1827};
1828
1829static const struct floatX256 floatX256NaN =
1830 { true, false, false, false, 0, { 0, 0, 0, 0 } };
1831static const struct floatX256 floatX256PositiveZero =
1832 { false, false, true, false, 0, { 0, 0, 0, 0 } };
1833static const struct floatX256 floatX256NegativeZero =
1834 { false, false, true, true, 0, { 0, 0, 0, 0 } };
1835
1836#ifdef FLOAT128
1837
1838static void f128MToFloatX256( const float128_t *aPtr, struct floatX256 *xPtr )
1839{
1840 struct floatX x;
1841
1842 f128MToFloatX( aPtr, &x );
1843 xPtr->isNaN = x.isNaN;
1844 xPtr->isInf = x.isInf;
1845 xPtr->isZero = x.isZero;
1846 xPtr->sign = x.sign;
1847 xPtr->exp = x.exp;
1848 xPtr->sig.v192 = x.sig.v64;
1849 xPtr->sig.v128 = x.sig.v0;
1850 xPtr->sig.v64 = 0;
1851 xPtr->sig.v0 = 0;
1852
1853}
1854
1855static void floatX256ToF128M( const struct floatX256 *xPtr, float128_t *zPtr )
1856{
1857 struct floatX x;
1858 int_fast32_t expZ;
1859 struct uint256 sig;
1860
1861 x.isNaN = xPtr->isNaN;
1862 x.isInf = xPtr->isInf;
1863 x.isZero = xPtr->isZero;
1864 x.sign = xPtr->sign;
1865 if ( !(x.isNaN | x.isInf | x.isZero) ) {
1866 expZ = xPtr->exp;
1867 sig = xPtr->sig;
1868 while ( !sig.v192 ) {
1869 expZ -= 64;
1870 sig.v192 = sig.v128;
1871 sig.v128 = sig.v64;
1872 sig.v64 = sig.v0;
1873 sig.v0 = 0;
1874 }
1875 while ( sig.v192 < UINT64_C( 0x0100000000000000 ) ) {
1876 --expZ;
1877 shiftLeft1256M( &sig );
1878 }
1879 x.exp = expZ;
1880 x.sig.v64 = sig.v192;
1881 x.sig.v0 = sig.v128 | ((sig.v64 | sig.v0) != 0);
1882 }
1883 floatXToF128M( &x, zPtr );
1884
1885}
1886
1887#endif
1888
1889static void floatX256Invalid( struct floatX256 *xPtr )
1890{
1891
1892 slowfloat_exceptionFlags |= softfloat_flag_invalid;
1893 *xPtr = floatX256NaN;
1894
1895}
1896
1897static
1898void floatX256Add( struct floatX256 *xPtr, const struct floatX256 *yPtr )
1899{
1900 int_fast32_t expX, expY, expDiff;
1901 struct uint256 sigY;
1902
1903 if ( xPtr->isNaN ) return;
1904 if ( yPtr->isNaN ) goto copyY;
1905 if ( xPtr->isInf && yPtr->isInf ) {
1906 if ( xPtr->sign != yPtr->sign ) floatX256Invalid( xPtr );
1907 return;
1908 }
1909 if ( xPtr->isInf ) return;
1910 if ( yPtr->isInf ) goto copyY;
1911 if ( xPtr->isZero && yPtr->isZero ) {
1912 if ( xPtr->sign == yPtr->sign ) return;
1913 goto completeCancellation;
1914 }
1915 expX = xPtr->exp;
1916 expY = yPtr->exp;
1917 if (
1918 (xPtr->sign != yPtr->sign) && (expX == expY)
1919 && eq256M( &xPtr->sig, &yPtr->sig )
1920 ) {
1921 completeCancellation:
1922 if (slowfloat_roundingMode == softfloat_round_min) {
1923 *xPtr = floatX256NegativeZero;
1924 } else {
1925 *xPtr = floatX256PositiveZero;
1926 }
1927 return;
1928 }
1929 if ( xPtr->isZero ) goto copyY;
1930 if ( yPtr->isZero ) return;
1931 expDiff = expX - expY;
1932 if ( expDiff < 0 ) {
1933 xPtr->exp = expY;
1934 if ( expDiff < -248 ) {
1935 xPtr->sig.v192 = 0;
1936 xPtr->sig.v128 = 0;
1937 xPtr->sig.v64 = 0;
1938 xPtr->sig.v0 = 1;
1939 } else {
1940 while ( expDiff < 0 ) {
1941 ++expDiff;
1942 shiftRight1Jam256M( &xPtr->sig );
1943 }
1944 }
1945 if ( xPtr->sign != yPtr->sign ) neg256M( &xPtr->sig );
1946 xPtr->sign = yPtr->sign;
1947 add256M( &xPtr->sig, &yPtr->sig );
1948 } else {
1949 sigY = yPtr->sig;
1950 if ( 248 < expDiff ) {
1951 sigY.v192 = 0;
1952 sigY.v128 = 0;
1953 sigY.v64 = 0;
1954 sigY.v0 = 1;
1955 } else {
1956 while ( 0 < expDiff ) {
1957 --expDiff;
1958 shiftRight1Jam256M( &sigY );
1959 }
1960 }
1961 if ( xPtr->sign != yPtr->sign ) neg256M( &sigY );
1962 add256M( &xPtr->sig, &sigY );
1963 }
1964 if ( xPtr->sig.v192 & UINT64_C( 0x8000000000000000 ) ) {
1965 xPtr->sign = !xPtr->sign;
1966 neg256M( &xPtr->sig );
1967 }
1968 return;
1969 copyY:
1970 *xPtr = *yPtr;
1971
1972}
1973
1974static
1975void floatX256Mul( struct floatX256 *xPtr, const struct floatX256 *yPtr )
1976{
1977 struct uint256 sig;
1978 int bitNum;
1979
1980 if ( xPtr->isNaN ) return;
1981 if ( yPtr->isNaN ) {
1982 xPtr->isNaN = true;
1983 xPtr->isInf = false;
1984 xPtr->isZero = false;
1985 xPtr->sign = yPtr->sign;
1986 return;
1987 }
1988 if ( yPtr->sign ) xPtr->sign = !xPtr->sign;
1989 if ( xPtr->isInf ) {
1990 if ( yPtr->isZero ) floatX256Invalid( xPtr );
1991 return;
1992 }
1993 if ( yPtr->isInf ) {
1994 if ( xPtr->isZero ) {
1995 floatX256Invalid( xPtr );
1996 return;
1997 }
1998 xPtr->isInf = true;
1999 return;
2000 }
2001 if ( xPtr->isZero || yPtr->isZero ) {
2002 if ( xPtr->sign ) {
2003 *xPtr = floatX256NegativeZero;
2004 } else {
2005 *xPtr = floatX256PositiveZero;
2006 }
2007 return;
2008 }
2009 xPtr->exp += yPtr->exp;
2010 sig.v192 = 0;
2011 sig.v128 = 0;
2012 sig.v64 = 0;
2013 sig.v0 = 0;
2014 for ( bitNum = 0; bitNum < 248; ++bitNum ) {
2015 shiftRight1Jam256M( &sig );
2016 if ( xPtr->sig.v0 & 1 ) add256M( &sig, &yPtr->sig );
2017 shiftRight1256M( &xPtr->sig );
2018 }
2019 if ( UINT64_C( 0x0100000000000000 ) <= sig.v192 ) {
2020 ++xPtr->exp;
2021 shiftRight1Jam256M( &sig );
2022 }
2023 xPtr->sig = sig;
2024
2025}
2026
2027#endif
2028
2029/*----------------------------------------------------------------------------
2030*----------------------------------------------------------------------------*/
2031
2032#ifdef FLOAT16
2033
2034float16_t slow_ui32_to_f16( uint32_t a )
2035{
2036 struct floatX x;
2037
2038 ui32ToFloatX( a, &x );
2039 return floatXToF16( &x );
2040
2041}
2042
2043#endif
2044
2045float32_t slow_ui32_to_f32( uint32_t a )
2046{
2047 struct floatX x;
2048
2049 ui32ToFloatX( a, &x );
2050 return floatXToF32( &x );
2051
2052}
2053
2054#ifdef FLOAT64
2055
2056float64_t slow_ui32_to_f64( uint32_t a )
2057{
2058 struct floatX x;
2059
2060 ui32ToFloatX( a, &x );
2061 return floatXToF64( &x );
2062
2063}
2064
2065#endif
2066
2067#ifdef EXTFLOAT80
2068
2069void slow_ui32_to_extF80M( uint32_t a, extFloat80_t *zPtr )
2070{
2071 struct floatX x;
2072
2073 ui32ToFloatX( a, &x );
2074 floatXToExtF80M( &x, zPtr );
2075
2076}
2077
2078#endif
2079
2080#ifdef FLOAT128
2081
2082void slow_ui32_to_f128M( uint32_t a, float128_t *zPtr )
2083{
2084 struct floatX x;
2085
2086 ui32ToFloatX( a, &x );
2087 floatXToF128M( &x, zPtr );
2088
2089}
2090
2091#endif
2092
2093#ifdef FLOAT16
2094
2095float16_t slow_ui64_to_f16( uint64_t a )
2096{
2097 struct floatX x;
2098
2099 ui64ToFloatX( a, &x );
2100 return floatXToF16( &x );
2101
2102}
2103
2104#endif
2105
2106float32_t slow_ui64_to_f32( uint64_t a )
2107{
2108 struct floatX x;
2109
2110 ui64ToFloatX( a, &x );
2111 return floatXToF32( &x );
2112
2113}
2114
2115#ifdef FLOAT64
2116
2117float64_t slow_ui64_to_f64( uint64_t a )
2118{
2119 struct floatX x;
2120
2121 ui64ToFloatX( a, &x );
2122 return floatXToF64( &x );
2123
2124}
2125
2126#endif
2127
2128#ifdef EXTFLOAT80
2129
2130void slow_ui64_to_extF80M( uint64_t a, extFloat80_t *zPtr )
2131{
2132 struct floatX x;
2133
2134 ui64ToFloatX( a, &x );
2135 floatXToExtF80M( &x, zPtr );
2136
2137}
2138
2139#endif
2140
2141#ifdef FLOAT128
2142
2143void slow_ui64_to_f128M( uint64_t a, float128_t *zPtr )
2144{
2145 struct floatX x;
2146
2147 ui64ToFloatX( a, &x );
2148 floatXToF128M( &x, zPtr );
2149
2150}
2151
2152#endif
2153
2154#ifdef FLOAT16
2155
2156float16_t slow_i32_to_f16( int32_t a )
2157{
2158 struct floatX x;
2159
2160 i32ToFloatX( a, &x );
2161 return floatXToF16( &x );
2162
2163}
2164
2165#endif
2166
2167float32_t slow_i32_to_f32( int32_t a )
2168{
2169 struct floatX x;
2170
2171 i32ToFloatX( a, &x );
2172 return floatXToF32( &x );
2173
2174}
2175
2176#ifdef FLOAT64
2177
2178float64_t slow_i32_to_f64( int32_t a )
2179{
2180 struct floatX x;
2181
2182 i32ToFloatX( a, &x );
2183 return floatXToF64( &x );
2184
2185}
2186
2187#endif
2188
2189#ifdef EXTFLOAT80
2190
2191void slow_i32_to_extF80M( int32_t a, extFloat80_t *zPtr )
2192{
2193 struct floatX x;
2194
2195 i32ToFloatX( a, &x );
2196 floatXToExtF80M( &x, zPtr );
2197
2198}
2199
2200#endif
2201
2202#ifdef FLOAT128
2203
2204void slow_i32_to_f128M( int32_t a, float128_t *zPtr )
2205{
2206 struct floatX x;
2207
2208 i32ToFloatX( a, &x );
2209 floatXToF128M( &x, zPtr );
2210
2211}
2212
2213#endif
2214
2215#ifdef FLOAT16
2216
2217float16_t slow_i64_to_f16( int64_t a )
2218{
2219 struct floatX x;
2220
2221 i64ToFloatX( a, &x );
2222 return floatXToF16( &x );
2223
2224}
2225
2226#endif
2227
2228float32_t slow_i64_to_f32( int64_t a )
2229{
2230 struct floatX x;
2231
2232 i64ToFloatX( a, &x );
2233 return floatXToF32( &x );
2234
2235}
2236
2237#ifdef FLOAT64
2238
2239float64_t slow_i64_to_f64( int64_t a )
2240{
2241 struct floatX x;
2242
2243 i64ToFloatX( a, &x );
2244 return floatXToF64( &x );
2245
2246}
2247
2248#endif
2249
2250#ifdef EXTFLOAT80
2251
2252void slow_i64_to_extF80M( int64_t a, extFloat80_t *zPtr )
2253{
2254 struct floatX x;
2255
2256 i64ToFloatX( a, &x );
2257 floatXToExtF80M( &x, zPtr );
2258
2259}
2260
2261#endif
2262
2263#ifdef FLOAT128
2264
2265void slow_i64_to_f128M( int64_t a, float128_t *zPtr )
2266{
2267 struct floatX x;
2268
2269 i64ToFloatX( a, &x );
2270 floatXToF128M( &x, zPtr );
2271
2272}
2273
2274#endif
2275
2276#ifdef FLOAT16
2277
2278uint_fast32_t
2279 slow_f16_to_ui32( float16_t a, uint_fast8_t roundingMode, bool exact )
2280{
2281 struct floatX x;
2282
2283 f16ToFloatX( a, &x );
2284 return floatXToUI32( &x, roundingMode, exact );
2285
2286}
2287
2288uint_fast64_t
2289 slow_f16_to_ui64( float16_t a, uint_fast8_t roundingMode, bool exact )
2290{
2291 struct floatX x;
2292
2293 f16ToFloatX( a, &x );
2294 return floatXToUI64( &x, roundingMode, exact );
2295
2296}
2297
2298int_fast32_t
2299 slow_f16_to_i32( float16_t a, uint_fast8_t roundingMode, bool exact )
2300{
2301 struct floatX x;
2302
2303 f16ToFloatX( a, &x );
2304 return floatXToI32( &x, roundingMode, exact );
2305
2306}
2307
2308int_fast64_t
2309 slow_f16_to_i64( float16_t a, uint_fast8_t roundingMode, bool exact )
2310{
2311 struct floatX x;
2312
2313 f16ToFloatX( a, &x );
2314 return floatXToI64( &x, roundingMode, exact );
2315
2316}
2317
2318uint_fast32_t slow_f16_to_ui32_r_minMag( float16_t a, bool exact )
2319{
2320 struct floatX x;
2321
2322 f16ToFloatX( a, &x );
2323 return floatXToUI32( &x, softfloat_round_minMag, exact );
2324
2325}
2326
2327uint_fast64_t slow_f16_to_ui64_r_minMag( float16_t a, bool exact )
2328{
2329 struct floatX x;
2330
2331 f16ToFloatX( a, &x );
2332 return floatXToUI64( &x, softfloat_round_minMag, exact );
2333
2334}
2335
2336int_fast32_t slow_f16_to_i32_r_minMag( float16_t a, bool exact )
2337{
2338 struct floatX x;
2339
2340 f16ToFloatX( a, &x );
2341 return floatXToI32( &x, softfloat_round_minMag, exact );
2342
2343}
2344
2345int_fast64_t slow_f16_to_i64_r_minMag( float16_t a, bool exact )
2346{
2347 struct floatX x;
2348
2349 f16ToFloatX( a, &x );
2350 return floatXToI64( &x, softfloat_round_minMag, exact );
2351
2352}
2353
2354float32_t slow_f16_to_f32( float16_t a )
2355{
2356 struct floatX x;
2357
2358 f16ToFloatX( a, &x );
2359 return floatXToF32( &x );
2360
2361}
2362
2363#ifdef FLOAT64
2364
2365float64_t slow_f16_to_f64( float16_t a )
2366{
2367 struct floatX x;
2368
2369 f16ToFloatX( a, &x );
2370 return floatXToF64( &x );
2371
2372}
2373
2374#endif
2375
2376#ifdef EXTFLOAT80
2377
2378void slow_f16_to_extF80M( float16_t a, extFloat80_t *zPtr )
2379{
2380 struct floatX x;
2381
2382 f16ToFloatX( a, &x );
2383 floatXToExtF80M( &x, zPtr );
2384
2385}
2386
2387#endif
2388
2389#ifdef FLOAT128
2390
2391void slow_f16_to_f128M( float16_t a, float128_t *zPtr )
2392{
2393 struct floatX x;
2394
2395 f16ToFloatX( a, &x );
2396 floatXToF128M( &x, zPtr );
2397
2398}
2399
2400#endif
2401
2402float16_t
2403 slow_f16_roundToInt( float16_t a, uint_fast8_t roundingMode, bool exact )
2404{
2405 struct floatX x;
2406
2407 f16ToFloatX( a, &x );
2408 floatXRoundToInt( &x, roundingMode, exact );
2409 return floatXToF16( &x );
2410
2411}
2412
2413float16_t slow_f16_add( float16_t a, float16_t b )
2414{
2415 struct floatX x, y;
2416
2417 f16ToFloatX( a, &x );
2418 f16ToFloatX( b, &y );
2419 floatXAdd( &x, &y );
2420 return floatXToF16( &x );
2421
2422}
2423
2424float16_t slow_f16_sub( float16_t a, float16_t b )
2425{
2426 struct floatX x, y;
2427
2428 f16ToFloatX( a, &x );
2429 f16ToFloatX( b, &y );
2430 y.sign = !y.sign;
2431 floatXAdd( &x, &y );
2432 return floatXToF16( &x );
2433
2434
2435}
2436
2437float16_t slow_f16_mul( float16_t a, float16_t b )
2438{
2439 struct floatX x, y;
2440
2441 f16ToFloatX( a, &x );
2442 f16ToFloatX( b, &y );
2443 floatXMul( &x, &y );
2444 return floatXToF16( &x );
2445
2446}
2447
2448float16_t slow_f16_mulAdd( float16_t a, float16_t b, float16_t c )
2449{
2450 struct floatX x, y;
2451
2452 f16ToFloatX( a, &x );
2453 f16ToFloatX( b, &y );
2454 floatXMul( &x, &y );
2455 f16ToFloatX( c, &y );
2456 floatXAdd( &x, &y );
2457 return floatXToF16( &x );
2458
2459}
2460
2461float16_t slow_f16_div( float16_t a, float16_t b )
2462{
2463 struct floatX x, y;
2464
2465 f16ToFloatX( a, &x );
2466 f16ToFloatX( b, &y );
2467 floatXDiv( &x, &y );
2468 return floatXToF16( &x );
2469
2470}
2471
2472float16_t slow_f16_rem( float16_t a, float16_t b )
2473{
2474 struct floatX x, y;
2475
2476 f16ToFloatX( a, &x );
2477 f16ToFloatX( b, &y );
2478 floatXRem( &x, &y );
2479 return floatXToF16( &x );
2480
2481}
2482
2483float16_t slow_f16_sqrt( float16_t a )
2484{
2485 struct floatX x;
2486
2487 f16ToFloatX( a, &x );
2488 floatXSqrt( &x );
2489 return floatXToF16( &x );
2490
2491}
2492
2493bool slow_f16_eq( float16_t a, float16_t b )
2494{
2495 struct floatX x, y;
2496
2497 f16ToFloatX( a, &x );
2498 f16ToFloatX( b, &y );
2499 return floatXEq( &x, &y );
2500
2501}
2502
2503bool slow_f16_le( float16_t a, float16_t b )
2504{
2505 struct floatX x, y;
2506
2507 f16ToFloatX( a, &x );
2508 f16ToFloatX( b, &y );
2509 if ( x.isNaN || y.isNaN ) {
2510 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2511 }
2512 return floatXLe( &x, &y );
2513
2514}
2515
2516bool slow_f16_lt( float16_t a, float16_t b )
2517{
2518 struct floatX x, y;
2519
2520 f16ToFloatX( a, &x );
2521 f16ToFloatX( b, &y );
2522 if ( x.isNaN || y.isNaN ) {
2523 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2524 }
2525 return floatXLt( &x, &y );
2526
2527}
2528
2529bool slow_f16_eq_signaling( float16_t a, float16_t b )
2530{
2531 struct floatX x, y;
2532
2533 f16ToFloatX( a, &x );
2534 f16ToFloatX( b, &y );
2535 if ( x.isNaN || y.isNaN ) {
2536 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2537 }
2538 return floatXEq( &x, &y );
2539
2540}
2541
2542bool slow_f16_le_quiet( float16_t a, float16_t b )
2543{
2544 struct floatX x, y;
2545
2546 f16ToFloatX( a, &x );
2547 f16ToFloatX( b, &y );
2548 return floatXLe( &x, &y );
2549
2550}
2551
2552bool slow_f16_lt_quiet( float16_t a, float16_t b )
2553{
2554 struct floatX x, y;
2555
2556 f16ToFloatX( a, &x );
2557 f16ToFloatX( b, &y );
2558 return floatXLt( &x, &y );
2559
2560}
2561
2562#endif
2563
2564uint_fast32_t
2565 slow_f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact )
2566{
2567 struct floatX x;
2568
2569 f32ToFloatX( a, &x );
2570 return floatXToUI32( &x, roundingMode, exact );
2571
2572}
2573
2574uint_fast64_t
2575 slow_f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact )
2576{
2577 struct floatX x;
2578
2579 f32ToFloatX( a, &x );
2580 return floatXToUI64( &x, roundingMode, exact );
2581
2582}
2583
2584int_fast32_t
2585 slow_f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact )
2586{
2587 struct floatX x;
2588
2589 f32ToFloatX( a, &x );
2590 return floatXToI32( &x, roundingMode, exact );
2591
2592}
2593
2594int_fast64_t
2595 slow_f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact )
2596{
2597 struct floatX x;
2598
2599 f32ToFloatX( a, &x );
2600 return floatXToI64( &x, roundingMode, exact );
2601
2602}
2603
2604uint_fast32_t slow_f32_to_ui32_r_minMag( float32_t a, bool exact )
2605{
2606 struct floatX x;
2607
2608 f32ToFloatX( a, &x );
2609 return floatXToUI32( &x, softfloat_round_minMag, exact );
2610
2611}
2612
2613uint_fast64_t slow_f32_to_ui64_r_minMag( float32_t a, bool exact )
2614{
2615 struct floatX x;
2616
2617 f32ToFloatX( a, &x );
2618 return floatXToUI64( &x, softfloat_round_minMag, exact );
2619
2620}
2621
2622int_fast32_t slow_f32_to_i32_r_minMag( float32_t a, bool exact )
2623{
2624 struct floatX x;
2625
2626 f32ToFloatX( a, &x );
2627 return floatXToI32( &x, softfloat_round_minMag, exact );
2628
2629}
2630
2631int_fast64_t slow_f32_to_i64_r_minMag( float32_t a, bool exact )
2632{
2633 struct floatX x;
2634
2635 f32ToFloatX( a, &x );
2636 return floatXToI64( &x, softfloat_round_minMag, exact );
2637
2638}
2639
2640#ifdef FLOAT16
2641
2642float16_t slow_f32_to_f16( float32_t a )
2643{
2644 struct floatX x;
2645
2646 f32ToFloatX( a, &x );
2647 return floatXToF16( &x );
2648
2649}
2650
2651#endif
2652
2653#ifdef FLOAT64
2654
2655float64_t slow_f32_to_f64( float32_t a )
2656{
2657 struct floatX x;
2658
2659 f32ToFloatX( a, &x );
2660 return floatXToF64( &x );
2661
2662}
2663
2664#endif
2665
2666#ifdef EXTFLOAT80
2667
2668void slow_f32_to_extF80M( float32_t a, extFloat80_t *zPtr )
2669{
2670 struct floatX x;
2671
2672 f32ToFloatX( a, &x );
2673 floatXToExtF80M( &x, zPtr );
2674
2675}
2676
2677#endif
2678
2679#ifdef FLOAT128
2680
2681void slow_f32_to_f128M( float32_t a, float128_t *zPtr )
2682{
2683 struct floatX x;
2684
2685 f32ToFloatX( a, &x );
2686 floatXToF128M( &x, zPtr );
2687
2688}
2689
2690#endif
2691
2692float32_t
2693 slow_f32_roundToInt( float32_t a, uint_fast8_t roundingMode, bool exact )
2694{
2695 struct floatX x;
2696
2697 f32ToFloatX( a, &x );
2698 floatXRoundToInt( &x, roundingMode, exact );
2699 return floatXToF32( &x );
2700
2701}
2702
2703float32_t slow_f32_add( float32_t a, float32_t b )
2704{
2705 struct floatX x, y;
2706
2707 f32ToFloatX( a, &x );
2708 f32ToFloatX( b, &y );
2709 floatXAdd( &x, &y );
2710 return floatXToF32( &x );
2711
2712}
2713
2714float32_t slow_f32_sub( float32_t a, float32_t b )
2715{
2716 struct floatX x, y;
2717
2718 f32ToFloatX( a, &x );
2719 f32ToFloatX( b, &y );
2720 y.sign = !y.sign;
2721 floatXAdd( &x, &y );
2722 return floatXToF32( &x );
2723
2724
2725}
2726
2727float32_t slow_f32_mul( float32_t a, float32_t b )
2728{
2729 struct floatX x, y;
2730
2731 f32ToFloatX( a, &x );
2732 f32ToFloatX( b, &y );
2733 floatXMul( &x, &y );
2734 return floatXToF32( &x );
2735
2736}
2737
2738float32_t slow_f32_mulAdd( float32_t a, float32_t b, float32_t c )
2739{
2740 struct floatX x, y;
2741
2742 f32ToFloatX( a, &x );
2743 f32ToFloatX( b, &y );
2744 floatXMul( &x, &y );
2745 f32ToFloatX( c, &y );
2746 floatXAdd( &x, &y );
2747 return floatXToF32( &x );
2748
2749}
2750
2751float32_t slow_f32_div( float32_t a, float32_t b )
2752{
2753 struct floatX x, y;
2754
2755 f32ToFloatX( a, &x );
2756 f32ToFloatX( b, &y );
2757 floatXDiv( &x, &y );
2758 return floatXToF32( &x );
2759
2760}
2761
2762float32_t slow_f32_rem( float32_t a, float32_t b )
2763{
2764 struct floatX x, y;
2765
2766 f32ToFloatX( a, &x );
2767 f32ToFloatX( b, &y );
2768 floatXRem( &x, &y );
2769 return floatXToF32( &x );
2770
2771}
2772
2773float32_t slow_f32_sqrt( float32_t a )
2774{
2775 struct floatX x;
2776
2777 f32ToFloatX( a, &x );
2778 floatXSqrt( &x );
2779 return floatXToF32( &x );
2780
2781}
2782
2783bool slow_f32_eq( float32_t a, float32_t b )
2784{
2785 struct floatX x, y;
2786
2787 f32ToFloatX( a, &x );
2788 f32ToFloatX( b, &y );
2789 return floatXEq( &x, &y );
2790
2791}
2792
2793bool slow_f32_le( float32_t a, float32_t b )
2794{
2795 struct floatX x, y;
2796
2797 f32ToFloatX( a, &x );
2798 f32ToFloatX( b, &y );
2799 if ( x.isNaN || y.isNaN ) {
2800 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2801 }
2802 return floatXLe( &x, &y );
2803
2804}
2805
2806bool slow_f32_lt( float32_t a, float32_t b )
2807{
2808 struct floatX x, y;
2809
2810 f32ToFloatX( a, &x );
2811 f32ToFloatX( b, &y );
2812 if ( x.isNaN || y.isNaN ) {
2813 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2814 }
2815 return floatXLt( &x, &y );
2816
2817}
2818
2819bool slow_f32_eq_signaling( float32_t a, float32_t b )
2820{
2821 struct floatX x, y;
2822
2823 f32ToFloatX( a, &x );
2824 f32ToFloatX( b, &y );
2825 if ( x.isNaN || y.isNaN ) {
2826 slowfloat_exceptionFlags |= softfloat_flag_invalid;
2827 }
2828 return floatXEq( &x, &y );
2829
2830}
2831
2832bool slow_f32_le_quiet( float32_t a, float32_t b )
2833{
2834 struct floatX x, y;
2835
2836 f32ToFloatX( a, &x );
2837 f32ToFloatX( b, &y );
2838 return floatXLe( &x, &y );
2839
2840}
2841
2842bool slow_f32_lt_quiet( float32_t a, float32_t b )
2843{
2844 struct floatX x, y;
2845
2846 f32ToFloatX( a, &x );
2847 f32ToFloatX( b, &y );
2848 return floatXLt( &x, &y );
2849
2850}
2851
2852#ifdef FLOAT64
2853
2854uint_fast32_t
2855 slow_f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact )
2856{
2857 struct floatX x;
2858
2859 f64ToFloatX( a, &x );
2860 return floatXToUI32( &x, roundingMode, exact );
2861
2862}
2863
2864uint_fast64_t
2865 slow_f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact )
2866{
2867 struct floatX x;
2868
2869 f64ToFloatX( a, &x );
2870 return floatXToUI64( &x, roundingMode, exact );
2871
2872}
2873
2874int_fast32_t
2875 slow_f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact )
2876{
2877 struct floatX x;
2878
2879 f64ToFloatX( a, &x );
2880 return floatXToI32( &x, roundingMode, exact );
2881
2882}
2883
2884int_fast64_t
2885 slow_f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact )
2886{
2887 struct floatX x;
2888
2889 f64ToFloatX( a, &x );
2890 return floatXToI64( &x, roundingMode, exact );
2891
2892}
2893
2894uint_fast32_t slow_f64_to_ui32_r_minMag( float64_t a, bool exact )
2895{
2896 struct floatX x;
2897
2898 f64ToFloatX( a, &x );
2899 return floatXToUI32( &x, softfloat_round_minMag, exact );
2900
2901}
2902
2903uint_fast64_t slow_f64_to_ui64_r_minMag( float64_t a, bool exact )
2904{
2905 struct floatX x;
2906
2907 f64ToFloatX( a, &x );
2908 return floatXToUI64( &x, softfloat_round_minMag, exact );
2909
2910}
2911
2912int_fast32_t slow_f64_to_i32_r_minMag( float64_t a, bool exact )
2913{
2914 struct floatX x;
2915
2916 f64ToFloatX( a, &x );
2917 return floatXToI32( &x, softfloat_round_minMag, exact );
2918
2919}
2920
2921int_fast64_t slow_f64_to_i64_r_minMag( float64_t a, bool exact )
2922{
2923 struct floatX x;
2924
2925 f64ToFloatX( a, &x );
2926 return floatXToI64( &x, softfloat_round_minMag, exact );
2927
2928}
2929
2930#ifdef FLOAT16
2931
2932float16_t slow_f64_to_f16( float64_t a )
2933{
2934 struct floatX x;
2935
2936 f64ToFloatX( a, &x );
2937 return floatXToF16( &x );
2938
2939}
2940
2941#endif
2942
2943float32_t slow_f64_to_f32( float64_t a )
2944{
2945 struct floatX x;
2946
2947 f64ToFloatX( a, &x );
2948 return floatXToF32( &x );
2949
2950}
2951
2952#ifdef EXTFLOAT80
2953
2954void slow_f64_to_extF80M( float64_t a, extFloat80_t *zPtr )
2955{
2956 struct floatX x;
2957
2958 f64ToFloatX( a, &x );
2959 floatXToExtF80M( &x, zPtr );
2960
2961}
2962
2963#endif
2964
2965#ifdef FLOAT128
2966
2967void slow_f64_to_f128M( float64_t a, float128_t *zPtr )
2968{
2969 struct floatX x;
2970
2971 f64ToFloatX( a, &x );
2972 floatXToF128M( &x, zPtr );
2973
2974}
2975
2976#endif
2977
2978float64_t
2979 slow_f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact )
2980{
2981 struct floatX x;
2982
2983 f64ToFloatX( a, &x );
2984 floatXRoundToInt( &x, roundingMode, exact );
2985 return floatXToF64( &x );
2986
2987}
2988
2989float64_t slow_f64_add( float64_t a, float64_t b )
2990{
2991 struct floatX x, y;
2992
2993 f64ToFloatX( a, &x );
2994 f64ToFloatX( b, &y );
2995 floatXAdd( &x, &y );
2996 return floatXToF64( &x );
2997
2998}
2999
3000float64_t slow_f64_sub( float64_t a, float64_t b )
3001{
3002 struct floatX x, y;
3003
3004 f64ToFloatX( a, &x );
3005 f64ToFloatX( b, &y );
3006 y.sign = !y.sign;
3007 floatXAdd( &x, &y );
3008 return floatXToF64( &x );
3009
3010}
3011
3012float64_t slow_f64_mul( float64_t a, float64_t b )
3013{
3014 struct floatX x, y;
3015
3016 f64ToFloatX( a, &x );
3017 f64ToFloatX( b, &y );
3018 floatXMul( &x, &y );
3019 return floatXToF64( &x );
3020
3021}
3022
3023float64_t slow_f64_mulAdd( float64_t a, float64_t b, float64_t c )
3024{
3025 struct floatX x, y;
3026
3027 f64ToFloatX( a, &x );
3028 f64ToFloatX( b, &y );
3029 floatXMul( &x, &y );
3030 f64ToFloatX( c, &y );
3031 floatXAdd( &x, &y );
3032 return floatXToF64( &x );
3033
3034}
3035
3036float64_t slow_f64_div( float64_t a, float64_t b )
3037{
3038 struct floatX x, y;
3039
3040 f64ToFloatX( a, &x );
3041 f64ToFloatX( b, &y );
3042 floatXDiv( &x, &y );
3043 return floatXToF64( &x );
3044
3045}
3046
3047float64_t slow_f64_rem( float64_t a, float64_t b )
3048{
3049 struct floatX x, y;
3050
3051 f64ToFloatX( a, &x );
3052 f64ToFloatX( b, &y );
3053 floatXRem( &x, &y );
3054 return floatXToF64( &x );
3055
3056}
3057
3058float64_t slow_f64_sqrt( float64_t a )
3059{
3060 struct floatX x;
3061
3062 f64ToFloatX( a, &x );
3063 floatXSqrt( &x );
3064 return floatXToF64( &x );
3065
3066}
3067
3068bool slow_f64_eq( float64_t a, float64_t b )
3069{
3070 struct floatX x, y;
3071
3072 f64ToFloatX( a, &x );
3073 f64ToFloatX( b, &y );
3074 return floatXEq( &x, &y );
3075
3076}
3077
3078bool slow_f64_le( float64_t a, float64_t b )
3079{
3080 struct floatX x, y;
3081
3082 f64ToFloatX( a, &x );
3083 f64ToFloatX( b, &y );
3084 if ( x.isNaN || y.isNaN ) {
3085 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3086 }
3087 return floatXLe( &x, &y );
3088
3089}
3090
3091bool slow_f64_lt( float64_t a, float64_t b )
3092{
3093 struct floatX x, y;
3094
3095 f64ToFloatX( a, &x );
3096 f64ToFloatX( b, &y );
3097 if ( x.isNaN || y.isNaN ) {
3098 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3099 }
3100 return floatXLt( &x, &y );
3101
3102}
3103
3104bool slow_f64_eq_signaling( float64_t a, float64_t b )
3105{
3106 struct floatX x, y;
3107
3108 f64ToFloatX( a, &x );
3109 f64ToFloatX( b, &y );
3110 if ( x.isNaN || y.isNaN ) {
3111 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3112 }
3113 return floatXEq( &x, &y );
3114
3115}
3116
3117bool slow_f64_le_quiet( float64_t a, float64_t b )
3118{
3119 struct floatX x, y;
3120
3121 f64ToFloatX( a, &x );
3122 f64ToFloatX( b, &y );
3123 return floatXLe( &x, &y );
3124
3125}
3126
3127bool slow_f64_lt_quiet( float64_t a, float64_t b )
3128{
3129 struct floatX x, y;
3130
3131 f64ToFloatX( a, &x );
3132 f64ToFloatX( b, &y );
3133 return floatXLt( &x, &y );
3134
3135}
3136
3137#endif
3138
3139#ifdef EXTFLOAT80
3140
3141uint_fast32_t
3142 slow_extF80M_to_ui32(
3143 const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact )
3144{
3145 struct floatX x;
3146
3147 extF80MToFloatX( aPtr, &x );
3148 return floatXToUI32( &x, roundingMode, exact );
3149
3150}
3151
3152uint_fast64_t
3153 slow_extF80M_to_ui64(
3154 const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact )
3155{
3156 struct floatX x;
3157
3158 extF80MToFloatX( aPtr, &x );
3159 return floatXToUI64( &x, roundingMode, exact );
3160
3161}
3162
3163int_fast32_t
3164 slow_extF80M_to_i32(
3165 const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact )
3166{
3167 struct floatX x;
3168
3169 extF80MToFloatX( aPtr, &x );
3170 return floatXToI32( &x, roundingMode, exact );
3171
3172}
3173
3174int_fast64_t
3175 slow_extF80M_to_i64(
3176 const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact )
3177{
3178 struct floatX x;
3179
3180 extF80MToFloatX( aPtr, &x );
3181 return floatXToI64( &x, roundingMode, exact );
3182
3183}
3184
3185uint_fast32_t
3186 slow_extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact )
3187{
3188 struct floatX x;
3189
3190 extF80MToFloatX( aPtr, &x );
3191 return floatXToUI32( &x, softfloat_round_minMag, exact );
3192
3193}
3194
3195uint_fast64_t
3196 slow_extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact )
3197{
3198 struct floatX x;
3199
3200 extF80MToFloatX( aPtr, &x );
3201 return floatXToUI64( &x, softfloat_round_minMag, exact );
3202
3203}
3204
3205int_fast32_t
3206 slow_extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact )
3207{
3208 struct floatX x;
3209
3210 extF80MToFloatX( aPtr, &x );
3211 return floatXToI32( &x, softfloat_round_minMag, exact );
3212
3213}
3214
3215int_fast64_t
3216 slow_extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact )
3217{
3218 struct floatX x;
3219
3220 extF80MToFloatX( aPtr, &x );
3221 return floatXToI64( &x, softfloat_round_minMag, exact );
3222
3223}
3224
3225#ifdef FLOAT16
3226
3227float16_t slow_extF80M_to_f16( const extFloat80_t *aPtr )
3228{
3229 struct floatX x;
3230
3231 extF80MToFloatX( aPtr, &x );
3232 return floatXToF16( &x );
3233
3234}
3235
3236#endif
3237
3238float32_t slow_extF80M_to_f32( const extFloat80_t *aPtr )
3239{
3240 struct floatX x;
3241
3242 extF80MToFloatX( aPtr, &x );
3243 return floatXToF32( &x );
3244
3245}
3246
3247#ifdef FLOAT64
3248
3249float64_t slow_extF80M_to_f64( const extFloat80_t *aPtr )
3250{
3251 struct floatX x;
3252
3253 extF80MToFloatX( aPtr, &x );
3254 return floatXToF64( &x );
3255
3256}
3257
3258#endif
3259
3260#ifdef FLOAT128
3261
3262void slow_extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *zPtr )
3263{
3264 struct floatX x;
3265
3266 extF80MToFloatX( aPtr, &x );
3267 floatXToF128M( &x, zPtr );
3268
3269}
3270
3271#endif
3272
3273void
3274 slow_extF80M_roundToInt(
3275 const extFloat80_t *aPtr,
3276 uint_fast8_t roundingMode,
3277 bool exact,
3278 extFloat80_t *zPtr
3279 )
3280{
3281 struct floatX x;
3282
3283 extF80MToFloatX( aPtr, &x );
3284 floatXRoundToInt( &x, roundingMode, exact );
3285 floatXToExtF80M( &x, zPtr );
3286
3287}
3288
3289void
3290 slow_extF80M_add(
3291 const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr )
3292{
3293 struct floatX x, y;
3294
3295 extF80MToFloatX( aPtr, &x );
3296 extF80MToFloatX( bPtr, &y );
3297 floatXAdd( &x, &y );
3298 floatXToExtF80M( &x, zPtr );
3299
3300}
3301
3302void
3303 slow_extF80M_sub(
3304 const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr )
3305{
3306 struct floatX x, y;
3307
3308 extF80MToFloatX( aPtr, &x );
3309 extF80MToFloatX( bPtr, &y );
3310 y.sign = !y.sign;
3311 floatXAdd( &x, &y );
3312 floatXToExtF80M( &x, zPtr );
3313
3314}
3315
3316void
3317 slow_extF80M_mul(
3318 const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr )
3319{
3320 struct floatX x, y;
3321
3322 extF80MToFloatX( aPtr, &x );
3323 extF80MToFloatX( bPtr, &y );
3324 floatXMul( &x, &y );
3325 floatXToExtF80M( &x, zPtr );
3326
3327}
3328
3329void
3330 slow_extF80M_div(
3331 const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr )
3332{
3333 struct floatX x, y;
3334
3335 extF80MToFloatX( aPtr, &x );
3336 extF80MToFloatX( bPtr, &y );
3337 floatXDiv( &x, &y );
3338 floatXToExtF80M( &x, zPtr );
3339
3340}
3341
3342void
3343 slow_extF80M_rem(
3344 const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr )
3345{
3346 struct floatX x, y;
3347
3348 extF80MToFloatX( aPtr, &x );
3349 extF80MToFloatX( bPtr, &y );
3350 floatXRem( &x, &y );
3351 floatXToExtF80M( &x, zPtr );
3352
3353}
3354
3355void slow_extF80M_sqrt( const extFloat80_t *aPtr, extFloat80_t *zPtr )
3356{
3357 struct floatX x;
3358
3359 extF80MToFloatX( aPtr, &x );
3360 floatXSqrt( &x );
3361 floatXToExtF80M( &x, zPtr );
3362
3363}
3364
3365bool slow_extF80M_eq( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3366{
3367 struct floatX x, y;
3368
3369 extF80MToFloatX( aPtr, &x );
3370 extF80MToFloatX( bPtr, &y );
3371 return floatXEq( &x, &y );
3372
3373}
3374
3375bool slow_extF80M_le( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3376{
3377 struct floatX x, y;
3378
3379 extF80MToFloatX( aPtr, &x );
3380 extF80MToFloatX( bPtr, &y );
3381 if ( x.isNaN || y.isNaN ) {
3382 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3383 }
3384 return floatXLe( &x, &y );
3385
3386}
3387
3388bool slow_extF80M_lt( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3389{
3390 struct floatX x, y;
3391
3392 extF80MToFloatX( aPtr, &x );
3393 extF80MToFloatX( bPtr, &y );
3394 if ( x.isNaN || y.isNaN ) {
3395 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3396 }
3397 return floatXLt( &x, &y );
3398
3399}
3400
3401bool
3402 slow_extF80M_eq_signaling(
3403 const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3404{
3405 struct floatX x, y;
3406
3407 extF80MToFloatX( aPtr, &x );
3408 extF80MToFloatX( bPtr, &y );
3409 if ( x.isNaN || y.isNaN ) {
3410 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3411 }
3412 return floatXEq( &x, &y );
3413
3414}
3415
3416bool slow_extF80M_le_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3417{
3418 struct floatX x, y;
3419
3420 extF80MToFloatX( aPtr, &x );
3421 extF80MToFloatX( bPtr, &y );
3422 return floatXLe( &x, &y );
3423
3424}
3425
3426bool slow_extF80M_lt_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr )
3427{
3428 struct floatX x, y;
3429
3430 extF80MToFloatX( aPtr, &x );
3431 extF80MToFloatX( bPtr, &y );
3432 return floatXLt( &x, &y );
3433
3434}
3435
3436#endif
3437
3438#ifdef FLOAT128
3439
3440uint_fast32_t
3441 slow_f128M_to_ui32(
3442 const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
3443{
3444 struct floatX x;
3445
3446 f128MToFloatX( aPtr, &x );
3447 return floatXToUI32( &x, roundingMode, exact );
3448
3449}
3450
3451uint_fast64_t
3452 slow_f128M_to_ui64(
3453 const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
3454{
3455 struct floatX x;
3456
3457 f128MToFloatX( aPtr, &x );
3458 return floatXToUI64( &x, roundingMode, exact );
3459
3460}
3461
3462int_fast32_t
3463 slow_f128M_to_i32(
3464 const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
3465{
3466 struct floatX x;
3467
3468 f128MToFloatX( aPtr, &x );
3469 return floatXToI32( &x, roundingMode, exact );
3470
3471}
3472
3473int_fast64_t
3474 slow_f128M_to_i64(
3475 const float128_t *aPtr, uint_fast8_t roundingMode, bool exact )
3476{
3477 struct floatX x;
3478
3479 f128MToFloatX( aPtr, &x );
3480 return floatXToI64( &x, roundingMode, exact );
3481
3482}
3483
3484uint_fast32_t slow_f128M_to_ui32_r_minMag( const float128_t *aPtr, bool exact )
3485{
3486 struct floatX x;
3487
3488 f128MToFloatX( aPtr, &x );
3489 return floatXToUI32( &x, softfloat_round_minMag, exact );
3490
3491}
3492
3493uint_fast64_t slow_f128M_to_ui64_r_minMag( const float128_t *aPtr, bool exact )
3494{
3495 struct floatX x;
3496
3497 f128MToFloatX( aPtr, &x );
3498 return floatXToUI64( &x, softfloat_round_minMag, exact );
3499
3500}
3501
3502int_fast32_t slow_f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact )
3503{
3504 struct floatX x;
3505
3506 f128MToFloatX( aPtr, &x );
3507 return floatXToI32( &x, softfloat_round_minMag, exact );
3508
3509}
3510
3511int_fast64_t slow_f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact )
3512{
3513 struct floatX x;
3514
3515 f128MToFloatX( aPtr, &x );
3516 return floatXToI64( &x, softfloat_round_minMag, exact );
3517
3518}
3519
3520#ifdef FLOAT16
3521
3522float16_t slow_f128M_to_f16( const float128_t *aPtr )
3523{
3524 struct floatX x;
3525
3526 f128MToFloatX( aPtr, &x );
3527 return floatXToF16( &x );
3528
3529}
3530
3531#endif
3532
3533float32_t slow_f128M_to_f32( const float128_t *aPtr )
3534{
3535 struct floatX x;
3536
3537 f128MToFloatX( aPtr, &x );
3538 return floatXToF32( &x );
3539
3540}
3541
3542#ifdef FLOAT64
3543
3544float64_t slow_f128M_to_f64( const float128_t *aPtr )
3545{
3546 struct floatX x;
3547
3548 f128MToFloatX( aPtr, &x );
3549 return floatXToF64( &x );
3550
3551}
3552
3553#endif
3554
3555#ifdef EXTFLOAT80
3556
3557void slow_f128M_to_extF80M( const float128_t *aPtr, extFloat80_t *zPtr )
3558{
3559 struct floatX x;
3560
3561 f128MToFloatX( aPtr, &x );
3562 floatXToExtF80M( &x, zPtr );
3563
3564}
3565
3566#endif
3567
3568void
3569 slow_f128M_roundToInt(
3570 const float128_t *aPtr,
3571 uint_fast8_t roundingMode,
3572 bool exact,
3573 float128_t *zPtr
3574 )
3575{
3576 struct floatX x;
3577
3578 f128MToFloatX( aPtr, &x );
3579 floatXRoundToInt( &x, roundingMode, exact );
3580 floatXToF128M( &x, zPtr );
3581
3582}
3583
3584void
3585 slow_f128M_add(
3586 const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
3587{
3588 struct floatX x, y;
3589
3590 f128MToFloatX( aPtr, &x );
3591 f128MToFloatX( bPtr, &y );
3592 floatXAdd( &x, &y );
3593 floatXToF128M( &x, zPtr );
3594
3595}
3596
3597void
3598 slow_f128M_sub(
3599 const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
3600{
3601 struct floatX x, y;
3602
3603 f128MToFloatX( aPtr, &x );
3604 f128MToFloatX( bPtr, &y );
3605 y.sign = !y.sign;
3606 floatXAdd( &x, &y );
3607 floatXToF128M( &x, zPtr );
3608
3609}
3610
3611void
3612 slow_f128M_mul(
3613 const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
3614{
3615 struct floatX x, y;
3616
3617 f128MToFloatX( aPtr, &x );
3618 f128MToFloatX( bPtr, &y );
3619 floatXMul( &x, &y );
3620 floatXToF128M( &x, zPtr );
3621
3622}
3623
3624void
3625 slow_f128M_mulAdd(
3626 const float128_t *aPtr,
3627 const float128_t *bPtr,
3628 const float128_t *cPtr,
3629 float128_t *zPtr
3630 )
3631{
3632 struct floatX256 x, y;
3633
3634 f128MToFloatX256( aPtr, &x );
3635 f128MToFloatX256( bPtr, &y );
3636 floatX256Mul( &x, &y );
3637 f128MToFloatX256( cPtr, &y );
3638 floatX256Add( &x, &y );
3639 floatX256ToF128M( &x, zPtr );
3640
3641}
3642
3643void
3644 slow_f128M_div(
3645 const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
3646{
3647 struct floatX x, y;
3648
3649 f128MToFloatX( aPtr, &x );
3650 f128MToFloatX( bPtr, &y );
3651 floatXDiv( &x, &y );
3652 floatXToF128M( &x, zPtr );
3653
3654}
3655
3656void
3657 slow_f128M_rem(
3658 const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr )
3659{
3660 struct floatX x, y;
3661
3662 f128MToFloatX( aPtr, &x );
3663 f128MToFloatX( bPtr, &y );
3664 floatXRem( &x, &y );
3665 floatXToF128M( &x, zPtr );
3666
3667}
3668
3669void slow_f128M_sqrt( const float128_t *aPtr, float128_t *zPtr )
3670{
3671 struct floatX x;
3672
3673 f128MToFloatX( aPtr, &x );
3674 floatXSqrt( &x );
3675 floatXToF128M( &x, zPtr );
3676
3677}
3678
3679bool slow_f128M_eq( const float128_t *aPtr, const float128_t *bPtr )
3680{
3681 struct floatX x, y;
3682
3683 f128MToFloatX( aPtr, &x );
3684 f128MToFloatX( bPtr, &y );
3685 return floatXEq( &x, &y );
3686
3687}
3688
3689bool slow_f128M_le( const float128_t *aPtr, const float128_t *bPtr )
3690{
3691 struct floatX x, y;
3692
3693 f128MToFloatX( aPtr, &x );
3694 f128MToFloatX( bPtr, &y );
3695 if ( x.isNaN || y.isNaN ) {
3696 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3697 }
3698 return floatXLe( &x, &y );
3699
3700}
3701
3702bool slow_f128M_lt( const float128_t *aPtr, const float128_t *bPtr )
3703{
3704 struct floatX x, y;
3705
3706 f128MToFloatX( aPtr, &x );
3707 f128MToFloatX( bPtr, &y );
3708 if ( x.isNaN || y.isNaN ) {
3709 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3710 }
3711 return floatXLt( &x, &y );
3712
3713}
3714
3715bool slow_f128M_eq_signaling( const float128_t *aPtr, const float128_t *bPtr )
3716{
3717 struct floatX x, y;
3718
3719 f128MToFloatX( aPtr, &x );
3720 f128MToFloatX( bPtr, &y );
3721 if ( x.isNaN || y.isNaN ) {
3722 slowfloat_exceptionFlags |= softfloat_flag_invalid;
3723 }
3724 return floatXEq( &x, &y );
3725
3726}
3727
3728bool slow_f128M_le_quiet( const float128_t *aPtr, const float128_t *bPtr )
3729{
3730 struct floatX x, y;
3731
3732 f128MToFloatX( aPtr, &x );
3733 f128MToFloatX( bPtr, &y );
3734 return floatXLe( &x, &y );
3735
3736}
3737
3738bool slow_f128M_lt_quiet( const float128_t *aPtr, const float128_t *bPtr )
3739{
3740 struct floatX x, y;
3741
3742 f128MToFloatX( aPtr, &x );
3743 f128MToFloatX( bPtr, &y );
3744 return floatXLt( &x, &y );
3745
3746}
3747
3748#endif
3749
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette