From patchwork Tue Aug 21 04:33:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 144673 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp4786170ljj; Mon, 20 Aug 2018 21:38:10 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzvRxxOJpA+4oMmFaTgupCrgMVY7TixTw7eH2sxApE1QDN8Z6EOcDu8C+eWvpiw+9uaj6Uo X-Received: by 2002:ac8:8e6:: with SMTP id y35-v6mr7704060qth.408.1534826289943; Mon, 20 Aug 2018 21:38:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534826289; cv=none; d=google.com; s=arc-20160816; b=O90tPEyOVKrWi6eCNA6nsstx+q2ysh5Or1NFhiuIscGw42EPO4V8CtjxyDDk3BgIfb vNlL5Aci4Wk1C6f33ES0BYoUmemvqUhYl124vyXc54XFlAi0/x6uRqNOQdcTKvRsqK3+ UTMHbOvxVv1brn7cYUl/nwUftKsBi5uhvo8XyYxVjDxE6IEJOeWFYfXkY/KNjcIpWfL7 PrI/gvxCNcJgvS/mW1wWj3u2+rloDr2vrcQiyumzxuBYkpyUhXsni9wyR1XWZqjSSg/w tFh+Xur9xgk7xKjUY7E9NBeSUSke20PGcYHaxO/qSLke+14RnM6DIBvoizRZduRIZ+NA XKkg== 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=QbFz9Ql6gZE7WK+4OYku769ZQp91fASPvMLX0jnekzk=; b=L3ksYdigFFngiruggs5tVeSsm6nPCpiesFOPY9iYb5J6wBDdQzUeMyzRvxdcormwsa sJNP5HyK+nGEKPQlvGD87VX7DL9R/cdbtLCQGI7YK8OOgcv3Of6GVQ2C+xbUojawHOi4 cOZzVph+FvbMVUbgOoBYlEt+ap8IlZ1vYY3qJcOvQGMINVqPZHFecQLyHULiispJG0tK t9y57nNyf1bFY+53T/dhTllj5kwUMDW9QjxV7Qj0z1Nim8ci9dDjItlhiXqJhOUVC0LJ Uxy6agkdEtN4pbv/fQr4Fb/aDXZ5Pv2yqwRpSf3tIwKlnnE6rRrXv8MfCFYdw/9EM9jW 6uGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gibson.dropbear.id.au header.s=201602 header.b=PpfQOXNP; 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" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id m3-v6si600622qtp.325.2018.08.20.21.38.09 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 20 Aug 2018 21:38:09 -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=@gibson.dropbear.id.au header.s=201602 header.b=PpfQOXNP; 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" Received: from localhost ([::1]:50651 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fryQj-0006Sn-BZ for patch@linaro.org; Tue, 21 Aug 2018 00:38:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56353) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fryMk-00044q-Tj for qemu-devel@nongnu.org; Tue, 21 Aug 2018 00:34:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fryMi-0000GS-Ik for qemu-devel@nongnu.org; Tue, 21 Aug 2018 00:34:02 -0400 Received: from ozlabs.org ([203.11.71.1]:37219) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fryMh-0000DF-Ac; Tue, 21 Aug 2018 00:33:59 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41vd9D2Zfxz9sCP; Tue, 21 Aug 2018 14:33:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1534826032; bh=yfpLkCnMOb3VM1BxVpF+WUG9zDk2jzfyR0pH5R9o/Sk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PpfQOXNPw0Ytc+mKPOFSbAG1FYoktoO2XVXlq11bX14Z8qdjc+PCBp/w4vTB2gGtP l4FYnlKLR/N58SGXFyfl+4xqU9ZAYZqVnYX82Igh6uMms0lz9AGdC10HbEIMG8hjCT NN2VnV68DEPG1qxcWr9fRlwnkQCFr9qKrc7OibjM= From: David Gibson To: peter.maydell@linaro.org Date: Tue, 21 Aug 2018 14:33:21 +1000 Message-Id: <20180821043343.7514-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180821043343.7514-1-david@gibson.dropbear.id.au> References: <20180821043343.7514-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 04/26] target/ppc: Honor fpscr_ze semantics and tidy fdiv 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: lvivier@redhat.com, aik@ozlabs.ru, Richard Henderson , groug@kaod.org, qemu-devel@nongnu.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Divide by zero, exception taken, leaves the destination register unmodified. Therefore we must raise the exception before returning from helper_fdiv. Move the check from do_float_check_status into helper_fdiv. 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 Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 50 +++++++++++++++++++++++------------------ target/ppc/helper.h | 2 +- 2 files changed, 29 insertions(+), 23 deletions(-) -- 2.17.1 diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 9b39c4b3e5..c20b9ae672 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -545,9 +545,7 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr) int status = get_float_exception_flags(&env->fp_status); bool inexact_happened = false; - if (status & float_flag_divbyzero) { - float_zero_divide_excp(env, raddr); - } else if (status & float_flag_overflow) { + if (status & float_flag_overflow) { float_overflow_excp(env); } else if (status & float_flag_underflow) { float_underflow_excp(env); @@ -661,30 +659,32 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2) } /* fdiv - fdiv. */ -uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2) +float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2) { - CPU_DoubleU farg1, farg2; - - farg1.ll = arg1; - farg2.ll = arg2; + float64 ret = float64_div(arg1, arg2, &env->fp_status); + int status = get_float_exception_flags(&env->fp_status); - if (unlikely(float64_is_infinity(farg1.d) && - float64_is_infinity(farg2.d))) { - /* Division of infinity by infinity */ - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1); - } else if (unlikely(float64_is_zero(farg1.d) && float64_is_zero(farg2.d))) { - /* Division of zero by zero */ - farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1); - } else { - if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) || - float64_is_signaling_nan(farg2.d, &env->fp_status))) { - /* sNaN division */ - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + if (unlikely(status)) { + if (status & float_flag_invalid) { + /* Determine what kind of invalid operation was seen. */ + if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) { + /* Division of infinity by infinity */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1); + } else if (float64_is_zero(arg1) && float64_is_zero(arg2)) { + /* Division of zero by zero */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1); + } else if (float64_is_signaling_nan(arg1, &env->fp_status) || + float64_is_signaling_nan(arg2, &env->fp_status)) { + /* sNaN division */ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + } + } + if (status & float_flag_divbyzero) { + float_zero_divide_excp(env, GETPC()); } - farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status); } - return farg1.ll; + return ret; } @@ -1928,6 +1928,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ tp##_is_signaling_nan(xb.fld, &tstat)) { \ float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ + } \ + if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \ + float_zero_divide_excp(env, GETPC()); \ } \ \ if (r2sp) { \ @@ -1978,6 +1981,9 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode) float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); } } + if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { + float_zero_divide_excp(env, GETPC()); + } helper_compute_fprf_float128(env, xt.f128); putVSR(rD(opcode) + 32, &xt, env); diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 5706c2497f..1c453fa0f7 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -88,7 +88,7 @@ DEF_HELPER_2(frim, i64, env, i64) DEF_HELPER_3(fadd, i64, env, i64, i64) DEF_HELPER_3(fsub, i64, env, i64, i64) DEF_HELPER_3(fmul, i64, env, i64, i64) -DEF_HELPER_3(fdiv, i64, env, i64, i64) +DEF_HELPER_3(fdiv, f64, env, f64, f64) DEF_HELPER_4(fmadd, i64, env, i64, i64, i64) DEF_HELPER_4(fmsub, i64, env, i64, i64, i64) DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)