[xcc] minor performance tweaks
[riscv-isa-sim.git] / softfloat / 8086 / s_propagateNaNF64UI.c
1
2 /*** UPDATE COMMENTS. ***/
3
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include "platform.h"
7 #include "internals.h"
8 #include "specialize.h"
9 #include "softfloat.h"
10
11 /*----------------------------------------------------------------------------
12 | Takes two double-precision floating-point values `a' and `b', one of which
13 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
14 | signaling NaN, the invalid exception is raised.
15 *----------------------------------------------------------------------------*/
16
17 uint_fast64_t
18 softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB )
19 {
20 bool isNaNA, isSigNaNA, isNaNB, isSigNaNB;
21 uint_fast64_t uiMagA, uiMagB;
22
23 /*------------------------------------------------------------------------
24 *------------------------------------------------------------------------*/
25 isNaNA = isNaNF64UI( uiA );
26 isSigNaNA = softfloat_isSigNaNF64UI( uiA );
27 isNaNB = isNaNF64UI( uiB );
28 isSigNaNB = softfloat_isSigNaNF64UI( uiB );
29 /*------------------------------------------------------------------------
30 | Make NaNs non-signaling.
31 *------------------------------------------------------------------------*/
32 uiA |= UINT64_C( 0x0008000000000000 );
33 uiB |= UINT64_C( 0x0008000000000000 );
34 /*------------------------------------------------------------------------
35 *------------------------------------------------------------------------*/
36 if ( isSigNaNA | isSigNaNB ) {
37 softfloat_raiseFlags( softfloat_flag_invalid );
38 }
39 if ( isSigNaNA ) {
40 if ( isSigNaNB ) goto returnLargerSignificand;
41 return isNaNB ? uiB : uiA;
42 } else if ( isNaNA ) {
43 if ( isSigNaNB || ! isNaNB ) return uiA;
44 returnLargerSignificand:
45 uiMagA = uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF );
46 uiMagB = uiB & UINT64_C( 0x7FFFFFFFFFFFFFFF );
47 if ( uiMagA < uiMagB ) return uiB;
48 if ( uiMagB < uiMagA ) return uiA;
49 return ( uiA < uiB ) ? uiA : uiB;
50 } else {
51 return uiB;
52 }
53
54 }
55