From patchwork Tue Jul 3 15:17:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 140979 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp1300559ljj; Tue, 3 Jul 2018 08:26:59 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfE3DrCn47y66MQj14mqFrJUSjm5hbUKw7olbVm/sQ33qrcZbtgIAvgJmJMiojRwX+Hs4Aj X-Received: by 2002:a37:1ae7:: with SMTP id l100-v6mr26219332qkh.248.1530631619030; Tue, 03 Jul 2018 08:26:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530631619; cv=none; d=google.com; s=arc-20160816; b=gj7bUk54RR0W6a6m/fMFXE2UwiKllmDvp7CupNXJbq4Exb/+t0YnUn94ieGFDlnXvN EdS5uEI5KBMmItfB1otAHdHfHY81bR6AeWAoOKFmx+WzjNsFpRi2iFqUT5TZAhhhlVEx eVbalnkVEMP5rK1Hi9g0Tcs6+CFu+2Unsre1bl/7VS8wEyorda7TXhDPLIVNOP06vJGi ycN+B2TIa/eojr3B+K8fMAwzVIWyuBS04i+xaga+Lw8qqCu9s+0/IHqzMOyOVYCABimn 0TafElxs+PAC+ydIvoQ9FjIlOg5Qq+6J0MsWkDO1JEM4rltMsZzTpH771IgGTHW9ruMt JFSw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=pH8EovXGz1h8tlGLK9DZKB5EE5L+qrmSbfLNiXlUNU0=; b=lEWbSVZUdfOIz6KlZkMRQqNWK6cFpjd+flXEHiXDRzbZcZJwuZZGfNU65c4EFIp8Gz TPQipalTAFO2GfN5jx8ZuPnKyEo8KoL75mHAE/sjYLPSvWohCDwZLuNOETFLHF0FqgU3 5dIa5DGqXxniWe/LrW2HqNv95ZwCAPrG3DTctf1Qw66wrBZ3RcfNFXv8mYLaYv1vow4q F1UMH7O1EeEAwPs8oIbSUNO4hsW7LMPM+wQhGzf2l/r244MtAjsL0egq08Vi3qXjyPda WELoK9baVppSiJZPdZe46dQYFVh8+/bK1Wat0GZjp/5d5I2zPxPpRU9xU4PScHQOD2lu eiLw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=jLkjL8CU; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id f8-v6si1362221qtk.135.2018.07.03.08.26.58 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 03 Jul 2018 08:26:59 -0700 (PDT) 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; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=jLkjL8CU; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:41089 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faNCk-00048C-F1 for patch@linaro.org; Tue, 03 Jul 2018 11:26:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faN3u-0006Q7-7q for qemu-devel@nongnu.org; Tue, 03 Jul 2018 11:17:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faN3p-0000RJ-17 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 11:17:50 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:39030) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1faN3o-0000Qg-S6 for qemu-devel@nongnu.org; Tue, 03 Jul 2018 11:17:44 -0400 Received: by mail-pf0-x242.google.com with SMTP id s21-v6so1178114pfm.6 for ; Tue, 03 Jul 2018 08:17:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pH8EovXGz1h8tlGLK9DZKB5EE5L+qrmSbfLNiXlUNU0=; b=jLkjL8CUyEXFeVRhlE2Ajv/X5qXYJ9Lqq4w0WUK61PDYRxzMpm8hRwgPjKV3k1z+PR b2K+gx0DD2kZQGe3KwxEfPCQXgPACU2GHbNvA5m+YL2jx7/OmbvqoX6283VNVipx01BX QSNpZauAh35dBk34z02AKxepjH08DfJjqz2CE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pH8EovXGz1h8tlGLK9DZKB5EE5L+qrmSbfLNiXlUNU0=; b=jSZ4wzPeVVvABIZJbNgH0FV5Jhkf130ndux6jfN8pZM7Zv4o1twap9AOTDGkVK/hFw Xk59USqG9GtUv/Ookvr4zan/7IFMxiHdeqz2UlVJdtMCdwCJiVM9CWpjtTT2TntzVuYd hAotRJcc/zhxSR5FOcgfIo/5XX4UIPJSCC++yUEZBlUHoK6ibwufyIAqKOYHogr++zpw k2qWjO2VUpKbSpoArjmuK2UIv70layCfERmqmwbxr+qbeAiI7HUTApqgl8AuVKRaQQpO NdOov6hK/8L8rM5WgNmn+9akY7EtBLCDlTTZB1LhBRQi3wjrOlJEXx9A61F3LXl5f5Iz HSiA== X-Gm-Message-State: APt69E0qqPKIWSsiDYQ1Pij3GKePW0cJDjTpUnnovWwAyblVT3zbDqRx t66Y+2aObn7hHbh9hlCTVn53nO4NYqQ= X-Received: by 2002:a63:4002:: with SMTP id n2-v6mr25398977pga.285.1530631063683; Tue, 03 Jul 2018 08:17:43 -0700 (PDT) Received: from cloudburst.twiddle.net (97-126-112-211.tukw.qwest.net. [97.126.112.211]) by smtp.gmail.com with ESMTPSA id s185-v6sm4834201pfb.116.2018.07.03.08.17.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 03 Jul 2018 08:17:42 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 08:17:31 -0700 Message-Id: <20180703151732.29843-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180703151732.29843-1-richard.henderson@linaro.org> References: <20180703151732.29843-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [PATCH 6/7] target/ppc: Honor fpscr_ze semantics and tidy fre, fresqrt X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, qemu-ppc@nongnu.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Divide by zero, exception taken, leaves the destination register unmodified. Therefore we must raise the exception before returning from the respective helpers. >From helper_fre, divide by zero exception not taken, return the documented +/- 0.5. At the same time, tidy the invalid exception checking so that we rely on softfloat for initial argument validation, and select the kind of invalid operand exception only when we know we must. At the same time, pass and return float64 values directly rather than bounce through the CPU_DoubleU union. Signed-off-by: Richard Henderson --- target/ppc/fpu_helper.c | 62 ++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 25 deletions(-) -- 2.17.1 diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index c8a2dd6408..1e195487d3 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -871,18 +871,27 @@ float64 helper_fsqrt(CPUPPCState *env, float64 arg) } /* fre - fre. */ -uint64_t helper_fre(CPUPPCState *env, uint64_t arg) +float64 helper_fre(CPUPPCState *env, float64 arg) { - CPU_DoubleU farg; + /* "Estimate" the reciprocal with actual division. */ + float64 ret = float64_div(float64_one, arg, &env->fp_status); + int status = get_float_exception_flags(&env->fp_status); - farg.ll = arg; - - if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { - /* sNaN reciprocal */ - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + if (unlikely(status)) { + if (status & float_flag_invalid) { + if (float64_is_signaling_nan(arg, &env->fp_status)) { + /* sNaN reciprocal */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + } + } + if (status & float_flag_divbyzero) { + float_zero_divide_excp(env, GETPC()); + /* For FPSCR.ZE == 0, the result is 1/2. */ + ret = float64_set_sign(float64_half, float64_is_neg(arg)); + } } - farg.d = float64_div(float64_one, farg.d, &env->fp_status); - return farg.d; + + return ret; } /* fres - fres. */ @@ -905,27 +914,30 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg) } /* frsqrte - frsqrte. */ -uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg) +float64 helper_frsqrte(CPUPPCState *env, float64 arg) { - CPU_DoubleU farg; + /* "Estimate" the reciprocal with actual division. */ + float64 rets = float64_sqrt(arg, &env->fp_status); + float64 retd = float64_div(float64_one, rets, &env->fp_status); + int status = get_float_exception_flags(&env->fp_status); - farg.ll = arg; - - if (unlikely(float64_is_any_nan(farg.d))) { - if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { - /* sNaN reciprocal square root */ - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); - farg.ll = float64_snan_to_qnan(farg.ll); + if (unlikely(status)) { + if (status & float_flag_invalid) { + if (float64_is_signaling_nan(arg, &env->fp_status)) { + /* sNaN reciprocal */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + } else { + /* Square root of a negative nonzero number */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1); + } + } + if (status & float_flag_divbyzero) { + /* Reciprocal of (square root of) zero. */ + float_zero_divide_excp(env, GETPC()); } - } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) { - /* Reciprocal square root of a negative nonzero number */ - farg.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1); - } else { - farg.d = float64_sqrt(farg.d, &env->fp_status); - farg.d = float64_div(float64_one, farg.d, &env->fp_status); } - return farg.ll; + return retd; } /* fsel - fsel. */