softfloat: Add minNum() and maxNum() functions to softfloat.

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.

Signed-off-by: Will Newton <will.newton@linaro.org>
Message-id: 1386158099-9239-5-git-send-email-will.newton@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Will Newton 2013-12-06 17:01:41 +00:00 committed by Peter Maydell
parent e70614eaa0
commit e17ab310e9
2 changed files with 33 additions and 3 deletions

View File

@ -6705,10 +6705,17 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
/* min() and max() functions. These can't be implemented as /* min() and max() functions. These can't be implemented as
* 'compare and pick one input' because that would mishandle * 'compare and pick one input' because that would mishandle
* NaNs and +0 vs -0. * NaNs and +0 vs -0.
*
* 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.
* minnum() and maxnum correspond to the IEEE 754-2008 minNum()
* and maxNum() operations. min() and max() are the typical min/max
* semantics provided by many CPUs which predate that specification.
*/ */
#define MINMAX(s) \ #define MINMAX(s) \
INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b, \ INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b, \
int ismin STATUS_PARAM ) \ int ismin, int isieee STATUS_PARAM) \
{ \ { \
flag aSign, bSign; \ flag aSign, bSign; \
uint ## s ## _t av, bv; \ uint ## s ## _t av, bv; \
@ -6716,6 +6723,15 @@ INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b, \
b = float ## s ## _squash_input_denormal(b STATUS_VAR); \ b = float ## s ## _squash_input_denormal(b STATUS_VAR); \
if (float ## s ## _is_any_nan(a) || \ if (float ## s ## _is_any_nan(a) || \
float ## s ## _is_any_nan(b)) { \ float ## s ## _is_any_nan(b)) { \
if (isieee) { \
if (float ## s ## _is_quiet_nan(a) && \
!float ## s ##_is_any_nan(b)) { \
return b; \
} else if (float ## s ## _is_quiet_nan(b) && \
!float ## s ## _is_any_nan(a)) { \
return a; \
} \
} \
return propagateFloat ## s ## NaN(a, b STATUS_VAR); \ return propagateFloat ## s ## NaN(a, b STATUS_VAR); \
} \ } \
aSign = extractFloat ## s ## Sign(a); \ aSign = extractFloat ## s ## Sign(a); \
@ -6739,12 +6755,22 @@ INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b, \
\ \
float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM) \ float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM) \
{ \ { \
return float ## s ## _minmax(a, b, 1 STATUS_VAR); \ return float ## s ## _minmax(a, b, 1, 0 STATUS_VAR); \
} \ } \
\ \
float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM) \ float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM) \
{ \ { \
return float ## s ## _minmax(a, b, 0 STATUS_VAR); \ return float ## s ## _minmax(a, b, 0, 0 STATUS_VAR); \
} \
\
float ## s float ## s ## _minnum(float ## s a, float ## s b STATUS_PARAM) \
{ \
return float ## s ## _minmax(a, b, 1, 1 STATUS_VAR); \
} \
\
float ## s float ## s ## _maxnum(float ## s a, float ## s b STATUS_PARAM) \
{ \
return float ## s ## _minmax(a, b, 0, 1 STATUS_VAR); \
} }
MINMAX(32) MINMAX(32)

View File

@ -302,6 +302,8 @@ int float32_compare( float32, float32 STATUS_PARAM );
int float32_compare_quiet( float32, float32 STATUS_PARAM ); int float32_compare_quiet( float32, float32 STATUS_PARAM );
float32 float32_min(float32, float32 STATUS_PARAM); float32 float32_min(float32, float32 STATUS_PARAM);
float32 float32_max(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_quiet_nan( float32 );
int float32_is_signaling_nan( float32 ); int float32_is_signaling_nan( float32 );
float32 float32_maybe_silence_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 ); int float64_compare_quiet( float64, float64 STATUS_PARAM );
float64 float64_min(float64, float64 STATUS_PARAM); float64 float64_min(float64, float64 STATUS_PARAM);
float64 float64_max(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_quiet_nan( float64 a );
int float64_is_signaling_nan( float64 ); int float64_is_signaling_nan( float64 );
float64 float64_maybe_silence_nan( float64 ); float64 float64_maybe_silence_nan( float64 );