From nobody Tue Feb 10 01:33:20 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1597725111; cv=none; d=zohomail.com; s=zohoarc; b=dbkcfLuaQzt5Y/Sh+1GuuF06FKmqTJmttDnAgB6eTn2qV3CMRBycRRtfcnJ1Okc5qcYhIrghH5euRoN39JxSGvfNBu6j70YW6iUu0WCKWOlW2/jEuQI0SR4oiO9ClYM1QKE11m8u6TrTRpWeDlq6oVvqs/+VIxqx9rPhXYIIEV8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597725111; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=0MBebWz6UBAmmY2y7GXxKyLPysCZ8+5y8+NWAgwSJuw=; b=aIhfbYbNPI4uTGOyiMtoDjUDeG8HXRW3jAx1gAFKr24Ucq56Aml3ul7JCecb5LMGr2alW7hLemn/ho1cGZGzHGkAmbfZtqlLkdpbSosJc63tCe3Ci0Gj2evkzPm6hO355YKy+T3RIyXLGZvrp2xld//fDR8in+anb3m8YVU8t7Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1597725111408932.6897366471463; Mon, 17 Aug 2020 21:31:51 -0700 (PDT) Received: from localhost ([::1]:47542 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k7tHp-0003TG-VL for importer@patchew.org; Tue, 18 Aug 2020 00:31:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:50076) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k7t6D-0007aR-Mt; Tue, 18 Aug 2020 00:19:49 -0400 Received: from bilbo.ozlabs.org ([203.11.71.1]:43185 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k7t6B-0006Mr-2U; Tue, 18 Aug 2020 00:19:49 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4BVyNb3pwKz9sVM; Tue, 18 Aug 2020 14:19:27 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1597724367; bh=p5k/N3bAXkiI8BCnZaFK1edTmmELskToQBlH18YDB1g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VqbgvlW2nz0yJEP34SYIca1YEfoONGnei9+Wj+IJoCB+TYx11gcGxViuNki3X86v0 Ol40UBei0lHNnoK9dGdnRAMbyQ1CnLl6E/RfubTONaQGEZlQGghhjW4gfvTRUFdfuV w41lf8VsyJR6On2G3RaSm3N6LDsNs8y07D3iD4t8= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 15/40] target/ppc: Fix SPE unavailable exception triggering Date: Tue, 18 Aug 2020 14:18:57 +1000 Message-Id: <20200818041922.251708-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200818041922.251708-1-david@gibson.dropbear.id.au> References: <20200818041922.251708-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/18 00:19:26 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] X-Spam_score_int: -9 X-Spam_score: -1.0 X-Spam_bar: - X-Spam_report: (-1.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Matthieu Bucchianeri , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Matthieu Bucchianeri When emulating certain floating point instructions or vector instructions on PowerPC machines, QEMU did not properly generate the SPE/Embedded Floating- Point Unavailable interrupt. See the buglink further below for references to the relevant NXP documentation. This patch fixes the behavior of some evfs* instructions that were incorrectly emitting the interrupt. More importantly, this patch fixes the behavior of several efd* and ev* instructions that were not generating the interrupt. Triggering the interrupt for these instructions fixes lazy FPU/vector context switching on some operating systems like Linux. Without this patch, the result of some double-precision arithmetic could be corrupted due to the lack of proper saving and restoring of the upper 32-bit part of the general-purpose registers. Buglink: https://bugs.launchpad.net/qemu/+bug/1888918 Buglink: https://bugs.launchpad.net/qemu/+bug/1611394 Signed-off-by: Matthieu Bucchianeri Message-Id: <20200727175553.32276-1-matthieu.bucchianeri@leostella.com> Signed-off-by: David Gibson --- target/ppc/translate/spe-impl.inc.c | 97 +++++++++++++++++++---------- 1 file changed, 64 insertions(+), 33 deletions(-) diff --git a/target/ppc/translate/spe-impl.inc.c b/target/ppc/translate/spe= -impl.inc.c index 42a0d1cffb..2e6e799a25 100644 --- a/target/ppc/translate/spe-impl.inc.c +++ b/target/ppc/translate/spe-impl.inc.c @@ -349,14 +349,24 @@ static inline void gen_evmergelohi(DisasContext *ctx) } static inline void gen_evsplati(DisasContext *ctx) { - uint64_t imm =3D ((int32_t)(rA(ctx->opcode) << 27)) >> 27; + uint64_t imm; + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + imm =3D ((int32_t)(rA(ctx->opcode) << 27)) >> 27; =20 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm); tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm); } static inline void gen_evsplatfi(DisasContext *ctx) { - uint64_t imm =3D rA(ctx->opcode) << 27; + uint64_t imm; + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + imm =3D rA(ctx->opcode) << 27; =20 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm); tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm); @@ -389,21 +399,37 @@ static inline void gen_evsel(DisasContext *ctx) =20 static void gen_evsel0(DisasContext *ctx) { + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } gen_evsel(ctx); } =20 static void gen_evsel1(DisasContext *ctx) { + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } gen_evsel(ctx); } =20 static void gen_evsel2(DisasContext *ctx) { + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } gen_evsel(ctx); } =20 static void gen_evsel3(DisasContext *ctx) { + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } gen_evsel(ctx); } =20 @@ -518,6 +544,11 @@ static inline void gen_evmwsmia(DisasContext *ctx) { TCGv_i64 tmp; =20 + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + gen_evmwsmi(ctx); /* rD :=3D rA * rB */ =20 tmp =3D tcg_temp_new_i64(); @@ -534,6 +565,11 @@ static inline void gen_evmwsmiaa(DisasContext *ctx) TCGv_i64 acc; TCGv_i64 tmp; =20 + if (unlikely(!ctx->spe_enabled)) { + gen_exception(ctx, POWERPC_EXCP_SPEU); + return; + } + gen_evmwsmi(ctx); /* rD :=3D rA * rB */ =20 acc =3D tcg_temp_new_i64(); @@ -892,8 +928,14 @@ static inline void gen_##name(DisasContext *ctx) = \ #define GEN_SPEFPUOP_CONV_32_64(name) = \ static inline void gen_##name(DisasContext *ctx) = \ { = \ - TCGv_i64 t0 =3D tcg_temp_new_i64(); = \ - TCGv_i32 t1 =3D tcg_temp_new_i32(); = \ + TCGv_i64 t0; = \ + TCGv_i32 t1; = \ + if (unlikely(!ctx->spe_enabled)) { = \ + gen_exception(ctx, POWERPC_EXCP_SPEU); = \ + return; = \ + } = \ + t0 =3D tcg_temp_new_i64(); = \ + t1 =3D tcg_temp_new_i32(); = \ gen_load_gpr64(t0, rB(ctx->opcode)); = \ gen_helper_##name(t1, cpu_env, t0); = \ tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); = \ @@ -903,8 +945,14 @@ static inline void gen_##name(DisasContext *ctx) = \ #define GEN_SPEFPUOP_CONV_64_32(name) = \ static inline void gen_##name(DisasContext *ctx) = \ { = \ - TCGv_i64 t0 =3D tcg_temp_new_i64(); = \ - TCGv_i32 t1 =3D tcg_temp_new_i32(); = \ + TCGv_i64 t0; = \ + TCGv_i32 t1; = \ + if (unlikely(!ctx->spe_enabled)) { = \ + gen_exception(ctx, POWERPC_EXCP_SPEU); = \ + return; = \ + } = \ + t0 =3D tcg_temp_new_i64(); = \ + t1 =3D tcg_temp_new_i32(); = \ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); = \ gen_helper_##name(t0, cpu_env, t1); = \ gen_store_gpr64(rD(ctx->opcode), t0); = \ @@ -914,7 +962,12 @@ static inline void gen_##name(DisasContext *ctx) = \ #define GEN_SPEFPUOP_CONV_64_64(name) = \ static inline void gen_##name(DisasContext *ctx) = \ { = \ - TCGv_i64 t0 =3D tcg_temp_new_i64(); = \ + TCGv_i64 t0; = \ + if (unlikely(!ctx->spe_enabled)) { = \ + gen_exception(ctx, POWERPC_EXCP_SPEU); = \ + return; = \ + } = \ + t0 =3D tcg_temp_new_i64(); = \ gen_load_gpr64(t0, rB(ctx->opcode)); = \ gen_helper_##name(t0, cpu_env, t0); = \ gen_store_gpr64(rD(ctx->opcode), t0); = \ @@ -923,13 +976,8 @@ static inline void gen_##name(DisasContext *ctx) = \ #define GEN_SPEFPUOP_ARITH2_32_32(name) = \ static inline void gen_##name(DisasContext *ctx) = \ { = \ - TCGv_i32 t0, t1; = \ - if (unlikely(!ctx->spe_enabled)) { = \ - gen_exception(ctx, POWERPC_EXCP_SPEU); = \ - return; = \ - } = \ - t0 =3D tcg_temp_new_i32(); = \ - t1 =3D tcg_temp_new_i32(); = \ + TCGv_i32 t0 =3D tcg_temp_new_i32(); = \ + TCGv_i32 t1 =3D tcg_temp_new_i32(); = \ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); = \ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); = \ gen_helper_##name(t0, cpu_env, t0, t1); = \ @@ -958,13 +1006,8 @@ static inline void gen_##name(DisasContext *ctx) = \ #define GEN_SPEFPUOP_COMP_32(name) = \ static inline void gen_##name(DisasContext *ctx) = \ { = \ - TCGv_i32 t0, t1; = \ - if (unlikely(!ctx->spe_enabled)) { = \ - gen_exception(ctx, POWERPC_EXCP_SPEU); = \ - return; = \ - } = \ - t0 =3D tcg_temp_new_i32(); = \ - t1 =3D tcg_temp_new_i32(); = \ + TCGv_i32 t0 =3D tcg_temp_new_i32(); = \ + TCGv_i32 t1 =3D tcg_temp_new_i32(); = \ = \ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); = \ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); = \ @@ -1074,28 +1117,16 @@ GEN_SPEFPUOP_ARITH2_32_32(efsmul); GEN_SPEFPUOP_ARITH2_32_32(efsdiv); static inline void gen_efsabs(DisasContext *ctx) { - if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_SPEU); - return; - } tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL); } static inline void gen_efsnabs(DisasContext *ctx) { - if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_SPEU); - return; - } tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); } static inline void gen_efsneg(DisasContext *ctx) { - if (unlikely(!ctx->spe_enabled)) { - gen_exception(ctx, POWERPC_EXCP_SPEU); - return; - } tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000); } --=20 2.26.2