aboutsummaryrefslogtreecommitdiff
path: root/softfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.c
diff options
context:
space:
mode:
Diffstat (limited to 'softfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.c')
-rwxr-xr-xsoftfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/softfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.c b/softfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.c
new file mode 100755
index 0000000..07774e8
--- /dev/null
+++ b/softfloat/SoftFloat-3/source/8086/s_propagateNaNF32UI.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 single-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_fast32_t
+ softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB )
+{
+ bool isNaNA, isSigNaNA, isNaNB, isSigNaNB;
+ uint_fast32_t uiMagA, uiMagB;
+
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ isNaNA = isNaNF32UI( uiA );
+ isSigNaNA = softfloat_isSigNaNF32UI( uiA );
+ isNaNB = isNaNF32UI( uiB );
+ isSigNaNB = softfloat_isSigNaNF32UI( uiB );
+ /*------------------------------------------------------------------------
+ | Make NaNs non-signaling.
+ *------------------------------------------------------------------------*/
+ uiA |= 0x00400000;
+ uiB |= 0x00400000;
+ /*------------------------------------------------------------------------
+ *------------------------------------------------------------------------*/
+ 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<<1;
+ uiMagB = uiB<<1;
+ if ( uiMagA < uiMagB ) return uiB;
+ if ( uiMagB < uiMagA ) return uiA;
+ return ( uiA < uiB ) ? uiA : uiB;
+ } else {
+ return uiB;
+ }
+
+}
+