From patchwork Fri Apr 1 14:30:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 89265 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E07FBB6F94 for ; Sat, 2 Apr 2011 01:32:47 +1100 (EST) Received: from localhost ([127.0.0.1]:47741 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q5fP3-0002nL-1x for incoming@patchwork.ozlabs.org; Fri, 01 Apr 2011 10:32:45 -0400 Received: from [140.186.70.92] (port=57123 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q5fNG-0002jN-Ko for qemu-devel@nongnu.org; Fri, 01 Apr 2011 10:30:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q5fNF-0004rr-9f for qemu-devel@nongnu.org; Fri, 01 Apr 2011 10:30:54 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:45963) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q5fNE-0004or-Ri for qemu-devel@nongnu.org; Fri, 01 Apr 2011 10:30:53 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1Q5fN5-0007mf-9H; Fri, 01 Apr 2011 15:30:43 +0100 From: Peter Maydell To: Anthony Liguori , qemu-devel@nongnu.org Date: Fri, 1 Apr 2011 15:30:39 +0100 Message-Id: <1301668243-29886-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1301668243-29886-1-git-send-email-peter.maydell@linaro.org> References: <1301668243-29886-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 81.2.115.146 Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH 06/10] softfloat: Add float*_min() and float*_max() functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add min and max operations to softfloat. This allows us to implement propagation of NaNs and handling of negative zero correctly (unlike the approach of having target helper routines return one of the operands based on the result of a comparison op). Signed-off-by: Peter Maydell --- fpu/softfloat.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ fpu/softfloat.h | 4 ++++ 2 files changed, 53 insertions(+), 0 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 08e4ae0..03fb948 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -6057,6 +6057,55 @@ int float128_compare_quiet( float128 a, float128 b STATUS_PARAM ) return float128_compare_internal(a, b, 1 STATUS_VAR); } +/* min() and max() functions. These can't be implemented as + * 'compare and pick one input' because that would mishandle + * NaNs and +0 vs -0. + */ +#define MINMAX(s, nan_exp) \ +INLINE float ## s float ## s ## _minmax(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_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 ## _min(float ## s a, float ## s b STATUS_PARAM) \ +{ \ + return float ## s ## _minmax(a, b, 1 STATUS_VAR); \ +} \ + \ +float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM) \ +{ \ + return float ## s ## _minmax(a, b, 0 STATUS_VAR); \ +} + +MINMAX(32, 0xff) +MINMAX(64, 0x7ff) + + /* Multiply A by 2 raised to the power N. */ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) { diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 5d05fa5..90f4250 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -324,6 +324,8 @@ int float32_le_quiet( float32, float32 STATUS_PARAM ); int float32_lt_quiet( float32, float32 STATUS_PARAM ); 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); int float32_is_quiet_nan( float32 ); int float32_is_signaling_nan( float32 ); float32 float32_maybe_silence_nan( float32 ); @@ -436,6 +438,8 @@ int float64_le_quiet( float64, float64 STATUS_PARAM ); int float64_lt_quiet( float64, float64 STATUS_PARAM ); 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); int float64_is_quiet_nan( float64 a ); int float64_is_signaling_nan( float64 ); float64 float64_maybe_silence_nan( float64 );