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:
parent
e70614eaa0
commit
e17ab310e9
@ -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)
|
||||||
|
@ -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 );
|
||||||
|
Loading…
Reference in New Issue
Block a user