From patchwork Fri Feb 7 21:49:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 24319 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f197.google.com (mail-ob0-f197.google.com [209.85.214.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4C8A2202B2 for ; Fri, 7 Feb 2014 21:49:37 +0000 (UTC) Received: by mail-ob0-f197.google.com with SMTP id gq1sf15989183obb.4 for ; Fri, 07 Feb 2014 13:49:36 -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:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=m6JrOaoeRUOiYEguSqjLg+a8E+ORzVc6WVJhEiG6wwE=; b=IqePndGd5tVdc00mxR13aNU8o6khQ5l+Cz71YIOLHvNbACxVuOU4qdzDcmsM0CzblF UXV3k33qEUn430Nz1XOCwJG1E7ybgaE8UE32yiB4tN0827sZeaGQ7Ez1VdMN3P5QYs2X oXJHF1u02WsNOBj3sd826LbfGZx8Uecs8DVbvzSD079pomBio0mpYHQ3WDDeiPjXclvX As0hzBIuoup8Gd3hrLUavphOy24bYN+bhk7tdieFROsiNgdSK/DqsoBOyKSMfmgFrTXv h+AD/JyFO+UQQGEvKcJfJkVLnnP9JZWDKHEeiDkGIWoRm4H49UG5zOIHt7q6aAc5RNMH Uv7Q== X-Gm-Message-State: ALoCoQkGQESmssjGmrwMgu2JCiDOFRexQqhWOlUNUU88v+hVF7qYuueXBnH4YfOAJYhMLz7mnNLI X-Received: by 10.182.118.194 with SMTP id ko2mr6793990obb.32.1391809776426; Fri, 07 Feb 2014 13:49:36 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.37.135 with SMTP id r7ls1248617qgr.25.gmail; Fri, 07 Feb 2014 13:49:36 -0800 (PST) X-Received: by 10.58.169.7 with SMTP id aa7mr8423681vec.24.1391809776299; Fri, 07 Feb 2014 13:49:36 -0800 (PST) Received: from mail-ve0-f182.google.com (mail-ve0-f182.google.com [209.85.128.182]) by mx.google.com with ESMTPS id f5si1272842vej.149.2014.02.07.13.49.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 07 Feb 2014 13:49:36 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.182 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.182; Received: by mail-ve0-f182.google.com with SMTP id jy13so3240767veb.41 for ; Fri, 07 Feb 2014 13:49:36 -0800 (PST) X-Received: by 10.220.48.194 with SMTP id s2mr62407vcf.43.1391809776200; Fri, 07 Feb 2014 13:49:36 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp137806vcz; Fri, 7 Feb 2014 13:49:35 -0800 (PST) X-Received: by 10.152.209.7 with SMTP id mi7mr3256997lac.42.1391809771517; Fri, 07 Feb 2014 13:49:31 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id 6si3118501laq.25.2014.02.07.13.49.29 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 07 Feb 2014 13:49:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WBtIa-0002wO-4z; Fri, 07 Feb 2014 21:49:24 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Alexander Graf , Michael Matz , Claudio Fontana , Dirk Mueller , Laurent Desnogues , kvmarm@lists.cs.columbia.edu, Richard Henderson , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Christoffer Dall , Will Newton , Peter Crosthwaite Subject: [PATCH 7/8] softfloat: Support halving the result of muladd operation Date: Fri, 7 Feb 2014 21:49:22 +0000 Message-Id: <1391809763-11251-8-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1391809763-11251-1-git-send-email-peter.maydell@linaro.org> References: <1391809763-11251-1-git-send-email-peter.maydell@linaro.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.128.182 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 Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , 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 --- 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..c8f0370 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) { + shift32RightJamming(cSig, 1, &cSig); + } else if (cExp == 1) { + shift32RightJamming(cSig, 1, &cSig); + cSig |= (1 << 22); + cExp = 0; + } else { + cExp--; + } + } 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) { + shift64RightJamming(cSig, 1, &cSig); + } else if (cExp == 1) { + shift64RightJamming(cSig, 1, &cSig); + cSig |= (1ULL << 51); + cExp = 0; + } else { + cExp--; + } + } 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, }; /*----------------------------------------------------------------------------