summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2011-04-20 13:04:22 +0200
committerAurelien Jarno <aurelien@aurel32.net>2011-04-25 11:18:32 +0200
commitf6714d365da068481d83787b4044134ae2ec5dfd (patch)
tree9b8d71115117135c1a9e77ec0c491b51bcae45f0
parentd2b1027d5ffe7c6832bd50f167751171ed168ed0 (diff)
downloadqemu-f6714d365da068481d83787b4044134ae2ec5dfd.tar.gz
qemu-f6714d365da068481d83787b4044134ae2ec5dfd.tar.bz2
qemu-f6714d365da068481d83787b4044134ae2ec5dfd.zip
softfloat: add floatx80_compare*() functions
Add floatx80_compare() and floatx80_compare_quiet() functions to match the softfloat-native ones. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--fpu/softfloat.c46
-rw-r--r--fpu/softfloat.h2
2 files changed, 48 insertions, 0 deletions
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6ce0b61c19..4368069dd6 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6190,6 +6190,52 @@ int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \
COMPARE(32, 0xff)
COMPARE(64, 0x7ff)
+INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
+ int is_quiet STATUS_PARAM )
+{
+ flag aSign, bSign;
+
+ if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
+ ( extractFloatx80Frac( a )<<1 ) ) ||
+ ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
+ ( extractFloatx80Frac( b )<<1 ) )) {
+ if (!is_quiet ||
+ floatx80_is_signaling_nan( a ) ||
+ floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid STATUS_VAR);
+ }
+ return float_relation_unordered;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+
+ if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
+ ( ( a.low | b.low ) == 0 ) ) {
+ /* zero case */
+ return float_relation_equal;
+ } else {
+ return 1 - (2 * aSign);
+ }
+ } else {
+ if (a.low == b.low && a.high == b.high) {
+ return float_relation_equal;
+ } else {
+ return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
+ }
+ }
+}
+
+int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
+{
+ return floatx80_compare_internal(a, b, 0 STATUS_VAR);
+}
+
+int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
+{
+ return floatx80_compare_internal(a, b, 1 STATUS_VAR);
+}
+
INLINE int float128_compare_internal( float128 a, float128 b,
int is_quiet STATUS_PARAM )
{
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 7b3b88f1b1..5eff0858f1 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -550,6 +550,8 @@ int floatx80_eq_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_le_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_lt_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_unordered_quiet( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
+int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
int floatx80_is_quiet_nan( floatx80 );
int floatx80_is_signaling_nan( floatx80 );
floatx80 floatx80_maybe_silence_nan( floatx80 );