qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v7 4/6] softfloat: Add minNum() and maxNum() functio


From: Will Newton
Subject: [Qemu-devel] [PATCH v7 4/6] softfloat: Add minNum() and maxNum() functions to softfloat.
Date: Mon, 2 Dec 2013 20:12:55 +0000

Add floatnn_minnum() and floatnn_maxnum() functions which are equivalent
to the minNum() and maxNum() functions from IEEE 754-2008. They are
similar to min() and max() but differ in the handling of QNaN arguments.
---
 fpu/softfloat.c         | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/fpu/softfloat.h |  4 ++++
 2 files changed, 58 insertions(+)

Changes in v7:
 - New patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 97bf627..9834927 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6750,6 +6750,60 @@ float ## s float ## s ## _max(float ## s a, float ## s b 
STATUS_PARAM)  \
 MINMAX(32)
 MINMAX(64)
 
+/* minnum() and maxnum() functions. These are similar to the min()
+ * and max() functions but if one of the arguments is a QNaN and
+ * the other is numerical then the numerical argument is returned.
+ */
+#define MINMAXNUM(s)                                                       \
+INLINE float ## s float ## s ## _minmaxnum(float ## s a, float ## s b,     \
+                                           int ismin STATUS_PARAM )        \
+{                                                                          \
+    flag aSign, bSign;                                                     \
+    uint ## s ## _t av, bv;                                                \
+    a = float ## s ## _squash_input_denormal(a STATUS_VAR);                \
+    b = float ## s ## _squash_input_denormal(b STATUS_VAR);                \
+    if (float ## s ## _is_quiet_nan(a) &&                                  \
+        !float ## s ##_is_quiet_nan(b)) {                                  \
+        return b;                                                          \
+    } else if (float ## s ## _is_quiet_nan(b) &&                           \
+               !float ## s ## _is_quiet_nan(a)) {                          \
+        return a;                                                          \
+    } else if (float ## s ## _is_any_nan(a) ||                             \
+        float ## s ## _is_any_nan(b)) {                                    \
+        return propagateFloat ## s ## NaN(a, b STATUS_VAR);                \
+    }                                                                      \
+    aSign = extractFloat ## s ## Sign(a);                                  \
+    bSign = extractFloat ## s ## Sign(b);                                  \
+    av = float ## s ## _val(a);                                            \
+    bv = float ## s ## _val(b);                                            \
+    if (aSign != bSign) {                                                  \
+        if (ismin) {                                                       \
+            return aSign ? a : b;                                          \
+        } else {                                                           \
+            return aSign ? b : a;                                          \
+        }                                                                  \
+    } else {                                                               \
+        if (ismin) {                                                       \
+            return (aSign ^ (av < bv)) ? a : b;                            \
+        } else {                                                           \
+            return (aSign ^ (av < bv)) ? b : a;                            \
+        }                                                                  \
+    }                                                                      \
+}                                                                          \
+                                                                           \
+float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM)  \
+{                                                                          \
+    return float ## s ## _minmaxnum(a, b, 1 STATUS_VAR);                   \
+}                                                                          \
+                                                                           \
+float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM)  \
+{                                                                          \
+    return float ## s ## _minmaxnum(a, b, 0 STATUS_VAR);                   \
+}
+
+MINMAXNUM(32)
+MINMAXNUM(64)
+
 
 /* Multiply A by 2 raised to the power N.  */
 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f3927e2..2365274 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -302,6 +302,8 @@ int float32_compare( float32, float32 STATUS_PARAM );
 int float32_compare_quiet( float32, float32 STATUS_PARAM );
 float32 float32_min(float32, float32 STATUS_PARAM);
 float32 float32_max(float32, float32 STATUS_PARAM);
+float32 float32_minnum(float32, float32 STATUS_PARAM);
+float32 float32_maxnum(float32, float32 STATUS_PARAM);
 int float32_is_quiet_nan( float32 );
 int float32_is_signaling_nan( float32 );
 float32 float32_maybe_silence_nan( float32 );
@@ -408,6 +410,8 @@ int float64_compare( float64, float64 STATUS_PARAM );
 int float64_compare_quiet( float64, float64 STATUS_PARAM );
 float64 float64_min(float64, float64 STATUS_PARAM);
 float64 float64_max(float64, float64 STATUS_PARAM);
+float64 float64_minnum(float64, float64 STATUS_PARAM);
+float64 float64_maxnum(float64, float64 STATUS_PARAM);
 int float64_is_quiet_nan( float64 a );
 int float64_is_signaling_nan( float64 );
 float64 float64_maybe_silence_nan( float64 );
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]