From patchwork Thu Feb 20 11:17:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 25020 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f200.google.com (mail-ob0-f200.google.com [209.85.214.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B66A9203BE for ; Thu, 20 Feb 2014 11:26:57 +0000 (UTC) Received: by mail-ob0-f200.google.com with SMTP id wo20sf6447800obc.3 for ; Thu, 20 Feb 2014 03:26:57 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=ByyTpNuuxjWfsYiG3crGg085nGI6xSCq2W3KZ00q8TM=; b=M5H1tSjpo18WJoWVOfrY+/+O5gGTSaLDzYHvWFSNiiETjRDJ0v8W8mCSBh2PoHvh1H mRvcHh45wEmzoldjJEtQlRr3jFKAsmcwmtQnK8E37rfDuOeFnfIUJxhVXr137rLSetLA 9HKuaucZ711HBWYgqJrUfAmgwjy5IOJhWh3+hqD37ENNkK01HoqMe01ncRZfbpXYP+8B 9DVOaIQ1HKi0plORVrKCwTq8G0MMHuJazFoaCPQRQ4w+1bK4bLMp0I8FIx88tnUSavhS p0yNBm/IAu/IxISSvzOQRL9W/94jIEgoLJunMTOT/OOOZ4OReN415R8x3gL+PJU9GOw0 fSLQ== X-Gm-Message-State: ALoCoQkcJ4s5I5/FkOa8u3fZzcxkFP0CTXi0RmAOuk62YffMh6YgBLXO2BT4GhzALXP+5yDUEr+Z X-Received: by 10.42.13.198 with SMTP id e6mr432261ica.21.1392895617221; Thu, 20 Feb 2014 03:26:57 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.42.138 with SMTP id c10ls496195qga.63.gmail; Thu, 20 Feb 2014 03:26:57 -0800 (PST) X-Received: by 10.221.22.71 with SMTP id qv7mr726235vcb.34.1392895617052; Thu, 20 Feb 2014 03:26:57 -0800 (PST) Received: from mail-vc0-f174.google.com (mail-vc0-f174.google.com [209.85.220.174]) by mx.google.com with ESMTPS id cz20si1340591veb.53.2014.02.20.03.26.57 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 20 Feb 2014 03:26:57 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.174; Received: by mail-vc0-f174.google.com with SMTP id im17so1741713vcb.33 for ; Thu, 20 Feb 2014 03:26:57 -0800 (PST) X-Received: by 10.52.61.168 with SMTP id q8mr599519vdr.40.1392895616985; Thu, 20 Feb 2014 03:26:56 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp50679vcz; Thu, 20 Feb 2014 03:26:56 -0800 (PST) X-Received: by 10.140.38.168 with SMTP id t37mr720969qgt.33.1392895616622; Thu, 20 Feb 2014 03:26:56 -0800 (PST) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c10si730339qcg.81.2014.02.20.03.26.56 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 20 Feb 2014 03:26:56 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:37615 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGRmK-00075z-3G for patch@linaro.org; Thu, 20 Feb 2014 06:26:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58880) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGReh-00042K-2Q for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:19:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WGRef-0004xE-VV for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:19:02 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:46035) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WGRef-0004wV-Km for qemu-devel@nongnu.org; Thu, 20 Feb 2014 06:19:01 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WGRdG-0003SO-TK; Thu, 20 Feb 2014 11:17:34 +0000 From: Peter Maydell To: Anthony Liguori Date: Thu, 20 Feb 2014 11:17:12 +0000 Message-Id: <1392895054-13232-9-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1392895054-13232-1-git-send-email-peter.maydell@linaro.org> References: <1392895054-13232-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 08/30] softfloat: Support halving the result of muladd operation 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The ARMv8 instruction set includes a fused floating point reciprocal square root step instruction which demands an "(x * y + z) / 2" fused operation. Support this by adding a flag to the softfloat muladd operations which requests that the result is halved before rounding. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- fpu/softfloat.c | 38 ++++++++++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 3 +++ 2 files changed, 41 insertions(+) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index e0ea599..fc0b179 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2372,6 +2372,17 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM) } } /* Zero plus something non-zero : just return the something */ + if (flags & float_muladd_halve_result) { + if (cExp == 0) { + normalizeFloat32Subnormal(cSig, &cExp, &cSig); + } + /* Subtract one to halve, and one again because roundAndPackFloat32 + * wants one less than the true exponent. + */ + cExp -= 2; + cSig = (cSig | 0x00800000) << 7; + return roundAndPackFloat32(cSign ^ signflip, cExp, cSig STATUS_VAR); + } return packFloat32(cSign ^ signflip, cExp, cSig); } @@ -2408,6 +2419,9 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM) /* Throw out the special case of c being an exact zero now */ shift64RightJamming(pSig64, 32, &pSig64); pSig = pSig64; + if (flags & float_muladd_halve_result) { + pExp--; + } return roundAndPackFloat32(zSign, pExp - 1, pSig STATUS_VAR); } @@ -2472,6 +2486,10 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM) zSig64 <<= shiftcount; zExp -= shiftcount; } + if (flags & float_muladd_halve_result) { + zExp--; + } + shift64RightJamming(zSig64, 32, &zSig64); return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR); } @@ -4088,6 +4106,17 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) } } /* Zero plus something non-zero : just return the something */ + if (flags & float_muladd_halve_result) { + if (cExp == 0) { + normalizeFloat64Subnormal(cSig, &cExp, &cSig); + } + /* Subtract one to halve, and one again because roundAndPackFloat64 + * wants one less than the true exponent. + */ + cExp -= 2; + cSig = (cSig | 0x0010000000000000ULL) << 10; + return roundAndPackFloat64(cSign ^ signflip, cExp, cSig STATUS_VAR); + } return packFloat64(cSign ^ signflip, cExp, cSig); } @@ -4123,6 +4152,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) if (!cSig) { /* Throw out the special case of c being an exact zero now */ shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1); + if (flags & float_muladd_halve_result) { + pExp--; + } return roundAndPackFloat64(zSign, pExp - 1, pSig1 STATUS_VAR); } @@ -4159,6 +4191,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) zExp--; } shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1); + if (flags & float_muladd_halve_result) { + zExp--; + } return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR); } else { /* Subtraction */ @@ -4209,6 +4244,9 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM) zExp -= (shiftcount + 64); } } + if (flags & float_muladd_halve_result) { + zExp--; + } return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR); } } diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 806ae13..4b4df88 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -249,11 +249,14 @@ void float_raise( int8 flags STATUS_PARAM); | Using these differs from negating an input or output before calling | the muladd function in that this means that a NaN doesn't have its | sign bit inverted before it is propagated. +| We also support halving the result before rounding, as a special +| case to support the ARM fused-sqrt-step instruction FRSQRTS. *----------------------------------------------------------------------------*/ enum { float_muladd_negate_c = 1, float_muladd_negate_product = 2, float_muladd_negate_result = 4, + float_muladd_halve_result = 8, }; /*----------------------------------------------------------------------------