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