From patchwork Sun May 15 14:13:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 95625 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CDC6AB6F06 for ; Mon, 16 May 2011 00:17:00 +1000 (EST) Received: from localhost ([::1]:46829 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QLc7t-0005pu-QK for incoming@patchwork.ozlabs.org; Sun, 15 May 2011 10:16:57 -0400 Received: from eggs.gnu.org ([140.186.70.92]:34650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QLc4a-00008m-I9 for qemu-devel@nongnu.org; Sun, 15 May 2011 10:13:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QLc4Z-0007ir-Ek for qemu-devel@nongnu.org; Sun, 15 May 2011 10:13:32 -0400 Received: from hall.aurel32.net ([88.191.126.93]:42087) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QLc4Z-0007ij-9S for qemu-devel@nongnu.org; Sun, 15 May 2011 10:13:31 -0400 Received: from [2001:470:d4ed:0:5e26:aff:fe2b:6f5b] (helo=volta.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1QLc4Y-0005ye-PV; Sun, 15 May 2011 16:13:30 +0200 Received: from aurel32 by volta.aurel32.net with local (Exim 4.72) (envelope-from ) id 1QLc4S-000258-Qz; Sun, 15 May 2011 16:13:24 +0200 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Sun, 15 May 2011 16:13:20 +0200 Message-Id: <1305468801-6015-11-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1305468801-6015-1-git-send-email-aurelien@aurel32.net> References: <1305468801-6015-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 88.191.126.93 Cc: Aurelien Jarno Subject: [Qemu-devel] [PATCH 10/11] softfloat: add floatx80_log2() function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Based on the same algorithm as float32_log2() and float64_log2(). Signed-off-by: Aurelien Jarno --- fpu/softfloat.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fpu/softfloat.h | 1 + 2 files changed, 59 insertions(+), 0 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b11e6dd..87e3645 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -4543,6 +4543,64 @@ floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM ) } /*---------------------------------------------------------------------------- +| Returns the binary log of the extended-precision floating-point value `a'. +| The operation is performed according to the IEC/IEEE Standard for Binary +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ +floatx80 floatx80_log2( floatx80 a STATUS_PARAM ) +{ + flag aSign, zSign; + int32_t aExp; + uint64_t aSig0, aSig1, zSig0, zSig1, i; + floatx80 z; + + aSig0 = 0; + aSig1 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + + if ( aExp == 0 ) { + if ( (aSig1 << 1) == 0 ) { + return packFloatx80( 1, 0x7FFF, 0 ); + } + normalizeFloatx80Subnormal( aSig1, &aExp, &aSig1 ); + } + if ( aSign ) { + float_raise( float_flag_invalid STATUS_VAR); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0x7FFF ) { + if ( aSig1 ) { + return propagateFloatx80NaN( a, a STATUS_VAR ); + } + return a; + } + + aExp -= 0x3FFF; + zSign = aExp < 0; + zSig0 = (int64_t)aExp >> 1; + zSig1 = (int64_t)aExp << 63; + for (i = 1LL << 62; i > 0; i >>= 1) { + mul64To128( aSig1, aSig1, &aSig0, &aSig1 ); + if ( aSig0 & LIT64 ( 0x8000000000000000 ) ) { + aSig1 = aSig0; + zSig1 |= i; + } else { + aSig1 = (aSig0 << 1) | (aSig1 >> 63); + } + } + + if ( zSign ) { + zSig1 = -zSig1; + zSig0 = ~zSig0 + (zSig1 ? 0 : 1); + } + return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision), + zSign, 0x403f, zSig0, zSig1 STATUS_VAR ); +} + +/*---------------------------------------------------------------------------- | Returns 1 if the extended double-precision floating-point value `a' is equal | to the corresponding value `b', and 0 otherwise. The invalid exception is | raised if either operand is a NaN. Otherwise, the comparison is performed diff --git a/fpu/softfloat.h b/fpu/softfloat.h index 8fa4af6..03ce60d 100644 --- a/fpu/softfloat.h +++ b/fpu/softfloat.h @@ -500,6 +500,7 @@ floatx80 floatx80_mul( floatx80, floatx80 STATUS_PARAM ); floatx80 floatx80_div( floatx80, floatx80 STATUS_PARAM ); floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM ); floatx80 floatx80_sqrt( floatx80 STATUS_PARAM ); +floatx80 floatx80_log2( floatx80 STATUS_PARAM ); int floatx80_eq( floatx80, floatx80 STATUS_PARAM ); int floatx80_le( floatx80, floatx80 STATUS_PARAM ); int floatx80_lt( floatx80, floatx80 STATUS_PARAM );