aboutsummaryrefslogtreecommitdiff
path: root/softfloat_riscv/s_propagateNaNF64UI.c
diff options
context:
space:
mode:
Diffstat (limited to 'softfloat_riscv/s_propagateNaNF64UI.c')
-rwxr-xr-xsoftfloat_riscv/s_propagateNaNF64UI.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/softfloat_riscv/s_propagateNaNF64UI.c b/softfloat_riscv/s_propagateNaNF64UI.c
new file mode 100755
index 0000000..0ff6446
--- /dev/null
+++ b/softfloat_riscv/s_propagateNaNF64UI.c
@@ -0,0 +1,55 @@
+
+/*** UPDATE COMMENTS. ***/
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "platform.h"
+#include "internals.h"
+#include "specialize.h"
+#include "softfloat.h"
+
+/*----------------------------------------------------------------------------
+| Takes two double-precision floating-point values `a' and `b', one of which
+| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
+| signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+uint_fast64_t
+ softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB )
+{
+ bool isNaNA, isSigNaNA, isNaNB, isSigNaNB;
+ uint_fast64_t uiMagA, uiMagB;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ isNaNA = isNaNF64UI( uiA );
+ isSigNaNA = softfloat_isSigNaNF64UI( uiA );
+ isNaNB = isNaNF64UI( uiB );
+ isSigNaNB = softfloat_isSigNaNF64UI( uiB );
+ /*------------------------------------------------------------------------
+ | Make NaNs non-signaling.
+ *------------------------------------------------------------------------*/
+ uiA |= UINT64_C( 0x0008000000000000 );
+ uiB |= UINT64_C( 0x0008000000000000 );
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ if ( isSigNaNA | isSigNaNB ) {
+ softfloat_raiseFlags( softfloat_flag_invalid );
+ }
+ if ( isSigNaNA ) {
+ if ( isSigNaNB ) goto returnLargerSignificand;
+ return isNaNB ? uiB : uiA;
+ } else if ( isNaNA ) {
+ if ( isSigNaNB || ! isNaNB ) return uiA;
+ returnLargerSignificand:
+ uiMagA = uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF );
+ uiMagB = uiB & UINT64_C( 0x7FFFFFFFFFFFFFFF );
+ if ( uiMagA < uiMagB ) return uiB;
+ if ( uiMagB < uiMagA ) return uiA;
+ return ( uiA < uiB ) ? uiA : uiB;
+ } else {
+ return uiB;
+ }
+
+}
+