From nobody Sun May 19 17:42:31 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; 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=1622133576; cv=none; d=zohomail.com; s=zohoarc; b=hAMWjOQ95xMJ1HYDqVrrnO1s1zomqXGOGJIgjTE5hKBop+CarcwfyrczFnwgfx65E+geieTQDGy+IOSAqEaaGVKmQRh/KBkfVQHU2gMEmgQpVAonRzARxgBQS8WnVQcGv0YBO2vahETrFcGmZ3mEYazL75/CPNwAK7qI1pI7w0g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622133576; h=Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:Sender:Subject:To; bh=BFsijJ14iLj/gkJf2FE+AprCXKUjD51qL5B+Wf/vZRI=; b=DI3Q9Lf4VdNRGQ7+ghEazAChI5A4m6zVWs/QWNSc+RLqtuCPec39p8hPFkU5t2WUpQpihH3mSKi2Nc/mPc7R6ZqabV/YX+7vN8J63hhgdVEfsKNJYueRwMQp4/2yxzCLJhNkOVe0Kf22WjkUQjqZSIcGNA9mICAnc6X+L6rY0Iw= ARC-Authentication-Results: i=1; mx.zohomail.com; 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 1622133576522646.6505436002423; Thu, 27 May 2021 09:39:36 -0700 (PDT) Received: from localhost ([::1]:59622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lmJ2l-0006pV-Bg for importer@patchew.org; Thu, 27 May 2021 12:39:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40538) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lmIzI-0004Et-QC; Thu, 27 May 2021 12:36:00 -0400 Received: from [201.28.113.2] (port=3613 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lmIzG-0006cE-4S; Thu, 27 May 2021 12:36:00 -0400 Received: from power9a ([10.10.71.235]) by outlook.eldorado.org.br with Microsoft SMTPSVC(8.5.9600.16384); Thu, 27 May 2021 13:35:53 -0300 Received: from eldorado.org.br (unknown [10.10.71.235]) by power9a (Postfix) with ESMTP id 1DA4C8013E1; Thu, 27 May 2021 13:35:53 -0300 (-03) From: "Bruno Larsen (billionai)" To: qemu-devel@nongnu.org Subject: [PATCH v4] target/ppc: overhauled and moved logic of storing fpscr Date: Thu, 27 May 2021 13:35:22 -0300 Message-Id: <20210527163522.23019-1-bruno.larsen@eldorado.org.br> X-Mailer: git-send-email 2.17.1 X-OriginalArrivalTime: 27 May 2021 16:35:53.0276 (UTC) FILETIME=[5C3F57C0:01D75316] X-Host-Lookup-Failed: Reverse DNS lookup failed for 201.28.113.2 (failed) 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=201.28.113.2; envelope-from=bruno.larsen@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-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: farosas@linux.ibm.com, richard.henderson@linaro.org, luis.pires@eldorado.org.br, Greg Kurz , lucas.araujo@eldorado.org.br, fernando.valle@eldorado.org.br, qemu-ppc@nongnu.org, matheus.ferst@eldorado.org.br, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Followed the suggested overhaul to store_fpscr logic, and moved it to cpu.c where it can be accessed in !TCG builds. The overhaul was suggested because storing a value to fpscr should never raise an exception, so we could remove all the mess that happened with POWERPC_EXCP_FP. We also moved fpscr_set_rounding_mode into cpu.c as it could now be moved there, and it is needed when a value for the fpscr is being stored directly. Suggested-by: Richard Henderson Signed-off-by: Bruno Larsen (billionai) Reviewed-by: Richard Henderson --- target/ppc/cpu.c | 43 ++++++++ target/ppc/cpu.h | 12 +- target/ppc/fpu_helper.c | 238 +++------------------------------------- target/ppc/gdbstub.c | 6 +- 4 files changed, 65 insertions(+), 234 deletions(-) diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index c8e87e30f1..19d67b5b07 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -25,6 +25,7 @@ #include "fpu/softfloat-helpers.h" #include "mmu-hash64.h" #include "helper_regs.h" +#include "sysemu/tcg.h" =20 target_ulong cpu_read_xer(CPUPPCState *env) { @@ -109,3 +110,45 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) /* The gtse bit affects hflags */ hreg_compute_hflags(env); } + +static inline void fpscr_set_rounding_mode(CPUPPCState *env) +{ + int rnd_type; + + /* Set rounding mode */ + switch (fpscr_rn) { + case 0: + /* Best approximation (round to nearest) */ + rnd_type =3D float_round_nearest_even; + break; + case 1: + /* Smaller magnitude (round toward zero) */ + rnd_type =3D float_round_to_zero; + break; + case 2: + /* Round toward +infinite */ + rnd_type =3D float_round_up; + break; + default: + case 3: + /* Round toward -infinite */ + rnd_type =3D float_round_down; + break; + } + set_float_rounding_mode(rnd_type, &env->fp_status); +} + +void ppc_store_fpscr(CPUPPCState *env, target_ulong val) +{ + val &=3D ~(FP_VX | FP_FEX); + if (val & FPSCR_IX) { + val |=3D FP_VX; + } + if ((val >> FPSCR_XX) & (val >> FPSCR_XE) & 0x1f) { + val |=3D FP_FEX; + } + env->fpscr =3D val; + if (tcg_enabled()) { + fpscr_set_rounding_mode(env); + } +} diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index b0934d9be4..b7ae4902e4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -675,11 +675,11 @@ enum { #define fpscr_ni (((env->fpscr) >> FPSCR_NI) & 0x1) #define fpscr_rn (((env->fpscr) >> FPSCR_RN0) & 0x3) /* Invalid operation exception summary */ -#define fpscr_ix ((env->fpscr) & ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI)= | \ - (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ)= | \ - (1 << FPSCR_VXIMZ) | (1 << FPSCR_VXVC) = | \ - (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT= ) | \ - (1 << FPSCR_VXCVI))) +#define FPSCR_IX ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \ + (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \ + (1 << FPSCR_VXIMZ) | (1 << FPSCR_VXVC) | \ + (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT) | \ + (1 << FPSCR_VXCVI)) /* exception summary */ #define fpscr_ex (((env->fpscr) >> FPSCR_XX) & 0x1F) /* enabled exception summary */ @@ -1332,7 +1332,7 @@ void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHype= rvisor *vhyp); #endif #endif =20 -void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask); +void ppc_store_fpscr(CPUPPCState *env, target_ulong val); void helper_hfscr_facility_check(CPUPPCState *env, uint32_t bit, const char *caller, uint32_t cause); =20 diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index a4a283df2b..c4896cecc8 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -383,247 +383,35 @@ static inline void float_inexact_excp(CPUPPCState *e= nv) } } =20 -static inline void fpscr_set_rounding_mode(CPUPPCState *env) -{ - int rnd_type; - - /* Set rounding mode */ - switch (fpscr_rn) { - case 0: - /* Best approximation (round to nearest) */ - rnd_type =3D float_round_nearest_even; - break; - case 1: - /* Smaller magnitude (round toward zero) */ - rnd_type =3D float_round_to_zero; - break; - case 2: - /* Round toward +infinite */ - rnd_type =3D float_round_up; - break; - default: - case 3: - /* Round toward -infinite */ - rnd_type =3D float_round_down; - break; - } - set_float_rounding_mode(rnd_type, &env->fp_status); -} - void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit) { - int prev; - - prev =3D (env->fpscr >> bit) & 1; - env->fpscr &=3D ~(1 << bit); - if (prev =3D=3D 1) { - switch (bit) { - case FPSCR_RN1: - case FPSCR_RN0: - fpscr_set_rounding_mode(env); - break; - case FPSCR_VXSNAN: - case FPSCR_VXISI: - case FPSCR_VXIDI: - case FPSCR_VXZDZ: - case FPSCR_VXIMZ: - case FPSCR_VXVC: - case FPSCR_VXSOFT: - case FPSCR_VXSQRT: - case FPSCR_VXCVI: - if (!fpscr_ix) { - /* Set VX bit to zero */ - env->fpscr &=3D ~FP_VX; - } - break; - case FPSCR_OX: - case FPSCR_UX: - case FPSCR_ZX: - case FPSCR_XX: - case FPSCR_VE: - case FPSCR_OE: - case FPSCR_UE: - case FPSCR_ZE: - case FPSCR_XE: - if (!fpscr_eex) { - /* Set the FEX bit */ - env->fpscr &=3D ~FP_FEX; - } - break; - default: - break; - } + uint32_t mask =3D 1u << bit; + if (env->fpscr & mask) { + ppc_store_fpscr(env, env->fpscr & ~(target_ulong)mask); } } =20 void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) { - CPUState *cs =3D env_cpu(env); - int prev; - - prev =3D (env->fpscr >> bit) & 1; - env->fpscr |=3D 1 << bit; - if (prev =3D=3D 0) { - switch (bit) { - case FPSCR_VX: - env->fpscr |=3D FP_FX; - if (fpscr_ve) { - goto raise_ve; - } - break; - case FPSCR_OX: - env->fpscr |=3D FP_FX; - if (fpscr_oe) { - goto raise_oe; - } - break; - case FPSCR_UX: - env->fpscr |=3D FP_FX; - if (fpscr_ue) { - goto raise_ue; - } - break; - case FPSCR_ZX: - env->fpscr |=3D FP_FX; - if (fpscr_ze) { - goto raise_ze; - } - break; - case FPSCR_XX: - env->fpscr |=3D FP_FX; - if (fpscr_xe) { - goto raise_xe; - } - break; - case FPSCR_VXSNAN: - case FPSCR_VXISI: - case FPSCR_VXIDI: - case FPSCR_VXZDZ: - case FPSCR_VXIMZ: - case FPSCR_VXVC: - case FPSCR_VXSOFT: - case FPSCR_VXSQRT: - case FPSCR_VXCVI: - env->fpscr |=3D FP_VX; - env->fpscr |=3D FP_FX; - if (fpscr_ve !=3D 0) { - goto raise_ve; - } - break; - case FPSCR_VE: - if (fpscr_vx !=3D 0) { - raise_ve: - env->error_code =3D POWERPC_EXCP_FP; - if (fpscr_vxsnan) { - env->error_code |=3D POWERPC_EXCP_FP_VXSNAN; - } - if (fpscr_vxisi) { - env->error_code |=3D POWERPC_EXCP_FP_VXISI; - } - if (fpscr_vxidi) { - env->error_code |=3D POWERPC_EXCP_FP_VXIDI; - } - if (fpscr_vxzdz) { - env->error_code |=3D POWERPC_EXCP_FP_VXZDZ; - } - if (fpscr_vximz) { - env->error_code |=3D POWERPC_EXCP_FP_VXIMZ; - } - if (fpscr_vxvc) { - env->error_code |=3D POWERPC_EXCP_FP_VXVC; - } - if (fpscr_vxsoft) { - env->error_code |=3D POWERPC_EXCP_FP_VXSOFT; - } - if (fpscr_vxsqrt) { - env->error_code |=3D POWERPC_EXCP_FP_VXSQRT; - } - if (fpscr_vxcvi) { - env->error_code |=3D POWERPC_EXCP_FP_VXCVI; - } - goto raise_excp; - } - break; - case FPSCR_OE: - if (fpscr_ox !=3D 0) { - raise_oe: - env->error_code =3D POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX; - goto raise_excp; - } - break; - case FPSCR_UE: - if (fpscr_ux !=3D 0) { - raise_ue: - env->error_code =3D POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX; - goto raise_excp; - } - break; - case FPSCR_ZE: - if (fpscr_zx !=3D 0) { - raise_ze: - env->error_code =3D POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX; - goto raise_excp; - } - break; - case FPSCR_XE: - if (fpscr_xx !=3D 0) { - raise_xe: - env->error_code =3D POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX; - goto raise_excp; - } - break; - case FPSCR_RN1: - case FPSCR_RN0: - fpscr_set_rounding_mode(env); - break; - default: - break; - raise_excp: - /* Update the floating-point enabled exception summary */ - env->fpscr |=3D FP_FEX; - /* We have to update Rc1 before raising the exception */ - cs->exception_index =3D POWERPC_EXCP_PROGRAM; - break; - } + uint32_t mask =3D 1u << bit; + if (!(env->fpscr & mask)) { + ppc_store_fpscr(env, env->fpscr | mask); } } =20 -void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) +void helper_store_fpscr(CPUPPCState *env, uint64_t val, uint32_t nibbles) { - CPUState *cs =3D env_cpu(env); - target_ulong prev, new; + target_ulong mask =3D 0; int i; =20 - prev =3D env->fpscr; - new =3D (target_ulong)arg; - new &=3D ~(FP_FEX | FP_VX); - new |=3D prev & (FP_FEX | FP_VX); + /* TODO: push this extension back to translation time */ for (i =3D 0; i < sizeof(target_ulong) * 2; i++) { - if (mask & (1 << i)) { - env->fpscr &=3D ~(0xFLL << (4 * i)); - env->fpscr |=3D new & (0xFLL << (4 * i)); + if (nibbles & (1 << i)) { + mask |=3D (target_ulong) 0xf << (4 * i); } } - /* Update VX and FEX */ - if (fpscr_ix !=3D 0) { - env->fpscr |=3D FP_VX; - } else { - env->fpscr &=3D ~FP_VX; - } - if ((fpscr_ex & fpscr_eex) !=3D 0) { - env->fpscr |=3D FP_FEX; - cs->exception_index =3D POWERPC_EXCP_PROGRAM; - /* XXX: we should compute it properly */ - env->error_code =3D POWERPC_EXCP_FP; - } else { - env->fpscr &=3D ~FP_FEX; - } - fpscr_set_rounding_mode(env); -} - -void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask) -{ - helper_store_fpscr(env, arg, mask); + val =3D (val & mask) | (env->fpscr & ~mask); + ppc_store_fpscr(env, val); } =20 static void do_float_check_status(CPUPPCState *env, uintptr_t raddr) diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 308b98fc90..09ff1328d4 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -271,7 +271,7 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *m= em_buf, int n) break; case 70: /* fpscr */ - store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); + ppc_store_fpscr(env, ldtul_p(mem_buf)); break; } } @@ -321,7 +321,7 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint= 8_t *mem_buf, int n) break; case 70 + 32: /* fpscr */ - store_fpscr(env, ldq_p(mem_buf), 0xffffffff); + ppc_store_fpscr(env, ldq_p(mem_buf)); break; } } @@ -474,7 +474,7 @@ static int gdb_set_float_reg(CPUPPCState *env, uint8_t = *mem_buf, int n) } if (n =3D=3D 32) { ppc_maybe_bswap_register(env, mem_buf, 4); - store_fpscr(env, ldl_p(mem_buf), 0xffffffff); + ppc_store_fpscr(env, ldl_p(mem_buf)); return 4; } return 0; --=20 2.17.1