From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025936; cv=none; d=zohomail.com; s=zohoarc; b=Ud+fYpitOthZub5sSIoHUqLtU4iXWVFj0RRgaBRHkXuGASF6g7LzWdQDhFXJyysuOo/o+vLtcgUyhTTFcwS4nGfAYc9rVh5U2qZtYixpNbqr46EjBt3p9W/jvkkatjU0G6a//CnilhEMm1tL8z318wmepSbDJJx9KS4vdyLezs4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025936; h=Content-Transfer-Encoding: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=F9963mAn0HXp01JNVVDARECVbWpEusJQnHobNxtO4XM=; b=Zc98erRR2wQ18Olds6v/90juc7FK67mhGOlEoGZRx+DtH74zNoQU8IeQGYDX+bviC2nxNrvYVaG4a9AUm+T/LgTxqEfdO2pkFY/Dfy+fJqSA02b7IpjXIMuXxbk0OlUFJsWz086P+QfOqEo1noO5TffcsKaGAF+QTFg50UENVYQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025936862723.9181575732483; Fri, 18 Jun 2021 07:18:56 -0700 (PDT) Received: from localhost ([::1]:43136 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFKh-0003VF-I5 for importer@patchew.org; Fri, 18 Jun 2021 10:18:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49736) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCq-0007d5-QC for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:49 -0400 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]:34569) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCV-0001wL-HF for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:48 -0400 Received: by mail-wm1-x32c.google.com with SMTP id u5-20020a7bc0450000b02901480e40338bso6621327wmc.1 for ; Fri, 18 Jun 2021 07:10:23 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=F9963mAn0HXp01JNVVDARECVbWpEusJQnHobNxtO4XM=; b=X2asAge8fEBRpJXityfVMz196fb0GRmTKIXzormOwSqi5rxJmr3lbPXnYymc9R0Xmc YuhsAibVzeaTL9D49jZFu3mNRv3XnC/adX25e3GzYx35hxCtKBSTzHSqYAe9/gYkbhVV gEXs5P5qrT6GMNA9gEznRZ8pZ72Xz0LNp2fTlXdV/54V6p1si/Xn6bwu5AX9AsJChzzP MwTn328RLKNErP5Td6ZLdqYMmgXY+pPSgb40s5d7ZT672mYrEyUgEOLX50AO4gXxJXsI z9cjd6HpIzfFAjpvEJSweqob5F7NET4PHVyZWymU20NQNFtGLBxxpN4z11YTepsUZZZk ZLxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=F9963mAn0HXp01JNVVDARECVbWpEusJQnHobNxtO4XM=; b=j3Ar7vBwmr14enp3rSB3jIyvBarCvaKNrTOmQ5ZLg/aT21F3fuFQAwsNKa8qBe0reT NkW3SUA/kij+Ax6xEI2xXwSqhS/r3mAbuI8ZqlGnf42roFSmuR5PcbWBMgnUP7C7t8Fx zBHtBu5+hlsKnzrGKQLVevLP2IoR7hXpwAAB5UWRwahRJvKI4ovXlIy0ujd+i00TB5xQ T16KvMOS7yd8F9DfJ9SHXIoqbAKWhK9Seo7x9lIVhFTtglLcJEr5k7LkTQ9LYtZ/QUt2 c4q4SjEgYmfdUsqXPyQu3JFf5Ye+Wi4PdLAoV4dvBajkaaZZh8+1Xf7cu5HQvbtdnNYp +7kw== X-Gm-Message-State: AOAM5318ep1GwQWN0wIGIRJtY2vLgjbCP4CuiIlUA2GFc9bEpbP9gxk6 qQkel5jj433hYffDcYn2et5vvQ== X-Google-Smtp-Source: ABdhPJx1vAV/fjp4MJmoBrBJ6uGWq3j01JlQlfXN7lYY2Ks2b5EmOj6xXT2k7TYorHH8LcVq3BnJ6Q== X-Received: by 2002:a1c:7314:: with SMTP id d20mr1132372wmb.156.1624025422370; Fri, 18 Jun 2021 07:10:22 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 1/7] target/arm/translate-vfp.c: Whitespace fixes Date: Fri, 18 Jun 2021 15:10:13 +0100 Message-Id: <20210618141019.10671-2-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::32c; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x32c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" In the code for handling VFP system register accesses there is some stray whitespace after a unary '-' operator, and also some incorrect indent in a couple of function prototypes. We're about to move this code to another file, so fix the code style issues first so checkpatch doesn't complain about the code-movement patch. Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/translate-vfp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 01e26a246d6..5a4a13ec1e1 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -771,9 +771,8 @@ static void gen_branch_fpInactive(DisasContext *s, TCGC= ond cond, } =20 static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, - fp_sysreg_loadfn *loadfn, - void *opaque) + void *opaque) { /* Do a write to an M-profile floating point system register */ TCGv_i32 tmp; @@ -874,8 +873,8 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, } =20 static bool gen_M_fp_sysreg_read(DisasContext *s, int regno, - fp_sysreg_storefn *storefn, - void *opaque) + fp_sysreg_storefn *storefn, + void *opaque) { /* Do a read from an M-profile floating point system register */ TCGv_i32 tmp; @@ -1207,7 +1206,7 @@ static void fp_sysreg_to_memory(DisasContext *s, void= *opaque, TCGv_i32 value) TCGv_i32 addr; =20 if (!a->a) { - offset =3D - offset; + offset =3D -offset; } =20 addr =3D load_reg(s, a->rn); @@ -1242,7 +1241,7 @@ static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, = void *opaque) TCGv_i32 value =3D tcg_temp_new_i32(); =20 if (!a->a) { - offset =3D - offset; + offset =3D -offset; } =20 addr =3D load_reg(s, a->rn); --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025577; cv=none; d=zohomail.com; s=zohoarc; b=C2Qu62V9QLsLqo7V5X7CpmL//Vz8mHZ++uUd9BXxpIyQ8Hmga8+WgxOH3jG1dJzxKoIR9afbb00E8YsEzSjCVNug8O85z11Hw/wB/d2v6ny0pVVxNTq7eyfxgVvAH341EunXZIqh+z0ZisoDE5ZGqz9DDxcKeYb9lMZjV+bauC0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025577; h=Content-Transfer-Encoding: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=dRfZrUkzHx2HbQeo0FP4Jf8eMM4MIpIZDbO0Ga50h6Y=; b=PyZZx0l6CqvubLaRnt9KGD2YrCsKQ5Atm7s1TaEIKr7pr61ukux0uOuCi04aM6RBHPYz8vhYwHPoI4p1b592QryDM3jy9NlSsmAZllx8H8K2bx/ubL8f1U8Q9it/IZHjR4/CHIox7m2W2y6kavTpXmwaBuXNv4zjeCtjdNh8O54= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 162402557784514.462729436611767; Fri, 18 Jun 2021 07:12:57 -0700 (PDT) Received: from localhost ([::1]:56194 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFEu-0001ls-5D for importer@patchew.org; Fri, 18 Jun 2021 10:12:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCX-0007OS-Iq for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:29 -0400 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]:34388) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCT-0001xY-WF for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:29 -0400 Received: by mail-wr1-x430.google.com with SMTP id e22so7356119wrc.1 for ; Fri, 18 Jun 2021 07:10:24 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=dRfZrUkzHx2HbQeo0FP4Jf8eMM4MIpIZDbO0Ga50h6Y=; b=P2TzW2ZaSkaDoxIiTnH2mrWozcCUa/cHSp9hXD+uDq+E5oBJxbdpBh8LIbZhvYLem/ EGpoOhpF4kPtsAY7QZpIZFZWe1KBrFTmAoJVEBrMNGQLzrb30oDTCftnM7XfHxH1tOKw FgDH2un/6B3ewOXcgJEc7aiNtb5aL3rkY1wj08dVcQO49GB6P1Hop+85J/Wv21fpNkXj BbinOQjvUP5oLcmYM5jNiJz3UaVFi4Aotx5TSey7e2aHihk/5Gt1oGyHQgQHHsgjE8MV GkQkkiczgSDW63VbAmoigUzVgw/GpIseELAtD75GcITF6dNO05IOug7DfmcBPXIsE4By CpAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dRfZrUkzHx2HbQeo0FP4Jf8eMM4MIpIZDbO0Ga50h6Y=; b=lFSf22Bzb94DkjQcfQH9mQtCQSC5jS8Rx4aejbXwMZYqb4GYyHcHJULyQQWaMj1F4k 2b2IezwAJ0WzCxxCILgIg6JEbKsIdXduOVcDlqX8Q9FzMq13amBEFOjGoHXzAmJK9jMv 3CdAE7dnP3idvSo4Hccifp+MVMX1t98FvMCMLJIaQk6+SGTM+6PcURdZe3Ycwbqh5AKz Ao0JTGZj/MMCdrMLfgIUu0yExoiaT80v5N4vUfcbSZ70UWsJWxGojIIo5+NbqzYRMTV8 uQ9bhye0SLkK9FZ8UhG2bjLU48luTiHwoe1XzC1qaPUj8rxFmoHXpp0wa3dlc4Cdu8+0 k1Vg== X-Gm-Message-State: AOAM531g/sBxnhmAuTub/lHIfrnmC2g5eJ1QAzYhA65ECI6IlzHl/Mj6 XaJkO65bZUkbSQpyH0fIZg2mCYOghAqLnYlL X-Google-Smtp-Source: ABdhPJx67+0ia9kelnVvqdhQGgcVb9o4BmLQebzCmFtO4BuhuzD0xkJRjeCtaBtUwpELVp7Is/0/XA== X-Received: by 2002:adf:ef87:: with SMTP id d7mr12797263wro.24.1624025423083; Fri, 18 Jun 2021 07:10:23 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 2/7] target/arm: Handle FPU being disabled in FPCXT_NS accesses Date: Fri, 18 Jun 2021 15:10:14 +0100 Message-Id: <20210618141019.10671-3-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::430; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" If the guest makes an FPCXT_NS access when the FPU is disabled, one of two things happens: * if there is no active FP context, then the insn behaves the same way as if the FPU was enabled: writes ignored, reads same value as FPDSCR_NS * if there is an active FP context, then we take a NOCP exception Add code to the sysreg read/write functions which emits code to take the NOCP exception in the latter case. At the moment this will never be used, because the NOCP checks in m-nocp.decode happen first, and so the trans functions are never called when the FPU is disabled. The code will be needed when we move the sysreg access insns to before the NOCP patterns in the following commit. Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- The "check for exception; then call gen_preserve_fp_state()" is a little repetitive. We'll clean this up in a bit of refactoring at the end of the patchseries, because the nicest way to do it involves restructuring vfp_access_check(). --- target/arm/translate-vfp.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 5a4a13ec1e1..107d6143be8 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -821,7 +821,21 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int= regno, lab_end =3D gen_new_label(); /* fpInactive case: write is a NOP, so branch to end */ gen_branch_fpInactive(s, TCG_COND_NE, lab_end); - /* !fpInactive: PreserveFPState(), and reads same as FPCXT_S */ + /* + * !fpInactive: if FPU disabled, take NOCP exception; + * otherwise PreserveFPState(), and then FPCXT_NS writes + * behave the same as FPCXT_S writes. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, s->pc_curr, EXCP_NOCP, + syn_uncategorized(), s->fp_excp_el); + /* + * This was only a conditional exception, so override + * gen_exception_insn()'s default to DISAS_NORETURN + */ + s->base.is_jmp =3D DISAS_NEXT; + break; + } gen_preserve_fp_state(s); /* fall through */ case ARM_VFP_FPCXT_S: @@ -961,7 +975,21 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int = regno, tcg_gen_br(lab_end); =20 gen_set_label(lab_active); - /* !fpInactive: Reads the same as FPCXT_S, but side effects differ= */ + /* + * !fpInactive: if FPU disabled, take NOCP exception; + * otherwise PreserveFPState(), and then FPCXT_NS + * reads the same as FPCXT_S. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, s->pc_curr, EXCP_NOCP, + syn_uncategorized(), s->fp_excp_el); + /* + * This was only a conditional exception, so override + * gen_exception_insn()'s default to DISAS_NORETURN + */ + s->base.is_jmp =3D DISAS_NEXT; + break; + } gen_preserve_fp_state(s); tmp =3D tcg_temp_new_i32(); sfpa =3D tcg_temp_new_i32(); --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025819; cv=none; d=zohomail.com; s=zohoarc; b=E97iIqOQQRjx9BmS2rT2cykBBOWHTmwA3D5VB7IZIs3lABE8IIgkl5iQ8sG1ujBKwbDFNDwCl5l1GYq7HkGfxKPbYOTyMQQC7PyMnKR7bHA0qHOvHiYacES7Oect0LdGgDOxafx3EaTJMAmzjN1S8c3NAuNrx/uI72/5uIQ6cFI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025819; h=Content-Transfer-Encoding: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=pdDFPpgX1DSvL1znGtOeU+Ms4xKNu5wOownWiji9ZnU=; b=nX/FwswCBLpoJ/y4WgTCnV/ykRwwvwaIHnZgfXXQvtXyIprdjj9VFkvzHqENTS+BWPk8SHWhEXqRvbyeaDUmT6vhirPzs4W7CU3QojV5oMjM7jnE7+61U32G571xNHN//UV+tdq0cSIlEw1CyAKhh83UtxQBG5+6sIN3Sey1Qzc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025819413271.36964034951575; Fri, 18 Jun 2021 07:16:59 -0700 (PDT) Received: from localhost ([::1]:37992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFIo-0008OB-79 for importer@patchew.org; Fri, 18 Jun 2021 10:16:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49728) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCq-0007bN-CX for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:48 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]:33511) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCV-0001zI-H6 for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:48 -0400 Received: by mail-wr1-x42d.google.com with SMTP id d11so8561769wrm.0 for ; Fri, 18 Jun 2021 07:10:25 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=pdDFPpgX1DSvL1znGtOeU+Ms4xKNu5wOownWiji9ZnU=; b=AuaBHIMyju4hJnW94jAAuFQLjoexiqfWc6xI/fvoKkJvlN4A+MMnaWH21LBpqcZE8X W7vPwPtmpO5KhTz1H4u+W9P4leTQxMccJoK5thB5I5oet7TsBKPd6VNcuR/2fw87zSBB OVvCtee6fyOkmk5oif3qgshSvx7dRdBxU63IFWu8HaJupeEID52YDRRCKKLqlPLQW0Vf VjLsue0xpo/Dn6X1KVbqSu3NhlVYF7G/USqp1O4NGQY+FY+6nhL114hTU37VFdv6vkvh +HarR4VP+DfOPdb2Dl+5WOP8dn2TKNWIiUaqyPjMZfFFBL3crA1qQuWVuIxQzApwzr9z tScQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pdDFPpgX1DSvL1znGtOeU+Ms4xKNu5wOownWiji9ZnU=; b=JXtxnszMPzHUQ4n/FRhGTBB49dadXhjDyjqRxaSmsjs33BHolEYAtDBx6UGzU9bpL9 MkoT9sL9BpMrUU1e9vXGC++P3KVNlA3aFkhSRz94bThRavpNswyK8vf0N2qODWLr32YH s1Wh0okPcPSjk+isDyv3WkRXKfgUAXtNFksY5Tlxue6FJOsGyEJ5lC8aOMCi9rCElT+j qqBsGaz6Vn4B8PvKwr/uQWGSZZqOmG/ueKR/T8NBYKPJWGFB55koAZJ93iGqc8Cchwlu iB4PFQyUsHwn8/h7iV8pm6XxaYwlBan7+Sdq9EhFl6ztHciberSS/c8RjaFZNnhLHur1 7S+A== X-Gm-Message-State: AOAM532KPj5LSXXGG6Q9I9LMqeF2KAgemV//zfy7lpENpkdqJ8TCnb2F McaEXq192ur3fYTetJfW03IC2fzlpe+kBVGQ X-Google-Smtp-Source: ABdhPJxwvUsJhyrBRDi00DI2E61DSv0Q0JR/k4wGPB6vDJZqeL/OFx+4I8gtYop2bALJFm14qOzHyw== X-Received: by 2002:adf:fc0e:: with SMTP id i14mr12817612wrr.71.1624025424444; Fri, 18 Jun 2021 07:10:24 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 3/7] target/arm: Don't NOCP fault for FPCXT_NS accesses Date: Fri, 18 Jun 2021 15:10:15 +0100 Message-Id: <20210618141019.10671-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::42d; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" The M-profile architecture requires that accesses to FPCXT_NS when there is no active FP state must not take a NOCP fault even if the FPU is disabled. We were not implementing this correctly, because in our decode we catch the NOCP faults early in m-nocp.decode. Fix this bug by moving all the handling of M-profile FP system register accesses from vfp.decode into m-nocp.decode and putting it above the NOCP blocks. This provides the correct behaviour: * for accesses other than FPCXT_NS the trans functions call vfp_access_check(), which will check for FPU disabled and raise a NOCP exception if necessary * for FPCXT_NS we have the special case code that doesn't call vfp_access_check() * when these trans functions want to raise an UNDEF they return false, so the decoder will fall through into the NOCP blocks. This means that NOCP correctly takes precedence over UNDEF for these insns. (This is a difference from the other insns handled by m-nocp.decode, where UNDEF takes precedence and which we implement by having those trans functions call unallocated_encoding() in the appropriate places.) [Note for backport to stable: this commit has a semantic dependency on commit 9a486856e9173af, which was not marked as cc-stable because we didn't know we'd need it for a for-stable bugfix.] Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- A big patch, but it's almost entirely code movement. --- target/arm/translate-a32.h | 1 + target/arm/m-nocp.decode | 24 ++ target/arm/vfp.decode | 14 - target/arm/translate-m-nocp.c | 514 +++++++++++++++++++++++++++++++++ target/arm/translate-vfp.c | 517 +--------------------------------- 5 files changed, 542 insertions(+), 528 deletions(-) diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h index 0a0053949f5..abb3ecb6bc9 100644 --- a/target/arm/translate-a32.h +++ b/target/arm/translate-a32.h @@ -32,6 +32,7 @@ bool disas_neon_shared(DisasContext *s, uint32_t insn); void load_reg_var(DisasContext *s, TCGv_i32 var, int reg); void arm_gen_condlabel(DisasContext *s); bool vfp_access_check(DisasContext *s); +void gen_preserve_fp_state(DisasContext *s); void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop); void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop); void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop); diff --git a/target/arm/m-nocp.decode b/target/arm/m-nocp.decode index 6699626d7cb..b65c801c97c 100644 --- a/target/arm/m-nocp.decode +++ b/target/arm/m-nocp.decode @@ -34,6 +34,14 @@ =20 &nocp cp =20 +# M-profile VLDR/VSTR to sysreg +%vldr_sysreg 22:1 13:3 +%imm7_0x4 0:7 !function=3Dtimes_4 + +&vldr_sysreg rn reg imm a w p +@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \ + reg=3D%vldr_sysreg imm=3D%imm7_0x4 &vldr_sysreg + { # Special cases which do not take an early NOCP: VLLDM and VLSTM VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 op:1 000 0000 @@ -41,6 +49,22 @@ VSCCLRM 1110 1100 1.01 1111 .... 1011 imm:7 0 vd=3D%vd_dp size=3D3 VSCCLRM 1110 1100 1.01 1111 .... 1010 imm:8 vd=3D%vd_sp size=3D2 =20 + # FP system register accesses: these are a special case because accesses + # to FPCXT_NS succeed even if the FPU is disabled. We therefore need + # to handle them before the big NOCP blocks. Note that within these + # insns NOCP still has higher priority than UNDEFs; this is implemented + # by their returning 'false' for UNDEF so as to fall through into the + # NOCP check (in contrast to VLLDM etc, which call unallocated_encoding() + # for the UNDEFs there that must take precedence over NOCP.) + + VMSR_VMRS ---- 1110 111 l:1 reg:4 rt:4 1010 0001 0000 + + # P=3D0 W=3D0 is SEE "Related encodings", so split into two patterns + VLDR_sysreg ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg= p=3D1 + VLDR_sysreg ---- 110 0 . . 1 1 .... ... 0 111 11 ....... @vldr_sysreg= p=3D0 w=3D1 + VSTR_sysreg ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg= p=3D1 + VSTR_sysreg ---- 110 0 . . 1 0 .... ... 0 111 11 ....... @vldr_sysreg= p=3D0 w=3D1 + NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp # From v8.1M onwards this range will also NOCP: diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode index 52535d9b0b8..5405e80197b 100644 --- a/target/arm/vfp.decode +++ b/target/arm/vfp.decode @@ -84,20 +84,6 @@ VLDR_VSTR_hp ---- 1101 u:1 .0 l:1 rn:4 .... 1001 imm:8 = vd=3D%vd_sp VLDR_VSTR_sp ---- 1101 u:1 .0 l:1 rn:4 .... 1010 imm:8 vd=3D%vd_sp VLDR_VSTR_dp ---- 1101 u:1 .0 l:1 rn:4 .... 1011 imm:8 vd=3D%vd_dp =20 -# M-profile VLDR/VSTR to sysreg -%vldr_sysreg 22:1 13:3 -%imm7_0x4 0:7 !function=3Dtimes_4 - -&vldr_sysreg rn reg imm a w p -@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \ - reg=3D%vldr_sysreg imm=3D%imm7_0x4 &vldr_sysreg - -# P=3D0 W=3D0 is SEE "Related encodings", so split into two patterns -VLDR_sysreg ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg p= =3D1 -VLDR_sysreg ---- 110 0 . . 1 1 .... ... 0 111 11 ....... @vldr_sysreg p= =3D0 w=3D1 -VSTR_sysreg ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg p= =3D1 -VSTR_sysreg ---- 110 0 . . 1 0 .... ... 0 111 11 ....... @vldr_sysreg p= =3D0 w=3D1 - # We split the load/store multiple up into two patterns to avoid # overlap with other insns in the "Advanced SIMD load/store and 64-bit mov= e" # grouping: diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index 09b3be4ed31..17fd2bf2fb9 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -19,6 +19,7 @@ =20 #include "qemu/osdep.h" #include "tcg/tcg-op.h" +#include "tcg/tcg-op-gvec.h" #include "translate.h" #include "translate-a32.h" =20 @@ -191,6 +192,519 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLR= M *a) return true; } =20 +/* + * M-profile provides two different sets of instructions that can + * access floating point system registers: VMSR/VMRS (which move + * to/from a general purpose register) and VLDR/VSTR sysreg (which + * move directly to/from memory). In some cases there are also side + * effects which must happen after any write to memory (which could + * cause an exception). So we implement the common logic for the + * sysreg access in gen_M_fp_sysreg_write() and gen_M_fp_sysreg_read(), + * which take pointers to callback functions which will perform the + * actual "read/write general purpose register" and "read/write + * memory" operations. + */ + +/* + * Emit code to store the sysreg to its final destination; frees the + * TCG temp 'value' it is passed. + */ +typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 val= ue); +/* + * Emit code to load the value to be copied to the sysreg; returns + * a new TCG temporary + */ +typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque); + +/* Common decode/access checks for fp sysreg read/write */ +typedef enum FPSysRegCheckResult { + FPSysRegCheckFailed, /* caller should return false */ + FPSysRegCheckDone, /* caller should return true */ + FPSysRegCheckContinue, /* caller should continue generating code */ +} FPSysRegCheckResult; + +static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno) +{ + if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)= ) { + return FPSysRegCheckFailed; + } + + switch (regno) { + case ARM_VFP_FPSCR: + case QEMU_VFP_FPSCR_NZCV: + break; + case ARM_VFP_FPSCR_NZCVQC: + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return FPSysRegCheckFailed; + } + break; + case ARM_VFP_FPCXT_S: + case ARM_VFP_FPCXT_NS: + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return FPSysRegCheckFailed; + } + if (!s->v8m_secure) { + return FPSysRegCheckFailed; + } + break; + case ARM_VFP_VPR: + case ARM_VFP_P0: + if (!dc_isar_feature(aa32_mve, s)) { + return FPSysRegCheckFailed; + } + break; + default: + return FPSysRegCheckFailed; + } + + /* + * FPCXT_NS is a special case: it has specific handling for + * "current FP state is inactive", and must do the PreserveFPState() + * but not the usual full set of actions done by ExecuteFPCheck(). + * So we don't call vfp_access_check() and the callers must handle thi= s. + */ + if (regno !=3D ARM_VFP_FPCXT_NS && !vfp_access_check(s)) { + return FPSysRegCheckDone; + } + return FPSysRegCheckContinue; +} + +static void gen_branch_fpInactive(DisasContext *s, TCGCond cond, + TCGLabel *label) +{ + /* + * FPCXT_NS is a special case: it has specific handling for + * "current FP state is inactive", and must do the PreserveFPState() + * but not the usual full set of actions done by ExecuteFPCheck(). + * We don't have a TB flag that matches the fpInactive check, so we + * do it at runtime as we don't expect FPCXT_NS accesses to be frequen= t. + * + * Emit code that checks fpInactive and does a conditional + * branch to label based on it: + * if cond is TCG_COND_NE then branch if fpInactive !=3D 0 (ie if ina= ctive) + * if cond is TCG_COND_EQ then branch if fpInactive =3D=3D 0 (ie if a= ctive) + */ + assert(cond =3D=3D TCG_COND_EQ || cond =3D=3D TCG_COND_NE); + + /* fpInactive =3D FPCCR_NS.ASPEN =3D=3D 1 && CONTROL.FPCA =3D=3D 0 */ + TCGv_i32 aspen, fpca; + aspen =3D load_cpu_field(v7m.fpccr[M_REG_NS]); + fpca =3D load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); + tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); + tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK); + tcg_gen_or_i32(fpca, fpca, aspen); + tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label); + tcg_temp_free_i32(aspen); + tcg_temp_free_i32(fpca); +} + +static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, + fp_sysreg_loadfn *loadfn, + void *opaque) +{ + /* Do a write to an M-profile floating point system register */ + TCGv_i32 tmp; + TCGLabel *lab_end =3D NULL; + + switch (fp_sysreg_checks(s, regno)) { + case FPSysRegCheckFailed: + return false; + case FPSysRegCheckDone: + return true; + case FPSysRegCheckContinue: + break; + } + + switch (regno) { + case ARM_VFP_FPSCR: + tmp =3D loadfn(s, opaque); + gen_helper_vfp_set_fpscr(cpu_env, tmp); + tcg_temp_free_i32(tmp); + gen_lookup_tb(s); + break; + case ARM_VFP_FPSCR_NZCVQC: + { + TCGv_i32 fpscr; + tmp =3D loadfn(s, opaque); + if (dc_isar_feature(aa32_mve, s)) { + /* QC is only present for MVE; otherwise RES0 */ + TCGv_i32 qc =3D tcg_temp_new_i32(); + tcg_gen_andi_i32(qc, tmp, FPCR_QC); + /* + * The 4 vfp.qc[] fields need only be "zero" vs "non-zero"; + * here writing the same value into all elements is simplest. + */ + tcg_gen_gvec_dup_i32(MO_32, offsetof(CPUARMState, vfp.qc), + 16, 16, qc); + } + tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK); + fpscr =3D load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); + tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK); + tcg_gen_or_i32(fpscr, fpscr, tmp); + store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]); + tcg_temp_free_i32(tmp); + break; + } + case ARM_VFP_FPCXT_NS: + lab_end =3D gen_new_label(); + /* fpInactive case: write is a NOP, so branch to end */ + gen_branch_fpInactive(s, TCG_COND_NE, lab_end); + /* + * !fpInactive: if FPU disabled, take NOCP exception; + * otherwise PreserveFPState(), and then FPCXT_NS writes + * behave the same as FPCXT_S writes. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, s->pc_curr, EXCP_NOCP, + syn_uncategorized(), s->fp_excp_el); + /* + * This was only a conditional exception, so override + * gen_exception_insn()'s default to DISAS_NORETURN + */ + s->base.is_jmp =3D DISAS_NEXT; + break; + } + gen_preserve_fp_state(s); + /* fall through */ + case ARM_VFP_FPCXT_S: + { + TCGv_i32 sfpa, control; + /* + * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes + * bits [27:0] from value and zeroes bits [31:28]. + */ + tmp =3D loadfn(s, opaque); + sfpa =3D tcg_temp_new_i32(); + tcg_gen_shri_i32(sfpa, tmp, 31); + control =3D load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_deposit_i32(control, control, sfpa, + R_V7M_CONTROL_SFPA_SHIFT, 1); + store_cpu_field(control, v7m.control[M_REG_S]); + tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK); + gen_helper_vfp_set_fpscr(cpu_env, tmp); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(sfpa); + break; + } + case ARM_VFP_VPR: + /* Behaves as NOP if not privileged */ + if (IS_USER(s)) { + break; + } + tmp =3D loadfn(s, opaque); + store_cpu_field(tmp, v7m.vpr); + break; + case ARM_VFP_P0: + { + TCGv_i32 vpr; + tmp =3D loadfn(s, opaque); + vpr =3D load_cpu_field(v7m.vpr); + tcg_gen_deposit_i32(vpr, vpr, tmp, + R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH); + store_cpu_field(vpr, v7m.vpr); + tcg_temp_free_i32(tmp); + break; + } + default: + g_assert_not_reached(); + } + if (lab_end) { + gen_set_label(lab_end); + } + return true; +} + +static bool gen_M_fp_sysreg_read(DisasContext *s, int regno, + fp_sysreg_storefn *storefn, + void *opaque) +{ + /* Do a read from an M-profile floating point system register */ + TCGv_i32 tmp; + TCGLabel *lab_end =3D NULL; + bool lookup_tb =3D false; + + switch (fp_sysreg_checks(s, regno)) { + case FPSysRegCheckFailed: + return false; + case FPSysRegCheckDone: + return true; + case FPSysRegCheckContinue: + break; + } + + if (regno =3D=3D ARM_VFP_FPSCR_NZCVQC && !dc_isar_feature(aa32_mve, s)= ) { + /* QC is RES0 without MVE, so NZCVQC simplifies to NZCV */ + regno =3D QEMU_VFP_FPSCR_NZCV; + } + + switch (regno) { + case ARM_VFP_FPSCR: + tmp =3D tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(tmp, cpu_env); + storefn(s, opaque, tmp); + break; + case ARM_VFP_FPSCR_NZCVQC: + tmp =3D tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(tmp, cpu_env); + tcg_gen_andi_i32(tmp, tmp, FPCR_NZCVQC_MASK); + storefn(s, opaque, tmp); + break; + case QEMU_VFP_FPSCR_NZCV: + /* + * Read just NZCV; this is a special case to avoid the + * helper call for the "VMRS to CPSR.NZCV" insn. + */ + tmp =3D load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); + tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK); + storefn(s, opaque, tmp); + break; + case ARM_VFP_FPCXT_S: + { + TCGv_i32 control, sfpa, fpscr; + /* Bits [27:0] from FPSCR, bit [31] from CONTROL.SFPA */ + tmp =3D tcg_temp_new_i32(); + sfpa =3D tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(tmp, cpu_env); + tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK); + control =3D load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK); + tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT); + tcg_gen_or_i32(tmp, tmp, sfpa); + tcg_temp_free_i32(sfpa); + /* + * Store result before updating FPSCR etc, in case + * it is a memory write which causes an exception. + */ + storefn(s, opaque, tmp); + /* + * Now we must reset FPSCR from FPDSCR_NS, and clear + * CONTROL.SFPA; so we'll end the TB here. + */ + tcg_gen_andi_i32(control, control, ~R_V7M_CONTROL_SFPA_MASK); + store_cpu_field(control, v7m.control[M_REG_S]); + fpscr =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); + gen_helper_vfp_set_fpscr(cpu_env, fpscr); + tcg_temp_free_i32(fpscr); + lookup_tb =3D true; + break; + } + case ARM_VFP_FPCXT_NS: + { + TCGv_i32 control, sfpa, fpscr, fpdscr, zero; + TCGLabel *lab_active =3D gen_new_label(); + + lookup_tb =3D true; + + gen_branch_fpInactive(s, TCG_COND_EQ, lab_active); + /* fpInactive case: reads as FPDSCR_NS */ + TCGv_i32 tmp =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); + storefn(s, opaque, tmp); + lab_end =3D gen_new_label(); + tcg_gen_br(lab_end); + + gen_set_label(lab_active); + /* + * !fpInactive: if FPU disabled, take NOCP exception; + * otherwise PreserveFPState(), and then FPCXT_NS + * reads the same as FPCXT_S. + */ + if (s->fp_excp_el) { + gen_exception_insn(s, s->pc_curr, EXCP_NOCP, + syn_uncategorized(), s->fp_excp_el); + /* + * This was only a conditional exception, so override + * gen_exception_insn()'s default to DISAS_NORETURN + */ + s->base.is_jmp =3D DISAS_NEXT; + break; + } + gen_preserve_fp_state(s); + tmp =3D tcg_temp_new_i32(); + sfpa =3D tcg_temp_new_i32(); + fpscr =3D tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(fpscr, cpu_env); + tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK); + control =3D load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK); + tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT); + tcg_gen_or_i32(tmp, tmp, sfpa); + tcg_temp_free_i32(control); + /* Store result before updating FPSCR, in case it faults */ + storefn(s, opaque, tmp); + /* If SFPA is zero then set FPSCR from FPDSCR_NS */ + fpdscr =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); + zero =3D tcg_const_i32(0); + tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr); + gen_helper_vfp_set_fpscr(cpu_env, fpscr); + tcg_temp_free_i32(zero); + tcg_temp_free_i32(sfpa); + tcg_temp_free_i32(fpdscr); + tcg_temp_free_i32(fpscr); + break; + } + case ARM_VFP_VPR: + /* Behaves as NOP if not privileged */ + if (IS_USER(s)) { + break; + } + tmp =3D load_cpu_field(v7m.vpr); + storefn(s, opaque, tmp); + break; + case ARM_VFP_P0: + tmp =3D load_cpu_field(v7m.vpr); + tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LEN= GTH); + storefn(s, opaque, tmp); + break; + default: + g_assert_not_reached(); + } + + if (lab_end) { + gen_set_label(lab_end); + } + if (lookup_tb) { + gen_lookup_tb(s); + } + return true; +} + +static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value) +{ + arg_VMSR_VMRS *a =3D opaque; + + if (a->rt =3D=3D 15) { + /* Set the 4 flag bits in the CPSR */ + gen_set_nzcv(value); + tcg_temp_free_i32(value); + } else { + store_reg(s, a->rt, value); + } +} + +static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque) +{ + arg_VMSR_VMRS *a =3D opaque; + + return load_reg(s, a->rt); +} + +static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a) +{ + /* + * Accesses to R15 are UNPREDICTABLE; we choose to undef. + * FPSCR -> r15 is a special case which writes to the PSR flags; + * set a->reg to a special value to tell gen_M_fp_sysreg_read() + * we only care about the top 4 bits of FPSCR there. + */ + if (a->rt =3D=3D 15) { + if (a->l && a->reg =3D=3D ARM_VFP_FPSCR) { + a->reg =3D QEMU_VFP_FPSCR_NZCV; + } else { + return false; + } + } + + if (a->l) { + /* VMRS, move FP system register to gp register */ + return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_gpr, a); + } else { + /* VMSR, move gp register to FP system register */ + return gen_M_fp_sysreg_write(s, a->reg, gpr_to_fp_sysreg, a); + } +} + +static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 va= lue) +{ + arg_vldr_sysreg *a =3D opaque; + uint32_t offset =3D a->imm; + TCGv_i32 addr; + + if (!a->a) { + offset =3D -offset; + } + + addr =3D load_reg(s, a->rn); + if (a->p) { + tcg_gen_addi_i32(addr, addr, offset); + } + + if (s->v8m_stackcheck && a->rn =3D=3D 13 && a->w) { + gen_helper_v8m_stackcheck(cpu_env, addr); + } + + gen_aa32_st_i32(s, value, addr, get_mem_index(s), + MO_UL | MO_ALIGN | s->be_data); + tcg_temp_free_i32(value); + + if (a->w) { + /* writeback */ + if (!a->p) { + tcg_gen_addi_i32(addr, addr, offset); + } + store_reg(s, a->rn, addr); + } else { + tcg_temp_free_i32(addr); + } +} + +static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque) +{ + arg_vldr_sysreg *a =3D opaque; + uint32_t offset =3D a->imm; + TCGv_i32 addr; + TCGv_i32 value =3D tcg_temp_new_i32(); + + if (!a->a) { + offset =3D -offset; + } + + addr =3D load_reg(s, a->rn); + if (a->p) { + tcg_gen_addi_i32(addr, addr, offset); + } + + if (s->v8m_stackcheck && a->rn =3D=3D 13 && a->w) { + gen_helper_v8m_stackcheck(cpu_env, addr); + } + + gen_aa32_ld_i32(s, value, addr, get_mem_index(s), + MO_UL | MO_ALIGN | s->be_data); + + if (a->w) { + /* writeback */ + if (!a->p) { + tcg_gen_addi_i32(addr, addr, offset); + } + store_reg(s, a->rn, addr); + } else { + tcg_temp_free_i32(addr); + } + return value; +} + +static bool trans_VLDR_sysreg(DisasContext *s, arg_vldr_sysreg *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + if (a->rn =3D=3D 15) { + return false; + } + return gen_M_fp_sysreg_write(s, a->reg, memory_to_fp_sysreg, a); +} + +static bool trans_VSTR_sysreg(DisasContext *s, arg_vldr_sysreg *a) +{ + if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { + return false; + } + if (a->rn =3D=3D 15) { + return false; + } + return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_memory, a); +} + static bool trans_NOCP(DisasContext *s, arg_nocp *a) { /* diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 107d6143be8..8987ef2e5b9 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -109,7 +109,7 @@ static inline long vfp_f16_offset(unsigned reg, bool to= p) * Generate code for M-profile lazy FP state preservation if needed; * this corresponds to the pseudocode PreserveFPState() function. */ -static void gen_preserve_fp_state(DisasContext *s) +void gen_preserve_fp_state(DisasContext *s) { if (s->v7m_lspact) { /* @@ -663,435 +663,14 @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a) return true; } =20 -/* - * M-profile provides two different sets of instructions that can - * access floating point system registers: VMSR/VMRS (which move - * to/from a general purpose register) and VLDR/VSTR sysreg (which - * move directly to/from memory). In some cases there are also side - * effects which must happen after any write to memory (which could - * cause an exception). So we implement the common logic for the - * sysreg access in gen_M_fp_sysreg_write() and gen_M_fp_sysreg_read(), - * which take pointers to callback functions which will perform the - * actual "read/write general purpose register" and "read/write - * memory" operations. - */ - -/* - * Emit code to store the sysreg to its final destination; frees the - * TCG temp 'value' it is passed. - */ -typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 val= ue); -/* - * Emit code to load the value to be copied to the sysreg; returns - * a new TCG temporary - */ -typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque); - -/* Common decode/access checks for fp sysreg read/write */ -typedef enum FPSysRegCheckResult { - FPSysRegCheckFailed, /* caller should return false */ - FPSysRegCheckDone, /* caller should return true */ - FPSysRegCheckContinue, /* caller should continue generating code */ -} FPSysRegCheckResult; - -static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno) -{ - if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)= ) { - return FPSysRegCheckFailed; - } - - switch (regno) { - case ARM_VFP_FPSCR: - case QEMU_VFP_FPSCR_NZCV: - break; - case ARM_VFP_FPSCR_NZCVQC: - if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { - return FPSysRegCheckFailed; - } - break; - case ARM_VFP_FPCXT_S: - case ARM_VFP_FPCXT_NS: - if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { - return FPSysRegCheckFailed; - } - if (!s->v8m_secure) { - return FPSysRegCheckFailed; - } - break; - case ARM_VFP_VPR: - case ARM_VFP_P0: - if (!dc_isar_feature(aa32_mve, s)) { - return FPSysRegCheckFailed; - } - break; - default: - return FPSysRegCheckFailed; - } - - /* - * FPCXT_NS is a special case: it has specific handling for - * "current FP state is inactive", and must do the PreserveFPState() - * but not the usual full set of actions done by ExecuteFPCheck(). - * So we don't call vfp_access_check() and the callers must handle thi= s. - */ - if (regno !=3D ARM_VFP_FPCXT_NS && !vfp_access_check(s)) { - return FPSysRegCheckDone; - } - return FPSysRegCheckContinue; -} - -static void gen_branch_fpInactive(DisasContext *s, TCGCond cond, - TCGLabel *label) -{ - /* - * FPCXT_NS is a special case: it has specific handling for - * "current FP state is inactive", and must do the PreserveFPState() - * but not the usual full set of actions done by ExecuteFPCheck(). - * We don't have a TB flag that matches the fpInactive check, so we - * do it at runtime as we don't expect FPCXT_NS accesses to be frequen= t. - * - * Emit code that checks fpInactive and does a conditional - * branch to label based on it: - * if cond is TCG_COND_NE then branch if fpInactive !=3D 0 (ie if ina= ctive) - * if cond is TCG_COND_EQ then branch if fpInactive =3D=3D 0 (ie if a= ctive) - */ - assert(cond =3D=3D TCG_COND_EQ || cond =3D=3D TCG_COND_NE); - - /* fpInactive =3D FPCCR_NS.ASPEN =3D=3D 1 && CONTROL.FPCA =3D=3D 0 */ - TCGv_i32 aspen, fpca; - aspen =3D load_cpu_field(v7m.fpccr[M_REG_NS]); - fpca =3D load_cpu_field(v7m.control[M_REG_S]); - tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); - tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); - tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK); - tcg_gen_or_i32(fpca, fpca, aspen); - tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label); - tcg_temp_free_i32(aspen); - tcg_temp_free_i32(fpca); -} - -static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, - fp_sysreg_loadfn *loadfn, - void *opaque) -{ - /* Do a write to an M-profile floating point system register */ - TCGv_i32 tmp; - TCGLabel *lab_end =3D NULL; - - switch (fp_sysreg_checks(s, regno)) { - case FPSysRegCheckFailed: - return false; - case FPSysRegCheckDone: - return true; - case FPSysRegCheckContinue: - break; - } - - switch (regno) { - case ARM_VFP_FPSCR: - tmp =3D loadfn(s, opaque); - gen_helper_vfp_set_fpscr(cpu_env, tmp); - tcg_temp_free_i32(tmp); - gen_lookup_tb(s); - break; - case ARM_VFP_FPSCR_NZCVQC: - { - TCGv_i32 fpscr; - tmp =3D loadfn(s, opaque); - if (dc_isar_feature(aa32_mve, s)) { - /* QC is only present for MVE; otherwise RES0 */ - TCGv_i32 qc =3D tcg_temp_new_i32(); - tcg_gen_andi_i32(qc, tmp, FPCR_QC); - /* - * The 4 vfp.qc[] fields need only be "zero" vs "non-zero"; - * here writing the same value into all elements is simplest. - */ - tcg_gen_gvec_dup_i32(MO_32, offsetof(CPUARMState, vfp.qc), - 16, 16, qc); - } - tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK); - fpscr =3D load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); - tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK); - tcg_gen_or_i32(fpscr, fpscr, tmp); - store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]); - tcg_temp_free_i32(tmp); - break; - } - case ARM_VFP_FPCXT_NS: - lab_end =3D gen_new_label(); - /* fpInactive case: write is a NOP, so branch to end */ - gen_branch_fpInactive(s, TCG_COND_NE, lab_end); - /* - * !fpInactive: if FPU disabled, take NOCP exception; - * otherwise PreserveFPState(), and then FPCXT_NS writes - * behave the same as FPCXT_S writes. - */ - if (s->fp_excp_el) { - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, - syn_uncategorized(), s->fp_excp_el); - /* - * This was only a conditional exception, so override - * gen_exception_insn()'s default to DISAS_NORETURN - */ - s->base.is_jmp =3D DISAS_NEXT; - break; - } - gen_preserve_fp_state(s); - /* fall through */ - case ARM_VFP_FPCXT_S: - { - TCGv_i32 sfpa, control; - /* - * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes - * bits [27:0] from value and zeroes bits [31:28]. - */ - tmp =3D loadfn(s, opaque); - sfpa =3D tcg_temp_new_i32(); - tcg_gen_shri_i32(sfpa, tmp, 31); - control =3D load_cpu_field(v7m.control[M_REG_S]); - tcg_gen_deposit_i32(control, control, sfpa, - R_V7M_CONTROL_SFPA_SHIFT, 1); - store_cpu_field(control, v7m.control[M_REG_S]); - tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK); - gen_helper_vfp_set_fpscr(cpu_env, tmp); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(sfpa); - break; - } - case ARM_VFP_VPR: - /* Behaves as NOP if not privileged */ - if (IS_USER(s)) { - break; - } - tmp =3D loadfn(s, opaque); - store_cpu_field(tmp, v7m.vpr); - break; - case ARM_VFP_P0: - { - TCGv_i32 vpr; - tmp =3D loadfn(s, opaque); - vpr =3D load_cpu_field(v7m.vpr); - tcg_gen_deposit_i32(vpr, vpr, tmp, - R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH); - store_cpu_field(vpr, v7m.vpr); - tcg_temp_free_i32(tmp); - break; - } - default: - g_assert_not_reached(); - } - if (lab_end) { - gen_set_label(lab_end); - } - return true; -} - -static bool gen_M_fp_sysreg_read(DisasContext *s, int regno, - fp_sysreg_storefn *storefn, - void *opaque) -{ - /* Do a read from an M-profile floating point system register */ - TCGv_i32 tmp; - TCGLabel *lab_end =3D NULL; - bool lookup_tb =3D false; - - switch (fp_sysreg_checks(s, regno)) { - case FPSysRegCheckFailed: - return false; - case FPSysRegCheckDone: - return true; - case FPSysRegCheckContinue: - break; - } - - if (regno =3D=3D ARM_VFP_FPSCR_NZCVQC && !dc_isar_feature(aa32_mve, s)= ) { - /* QC is RES0 without MVE, so NZCVQC simplifies to NZCV */ - regno =3D QEMU_VFP_FPSCR_NZCV; - } - - switch (regno) { - case ARM_VFP_FPSCR: - tmp =3D tcg_temp_new_i32(); - gen_helper_vfp_get_fpscr(tmp, cpu_env); - storefn(s, opaque, tmp); - break; - case ARM_VFP_FPSCR_NZCVQC: - tmp =3D tcg_temp_new_i32(); - gen_helper_vfp_get_fpscr(tmp, cpu_env); - tcg_gen_andi_i32(tmp, tmp, FPCR_NZCVQC_MASK); - storefn(s, opaque, tmp); - break; - case QEMU_VFP_FPSCR_NZCV: - /* - * Read just NZCV; this is a special case to avoid the - * helper call for the "VMRS to CPSR.NZCV" insn. - */ - tmp =3D load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); - tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK); - storefn(s, opaque, tmp); - break; - case ARM_VFP_FPCXT_S: - { - TCGv_i32 control, sfpa, fpscr; - /* Bits [27:0] from FPSCR, bit [31] from CONTROL.SFPA */ - tmp =3D tcg_temp_new_i32(); - sfpa =3D tcg_temp_new_i32(); - gen_helper_vfp_get_fpscr(tmp, cpu_env); - tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK); - control =3D load_cpu_field(v7m.control[M_REG_S]); - tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK); - tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT); - tcg_gen_or_i32(tmp, tmp, sfpa); - tcg_temp_free_i32(sfpa); - /* - * Store result before updating FPSCR etc, in case - * it is a memory write which causes an exception. - */ - storefn(s, opaque, tmp); - /* - * Now we must reset FPSCR from FPDSCR_NS, and clear - * CONTROL.SFPA; so we'll end the TB here. - */ - tcg_gen_andi_i32(control, control, ~R_V7M_CONTROL_SFPA_MASK); - store_cpu_field(control, v7m.control[M_REG_S]); - fpscr =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); - gen_helper_vfp_set_fpscr(cpu_env, fpscr); - tcg_temp_free_i32(fpscr); - lookup_tb =3D true; - break; - } - case ARM_VFP_FPCXT_NS: - { - TCGv_i32 control, sfpa, fpscr, fpdscr, zero; - TCGLabel *lab_active =3D gen_new_label(); - - lookup_tb =3D true; - - gen_branch_fpInactive(s, TCG_COND_EQ, lab_active); - /* fpInactive case: reads as FPDSCR_NS */ - TCGv_i32 tmp =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); - storefn(s, opaque, tmp); - lab_end =3D gen_new_label(); - tcg_gen_br(lab_end); - - gen_set_label(lab_active); - /* - * !fpInactive: if FPU disabled, take NOCP exception; - * otherwise PreserveFPState(), and then FPCXT_NS - * reads the same as FPCXT_S. - */ - if (s->fp_excp_el) { - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, - syn_uncategorized(), s->fp_excp_el); - /* - * This was only a conditional exception, so override - * gen_exception_insn()'s default to DISAS_NORETURN - */ - s->base.is_jmp =3D DISAS_NEXT; - break; - } - gen_preserve_fp_state(s); - tmp =3D tcg_temp_new_i32(); - sfpa =3D tcg_temp_new_i32(); - fpscr =3D tcg_temp_new_i32(); - gen_helper_vfp_get_fpscr(fpscr, cpu_env); - tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK); - control =3D load_cpu_field(v7m.control[M_REG_S]); - tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK); - tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT); - tcg_gen_or_i32(tmp, tmp, sfpa); - tcg_temp_free_i32(control); - /* Store result before updating FPSCR, in case it faults */ - storefn(s, opaque, tmp); - /* If SFPA is zero then set FPSCR from FPDSCR_NS */ - fpdscr =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); - zero =3D tcg_const_i32(0); - tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr); - gen_helper_vfp_set_fpscr(cpu_env, fpscr); - tcg_temp_free_i32(zero); - tcg_temp_free_i32(sfpa); - tcg_temp_free_i32(fpdscr); - tcg_temp_free_i32(fpscr); - break; - } - case ARM_VFP_VPR: - /* Behaves as NOP if not privileged */ - if (IS_USER(s)) { - break; - } - tmp =3D load_cpu_field(v7m.vpr); - storefn(s, opaque, tmp); - break; - case ARM_VFP_P0: - tmp =3D load_cpu_field(v7m.vpr); - tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LEN= GTH); - storefn(s, opaque, tmp); - break; - default: - g_assert_not_reached(); - } - - if (lab_end) { - gen_set_label(lab_end); - } - if (lookup_tb) { - gen_lookup_tb(s); - } - return true; -} - -static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value) -{ - arg_VMSR_VMRS *a =3D opaque; - - if (a->rt =3D=3D 15) { - /* Set the 4 flag bits in the CPSR */ - gen_set_nzcv(value); - tcg_temp_free_i32(value); - } else { - store_reg(s, a->rt, value); - } -} - -static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque) -{ - arg_VMSR_VMRS *a =3D opaque; - - return load_reg(s, a->rt); -} - -static bool gen_M_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a) -{ - /* - * Accesses to R15 are UNPREDICTABLE; we choose to undef. - * FPSCR -> r15 is a special case which writes to the PSR flags; - * set a->reg to a special value to tell gen_M_fp_sysreg_read() - * we only care about the top 4 bits of FPSCR there. - */ - if (a->rt =3D=3D 15) { - if (a->l && a->reg =3D=3D ARM_VFP_FPSCR) { - a->reg =3D QEMU_VFP_FPSCR_NZCV; - } else { - return false; - } - } - - if (a->l) { - /* VMRS, move FP system register to gp register */ - return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_gpr, a); - } else { - /* VMSR, move gp register to FP system register */ - return gen_M_fp_sysreg_write(s, a->reg, gpr_to_fp_sysreg, a); - } -} - static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a) { TCGv_i32 tmp; bool ignore_vfp_enabled =3D false; =20 if (arm_dc_feature(s, ARM_FEATURE_M)) { - return gen_M_VMSR_VMRS(s, a); + /* M profile version was already handled in m-nocp.decode */ + return false; } =20 if (!dc_isar_feature(aa32_fpsp_v2, s)) { @@ -1227,96 +806,6 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR= _VMRS *a) return true; } =20 -static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 va= lue) -{ - arg_vldr_sysreg *a =3D opaque; - uint32_t offset =3D a->imm; - TCGv_i32 addr; - - if (!a->a) { - offset =3D -offset; - } - - addr =3D load_reg(s, a->rn); - if (a->p) { - tcg_gen_addi_i32(addr, addr, offset); - } - - if (s->v8m_stackcheck && a->rn =3D=3D 13 && a->w) { - gen_helper_v8m_stackcheck(cpu_env, addr); - } - - gen_aa32_st_i32(s, value, addr, get_mem_index(s), - MO_UL | MO_ALIGN | s->be_data); - tcg_temp_free_i32(value); - - if (a->w) { - /* writeback */ - if (!a->p) { - tcg_gen_addi_i32(addr, addr, offset); - } - store_reg(s, a->rn, addr); - } else { - tcg_temp_free_i32(addr); - } -} - -static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque) -{ - arg_vldr_sysreg *a =3D opaque; - uint32_t offset =3D a->imm; - TCGv_i32 addr; - TCGv_i32 value =3D tcg_temp_new_i32(); - - if (!a->a) { - offset =3D -offset; - } - - addr =3D load_reg(s, a->rn); - if (a->p) { - tcg_gen_addi_i32(addr, addr, offset); - } - - if (s->v8m_stackcheck && a->rn =3D=3D 13 && a->w) { - gen_helper_v8m_stackcheck(cpu_env, addr); - } - - gen_aa32_ld_i32(s, value, addr, get_mem_index(s), - MO_UL | MO_ALIGN | s->be_data); - - if (a->w) { - /* writeback */ - if (!a->p) { - tcg_gen_addi_i32(addr, addr, offset); - } - store_reg(s, a->rn, addr); - } else { - tcg_temp_free_i32(addr); - } - return value; -} - -static bool trans_VLDR_sysreg(DisasContext *s, arg_vldr_sysreg *a) -{ - if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { - return false; - } - if (a->rn =3D=3D 15) { - return false; - } - return gen_M_fp_sysreg_write(s, a->reg, memory_to_fp_sysreg, a); -} - -static bool trans_VSTR_sysreg(DisasContext *s, arg_vldr_sysreg *a) -{ - if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { - return false; - } - if (a->rn =3D=3D 15) { - return false; - } - return gen_M_fp_sysreg_read(s, a->reg, fp_sysreg_to_memory, a); -} =20 static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a) { --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025580; cv=none; d=zohomail.com; s=zohoarc; b=IDCaENigyIB9AHCZKmKeJ51y/N9xK9liPo5oAubq+k97u2ifiIVyZf40eyNqXB0xuEhY1NCBlfaptfX2mdscmdqh1NwKaUCfW40BNJ7TcwPAbKFghpEC1ddkV1eZISsWNrHnRd7h3Wz5q+SOG3+prHuTxApcesbP5xn3IFxhdcU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025580; h=Content-Transfer-Encoding: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=aTfR1HT9DaXFfl1KAFLCshDh3G+k5LtBMroZMj4avHE=; b=kDRbCTSdEvUxUarEPs/T9cX4ZKwxKEw6uU/TdG3TVsHKHXkevZMLrFymLNDHoLmr1pXFPF1iTT8hAeQKr1Hil9XVcU6WUKZ2IRWACgfRC29EmrzwKOdt+jT78gmJw3DJVpRSxGNs3XtLNa5wdCUVqhTQcIegW0bfV+RMr8hoYjc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025580808258.99361188643036; Fri, 18 Jun 2021 07:13:00 -0700 (PDT) Received: from localhost ([::1]:56428 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFEx-0001uu-Fh for importer@patchew.org; Fri, 18 Jun 2021 10:12:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49630) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCZ-0007Pj-JA for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:31 -0400 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:46972) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCV-00020D-96 for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:31 -0400 Received: by mail-wr1-x42e.google.com with SMTP id a11so10941371wrt.13 for ; Fri, 18 Jun 2021 07:10:26 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=aTfR1HT9DaXFfl1KAFLCshDh3G+k5LtBMroZMj4avHE=; b=C3vcTF1DzANCoVSt8aXcq1XROVLjxqmF4P0ErvPUYysy/hnHVLwT/28834EGwqxgCL Q7jd8QOUoflFRqMfxskBMPFGR6WBNXF6YBVETiFFZmVvLS0hcf0ZDdd2f9iVfwiIxSoM agXzILFmrsdCQJE+Wk5O98YcChmJYy2WA4nNbDTBh/IETjJtCmTKH/TlS7Rvtu9HXlST Nyj1t30SNSjo75aSk/IB51oCqRJWunT2eID2w37AWzqHQRslu2js5U585hULLC2Gp16K EbRlGWEtYV1E4lyXkfmEdbJQIoOD//6esFAM+n6bNlItEuXEhaToDpXYqzLJZZkFAP0Y ctVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=aTfR1HT9DaXFfl1KAFLCshDh3G+k5LtBMroZMj4avHE=; b=M8w97Ym/t4JhV5VTNjgXgrAAylAn1l4ED1tuevMF3oR/MAJ73NHONHqhdnqnsekjlb a3ExzfE1pkNYkR7dBqcajBNAmWxmGRUrCcO38/+eHYS+YAbD1MCPbT5aosGSWLgTAoWE XDUZpB+74dgEl6hgE1CE2CNNBwJ5W6EhstxAG2aY5+GXQozgSRbzquoM5o90EYFyPsbT QTVvb5pUv7rbQ83BEQmLgcBhLjRqCmRFfBt4475h6cODwf5e50E8cHepOuZ0ZYhwSHMM mWxZN/K4aEQkHdMlOqXr017VijThrEEjxAe+xyjhdnEfkWCaZa2x/Sqe1/myRk+hGD0d FgPA== X-Gm-Message-State: AOAM532+JN/M6xjzq+VbX33y0Mzaq205+mw5UNk+P6PbFkXOpSR5FsBO 2Zfp5RZsxIcU4vZq4XJzd/jCdw== X-Google-Smtp-Source: ABdhPJyn2t6G85xOJXQ+ve2CFT3U+R4rYUxqq1bX468SYkHPL7fe2LQ77bGvyHWQ99VKoU8QFptpzg== X-Received: by 2002:a05:6000:1c1:: with SMTP id t1mr12456873wrx.282.1624025425280; Fri, 18 Jun 2021 07:10:25 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 4/7] target/arm: Handle writeback in VLDR/VSTR sysreg with no memory access Date: Fri, 18 Jun 2021 15:10:16 +0100 Message-Id: <20210618141019.10671-5-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::42e; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" A few subcases of VLDR/VSTR sysreg succeed but do not perform a memory access: * VSTR of VPR when unprivileged * VLDR to VPR when unprivileged * VLDR to FPCXT_NS when fpInactive In these cases, even though we don't do the memory access we should still update the base register and perform the stack limit check if the insn's addressing mode specifies writeback. Our implementation failed to do this, because we handle these side-effects inside the memory_to_fp_sysreg() and fp_sysreg_to_memory() callback functions, which are only called if there's something to load or store. Fix this by adding an extra argument to the callbacks which is set to true to actually perform the access and false to only do side effects like writeback, and calling the callback with do_access =3D false for the three cases listed above. This produces slightly suboptimal code for the case of a write to FPCXT_NS when the FPU is inactive and the insn didn't have side effects (ie no writeback, or via VMSR), in which case we'll generate a conditional branch over an unconditional branch. But this doesn't seem to be important enough to merit requiring the callback to report back whether it generated any code or not. Cc: qemu-stable@nongnu.org Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/translate-m-nocp.c | 102 ++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index 17fd2bf2fb9..312a25f0589 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -207,14 +207,20 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLR= M *a) =20 /* * Emit code to store the sysreg to its final destination; frees the - * TCG temp 'value' it is passed. + * TCG temp 'value' it is passed. do_access is true to do the store, + * and false to skip it and only perform side-effects like base + * register writeback. */ -typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 val= ue); +typedef void fp_sysreg_storefn(DisasContext *s, void *opaque, TCGv_i32 val= ue, + bool do_access); /* * Emit code to load the value to be copied to the sysreg; returns - * a new TCG temporary + * a new TCG temporary. do_access is true to do the store, + * and false to skip it and only perform side-effects like base + * register writeback. */ -typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque); +typedef TCGv_i32 fp_sysreg_loadfn(DisasContext *s, void *opaque, + bool do_access); =20 /* Common decode/access checks for fp sysreg read/write */ typedef enum FPSysRegCheckResult { @@ -318,7 +324,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, =20 switch (regno) { case ARM_VFP_FPSCR: - tmp =3D loadfn(s, opaque); + tmp =3D loadfn(s, opaque, true); gen_helper_vfp_set_fpscr(cpu_env, tmp); tcg_temp_free_i32(tmp); gen_lookup_tb(s); @@ -326,7 +332,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, case ARM_VFP_FPSCR_NZCVQC: { TCGv_i32 fpscr; - tmp =3D loadfn(s, opaque); + tmp =3D loadfn(s, opaque, true); if (dc_isar_feature(aa32_mve, s)) { /* QC is only present for MVE; otherwise RES0 */ TCGv_i32 qc =3D tcg_temp_new_i32(); @@ -347,9 +353,19 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int= regno, break; } case ARM_VFP_FPCXT_NS: + { + TCGLabel *lab_active =3D gen_new_label(); + lab_end =3D gen_new_label(); - /* fpInactive case: write is a NOP, so branch to end */ - gen_branch_fpInactive(s, TCG_COND_NE, lab_end); + gen_branch_fpInactive(s, TCG_COND_EQ, lab_active); + /* + * fpInactive case: write is a NOP, so only do side effects + * like register writeback before we branch to end + */ + loadfn(s, opaque, false); + tcg_gen_br(lab_end); + + gen_set_label(lab_active); /* * !fpInactive: if FPU disabled, take NOCP exception; * otherwise PreserveFPState(), and then FPCXT_NS writes @@ -366,7 +382,8 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, break; } gen_preserve_fp_state(s); - /* fall through */ + } + /* fall through */ case ARM_VFP_FPCXT_S: { TCGv_i32 sfpa, control; @@ -374,7 +391,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes * bits [27:0] from value and zeroes bits [31:28]. */ - tmp =3D loadfn(s, opaque); + tmp =3D loadfn(s, opaque, true); sfpa =3D tcg_temp_new_i32(); tcg_gen_shri_i32(sfpa, tmp, 31); control =3D load_cpu_field(v7m.control[M_REG_S]); @@ -390,15 +407,16 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, in= t regno, case ARM_VFP_VPR: /* Behaves as NOP if not privileged */ if (IS_USER(s)) { + loadfn(s, opaque, false); break; } - tmp =3D loadfn(s, opaque); + tmp =3D loadfn(s, opaque, true); store_cpu_field(tmp, v7m.vpr); break; case ARM_VFP_P0: { TCGv_i32 vpr; - tmp =3D loadfn(s, opaque); + tmp =3D loadfn(s, opaque, true); vpr =3D load_cpu_field(v7m.vpr); tcg_gen_deposit_i32(vpr, vpr, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH); @@ -442,13 +460,13 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int= regno, case ARM_VFP_FPSCR: tmp =3D tcg_temp_new_i32(); gen_helper_vfp_get_fpscr(tmp, cpu_env); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); break; case ARM_VFP_FPSCR_NZCVQC: tmp =3D tcg_temp_new_i32(); gen_helper_vfp_get_fpscr(tmp, cpu_env); tcg_gen_andi_i32(tmp, tmp, FPCR_NZCVQC_MASK); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); break; case QEMU_VFP_FPSCR_NZCV: /* @@ -457,7 +475,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, */ tmp =3D load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); break; case ARM_VFP_FPCXT_S: { @@ -476,7 +494,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, * Store result before updating FPSCR etc, in case * it is a memory write which causes an exception. */ - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); /* * Now we must reset FPSCR from FPDSCR_NS, and clear * CONTROL.SFPA; so we'll end the TB here. @@ -499,7 +517,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, gen_branch_fpInactive(s, TCG_COND_EQ, lab_active); /* fpInactive case: reads as FPDSCR_NS */ TCGv_i32 tmp =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); lab_end =3D gen_new_label(); tcg_gen_br(lab_end); =20 @@ -531,7 +549,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, tcg_gen_or_i32(tmp, tmp, sfpa); tcg_temp_free_i32(control); /* Store result before updating FPSCR, in case it faults */ - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); /* If SFPA is zero then set FPSCR from FPDSCR_NS */ fpdscr =3D load_cpu_field(v7m.fpdscr[M_REG_NS]); zero =3D tcg_const_i32(0); @@ -546,15 +564,16 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int= regno, case ARM_VFP_VPR: /* Behaves as NOP if not privileged */ if (IS_USER(s)) { + storefn(s, opaque, NULL, false); break; } tmp =3D load_cpu_field(v7m.vpr); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); break; case ARM_VFP_P0: tmp =3D load_cpu_field(v7m.vpr); tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LEN= GTH); - storefn(s, opaque, tmp); + storefn(s, opaque, tmp, true); break; default: g_assert_not_reached(); @@ -569,10 +588,15 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int= regno, return true; } =20 -static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value) +static void fp_sysreg_to_gpr(DisasContext *s, void *opaque, TCGv_i32 value, + bool do_access) { arg_VMSR_VMRS *a =3D opaque; =20 + if (!do_access) { + return; + } + if (a->rt =3D=3D 15) { /* Set the 4 flag bits in the CPSR */ gen_set_nzcv(value); @@ -582,10 +606,13 @@ static void fp_sysreg_to_gpr(DisasContext *s, void *o= paque, TCGv_i32 value) } } =20 -static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque) +static TCGv_i32 gpr_to_fp_sysreg(DisasContext *s, void *opaque, bool do_ac= cess) { arg_VMSR_VMRS *a =3D opaque; =20 + if (!do_access) { + return NULL; + } return load_reg(s, a->rt); } =20 @@ -614,7 +641,8 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_V= MRS *a) } } =20 -static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 va= lue) +static void fp_sysreg_to_memory(DisasContext *s, void *opaque, TCGv_i32 va= lue, + bool do_access) { arg_vldr_sysreg *a =3D opaque; uint32_t offset =3D a->imm; @@ -624,6 +652,10 @@ static void fp_sysreg_to_memory(DisasContext *s, void = *opaque, TCGv_i32 value) offset =3D -offset; } =20 + if (!do_access && !a->w) { + return; + } + addr =3D load_reg(s, a->rn); if (a->p) { tcg_gen_addi_i32(addr, addr, offset); @@ -633,9 +665,11 @@ static void fp_sysreg_to_memory(DisasContext *s, void = *opaque, TCGv_i32 value) gen_helper_v8m_stackcheck(cpu_env, addr); } =20 - gen_aa32_st_i32(s, value, addr, get_mem_index(s), - MO_UL | MO_ALIGN | s->be_data); - tcg_temp_free_i32(value); + if (do_access) { + gen_aa32_st_i32(s, value, addr, get_mem_index(s), + MO_UL | MO_ALIGN | s->be_data); + tcg_temp_free_i32(value); + } =20 if (a->w) { /* writeback */ @@ -648,17 +682,22 @@ static void fp_sysreg_to_memory(DisasContext *s, void= *opaque, TCGv_i32 value) } } =20 -static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque) +static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, void *opaque, + bool do_access) { arg_vldr_sysreg *a =3D opaque; uint32_t offset =3D a->imm; TCGv_i32 addr; - TCGv_i32 value =3D tcg_temp_new_i32(); + TCGv_i32 value =3D NULL; =20 if (!a->a) { offset =3D -offset; } =20 + if (!do_access && !a->w) { + return NULL; + } + addr =3D load_reg(s, a->rn); if (a->p) { tcg_gen_addi_i32(addr, addr, offset); @@ -668,8 +707,11 @@ static TCGv_i32 memory_to_fp_sysreg(DisasContext *s, v= oid *opaque) gen_helper_v8m_stackcheck(cpu_env, addr); } =20 - gen_aa32_ld_i32(s, value, addr, get_mem_index(s), - MO_UL | MO_ALIGN | s->be_data); + if (do_access) { + value =3D tcg_temp_new_i32(); + gen_aa32_ld_i32(s, value, addr, get_mem_index(s), + MO_UL | MO_ALIGN | s->be_data); + } =20 if (a->w) { /* writeback */ --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025756; cv=none; d=zohomail.com; s=zohoarc; b=ElOTxLZPPJ7otBm4rGg3JDc1OFlfsLwGy57LYvWTSOENWSilbjLCNr+tXvbaBtDXz3m31iTEuTKGfZxuHa/PpnwiuAnvh+NImMUcnWwDobHxvvN7WOJ6dzlmkpZFU2gkqAhIPh2flHyjcdxZmY0TV21yJC9XzqwRMIkLn1/ddho= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025756; h=Content-Transfer-Encoding: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=pGYtozpvnJsI8f1HWKWhkwq5RfsGSkgw1OuyAEOVRpk=; b=lwZKR9WQMB0DpTZnCBE/PX9wopjL4ifds3p7+F17XQFHeL1IswvEGhYt4GOE6xCCx0hXRjKNXY1PA8sRlQs5zbMp0kQMuADxps9VbBe3zT3KxAXyrf8dCkHRMcwVD58QT6TV427GnO1TtMcpnGfoEhwJaa3tNsstjpEVvMg38Es= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025756881510.3152328538206; Fri, 18 Jun 2021 07:15:56 -0700 (PDT) Received: from localhost ([::1]:36892 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFHn-0007do-OF for importer@patchew.org; Fri, 18 Jun 2021 10:15:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCk-0007bG-TP for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:48 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:33517) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCV-00020z-Gi for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:42 -0400 Received: by mail-wr1-x433.google.com with SMTP id d11so8561868wrm.0 for ; Fri, 18 Jun 2021 07:10:27 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=pGYtozpvnJsI8f1HWKWhkwq5RfsGSkgw1OuyAEOVRpk=; b=BfG8W0kJbiP8zjiNotpPeFcCiXGjsYAC5JIj3qK2NQcKIP/CAMppq7ZSAy7pp4X4oH SkLWWacByCVREEKxXdQR0AY/5I+dEenMpeDOF5mCJ1JVP8qx/xR87DGHpK6JlG7oWeby fU9uc0HMU5JfxM9cgbjSY1Gx7CgTXsWCmRfRBeu4bkBw2pTGxp8wdX7VOXlEC53+DXO3 pf2kYUGXl3njig0lUNgSwkpCAFnLE7ffKJalIPEVwwGbF43y3/nrGGqFkljInf4OSgGW AXuxVnFcssjCOoZjDlkofthwIvBSYlzAvIBDi9tcx4gN0bP3s//9Xggu95c+Q9gGQ89F rUAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pGYtozpvnJsI8f1HWKWhkwq5RfsGSkgw1OuyAEOVRpk=; b=YhiD5+dDkpCbsJhzhVaFNySki+oGSLlCSO8PL/unNFYiyrSNWs+T/LZue+jCI8uVys DJta2M8SvZRfhHaqnocKLwcu/RNdBg01Tgz+zdeBDefGZQCp+MtB/7D28BT2NmtGCNMs X5TgDOF6UA0YsIgbHWBmxpifjG+tzqfDlUkwCS3YOQYkiiVypwGRj/QVvEN/HEL3B9tM TCx0rXO/VyCwiD0FQEHx9AumQTBl2P9jCnuH8J5Eb1TdplIHU9pxwHaD7yEWuIRUzlmg tdC+PseTESsLlTBvvE1ax4FTjBYTnCy56Ud1wh8Ui4Bmm957qDS3s4N+mUHcBKcMOhew VlNw== X-Gm-Message-State: AOAM532gyaglxQY7UGZaMgQH8Y3X2eTG22Cy+n3D3c1uKgNyZTKgtVQT AJ30Eo3AF7+MBpiNDBUs3hl++puMJ0AmHhXP X-Google-Smtp-Source: ABdhPJw5Vt0aMjVn5dIoe/WKsVD8iypgp0VQ4a5bTuUqmJTfrSF4o/lKwlPkZN6TPO5GhdCm0Pit+w== X-Received: by 2002:a05:6000:1084:: with SMTP id y4mr11463386wrw.173.1624025426065; Fri, 18 Jun 2021 07:10:26 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 5/7] target/arm: Factor FP context update code out into helper function Date: Fri, 18 Jun 2021 15:10:17 +0100 Message-Id: <20210618141019.10671-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::433; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Factor the code in full_vfp_access_check() which updates the ownership of the FP context and creates a new FP context out into its own function. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/translate-vfp.c | 104 +++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 8987ef2e5b9..85418dee2e4 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -131,6 +131,62 @@ void gen_preserve_fp_state(DisasContext *s) } } =20 +/* + * Generate code for M-profile FP context handling: update the + * ownership of the FP context, and create a new context if + * necessary. This corresponds to the parts of the pseudocode + * ExecuteFPCheck() after the inital PreserveFPState() call. + */ +static void gen_update_fp_context(DisasContext *s) +{ + /* Update ownership of FP context: set FPCCR.S to match current state = */ + if (s->v8m_fpccr_s_wrong) { + TCGv_i32 tmp; + + tmp =3D load_cpu_field(v7m.fpccr[M_REG_S]); + if (s->v8m_secure) { + tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK); + } else { + tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK); + } + store_cpu_field(tmp, v7m.fpccr[M_REG_S]); + /* Don't need to do this for any further FP insns in this TB */ + s->v8m_fpccr_s_wrong =3D false; + } + + if (s->v7m_new_fp_ctxt_needed) { + /* + * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA, + * the FPSCR, and VPR. + */ + TCGv_i32 control, fpscr; + uint32_t bits =3D R_V7M_CONTROL_FPCA_MASK; + + fpscr =3D load_cpu_field(v7m.fpdscr[s->v8m_secure]); + gen_helper_vfp_set_fpscr(cpu_env, fpscr); + tcg_temp_free_i32(fpscr); + if (dc_isar_feature(aa32_mve, s)) { + TCGv_i32 z32 =3D tcg_const_i32(0); + store_cpu_field(z32, v7m.vpr); + } + + /* + * We don't need to arrange to end the TB, because the only + * parts of FPSCR which we cache in the TB flags are the VECLEN + * and VECSTRIDE, and those don't exist for M-profile. + */ + + if (s->v8m_secure) { + bits |=3D R_V7M_CONTROL_SFPA_MASK; + } + control =3D load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_ori_i32(control, control, bits); + store_cpu_field(control, v7m.control[M_REG_S]); + /* Don't need to do this for any further FP insns in this TB */ + s->v7m_new_fp_ctxt_needed =3D false; + } +} + /* * Check that VFP access is enabled. If it is, do the necessary * M-profile lazy-FP handling and then return true. @@ -173,52 +229,8 @@ static bool full_vfp_access_check(DisasContext *s, boo= l ignore_vfp_enabled) /* Trigger lazy-state preservation if necessary */ gen_preserve_fp_state(s); =20 - /* Update ownership of FP context: set FPCCR.S to match current st= ate */ - if (s->v8m_fpccr_s_wrong) { - TCGv_i32 tmp; - - tmp =3D load_cpu_field(v7m.fpccr[M_REG_S]); - if (s->v8m_secure) { - tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK); - } else { - tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK); - } - store_cpu_field(tmp, v7m.fpccr[M_REG_S]); - /* Don't need to do this for any further FP insns in this TB */ - s->v8m_fpccr_s_wrong =3D false; - } - - if (s->v7m_new_fp_ctxt_needed) { - /* - * Create new FP context by updating CONTROL.FPCA, CONTROL.SFP= A, - * the FPSCR, and VPR. - */ - TCGv_i32 control, fpscr; - uint32_t bits =3D R_V7M_CONTROL_FPCA_MASK; - - fpscr =3D load_cpu_field(v7m.fpdscr[s->v8m_secure]); - gen_helper_vfp_set_fpscr(cpu_env, fpscr); - tcg_temp_free_i32(fpscr); - if (dc_isar_feature(aa32_mve, s)) { - TCGv_i32 z32 =3D tcg_const_i32(0); - store_cpu_field(z32, v7m.vpr); - } - - /* - * We don't need to arrange to end the TB, because the only - * parts of FPSCR which we cache in the TB flags are the VECLEN - * and VECSTRIDE, and those don't exist for M-profile. - */ - - if (s->v8m_secure) { - bits |=3D R_V7M_CONTROL_SFPA_MASK; - } - control =3D load_cpu_field(v7m.control[M_REG_S]); - tcg_gen_ori_i32(control, control, bits); - store_cpu_field(control, v7m.control[M_REG_S]); - /* Don't need to do this for any further FP insns in this TB */ - s->v7m_new_fp_ctxt_needed =3D false; - } + /* Update ownership of FP context and create new FP context if nee= ded */ + gen_update_fp_context(s); } =20 return true; --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025978; cv=none; d=zohomail.com; s=zohoarc; b=nlU3EBNfGaY2BYHhdA0hBgLXwoW6rx7TrMHOii2GbOoeNQRFSo8p7jSNdzrWIsdr7Z/EVkA84QQDUhOBr+MScjQmeC+kOuLkka0n603YanthEIcehui60c6+M1KPGPG4cQrIXkQjQckbMeB3QmWjndix7eQxuD5u7pLF1SGswYo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025978; h=Content-Transfer-Encoding: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=s+/OW/sFe2egCGOmpvnbQvn6rHu2TjvlR2dS4FiM/Es=; b=bGcUwrmmuQj3QKkZZBtSemOx8mjhK4l4D0tAq8eCieb3Mzei4zzAPz4h0Bcgq+EdmNvDDeBUs53XdtAmsJtIGehZUbilYRhnmfurMRl0F953I/ZWbVQZFosA8+oBbUkF8fcW0CCWdwloTegROk7uPg8GrKXZyjEJjMcx61+zJNk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025978442123.22500453648695; Fri, 18 Jun 2021 07:19:38 -0700 (PDT) Received: from localhost ([::1]:44690 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFLN-0004YB-Dm for importer@patchew.org; Fri, 18 Jun 2021 10:19:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49788) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFCu-0007kK-N1 for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:52 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:39570) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCW-00021Q-1b for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:52 -0400 Received: by mail-wr1-x433.google.com with SMTP id b3so680198wrm.6 for ; Fri, 18 Jun 2021 07:10:27 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=s+/OW/sFe2egCGOmpvnbQvn6rHu2TjvlR2dS4FiM/Es=; b=xVS0gbG06NwDSpb+gjm5ECyaDk+hbPjjXM7p23bOAQJJ65HLKnWQJ3wFDbtmGuPC6c OBj/qz8Hrh9UQy8LdTeeNvvDib39AET33++an0HMpv2+TvzkmQ5SEJII6ntgO5r0dk99 bc1+zJxM2p0s+d+L4US2gQPohd+qs+/ZpMuqZH1E53xiQ/0nZgoOBFhUZidOuqdi35te WWAa6a/rvs866+faDWMkkSE7lenHXxWUQu6er7fOTIipdyXiQkzUsmXbccCxba7QgEJP BWLoxCsev8fUycycxLvB75Py5eRBnKEBHpL3HuTnKxZY8q6wtUtR2VWIUCuDjWxW+7ys hnUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=s+/OW/sFe2egCGOmpvnbQvn6rHu2TjvlR2dS4FiM/Es=; b=nOm/el8YOHoq4Go8WJap4/M2bo4Be0KYQV0umTn3/kvNa1WCoftdoZuqzVs5Z5XhnF 2THxtw0xiSXvPtC3VxZtUsKSTRZ91l6pguxcTfb/cyZPseD1naYZMMV+8Y48TBkHjjJn /hAGCiSeHusFYy62bHt+7IXbqW2atJzti+xRSndgbPS/1dZRUNs9e1ObB52I5cvUxP98 e35nspgUpKfd6WIZdIGP0jQoQ5Bwuw6gzLNVP/hQj0gE8dR7YQukTOiADHzRdKW1zqLE bzcFq269pe0SkSOVatDQo5NRY8ecqzVvzyENwEgUSDxqCqjBSuom9J6FzagxujaGd2XT Mqbg== X-Gm-Message-State: AOAM5333PFh/XCsF7hVlwHhdOwE06X/1eXumbkfnvBzvC5phEHGJ511u jpTRok6k8AGJHpkmmo2Qkr4tMiYjTQ+E6cn7 X-Google-Smtp-Source: ABdhPJy2tL1+g8uAcKhAkc3PRW8RdFJSjbXBB07NBsboGH5fQWoFwd3Atnl4H+jt3rLuqJoShPrbAw== X-Received: by 2002:adf:e948:: with SMTP id m8mr12791619wrn.205.1624025426812; Fri, 18 Jun 2021 07:10:26 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 6/7] target/arm: Split vfp_access_check() into A and M versions Date: Fri, 18 Jun 2021 15:10:18 +0100 Message-Id: <20210618141019.10671-7-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::433; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" vfp_access_check and its helper routine full_vfp_access_check() has gradually grown and is now an awkward mix of A-profile only and M-profile only pieces. Refactor it into an A-profile only and an M-profile only version, taking advantage of the fact that now the only direct call to full_vfp_access_check() is in A-profile-only code. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/translate-vfp.c | 79 +++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 85418dee2e4..d89c7834faa 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -188,32 +188,19 @@ static void gen_update_fp_context(DisasContext *s) } =20 /* - * Check that VFP access is enabled. If it is, do the necessary - * M-profile lazy-FP handling and then return true. - * If not, emit code to generate an appropriate exception and - * return false. + * Check that VFP access is enabled, A-profile specific version. + * + * If VFP is enabled, return true. If not, emit code to generate an + * appropriate exception and return false. * The ignore_vfp_enabled argument specifies that we should ignore - * whether VFP is enabled via FPEXC[EN]: this should be true for FMXR/FMRX + * whether VFP is enabled via FPEXC.EN: this should be true for FMXR/FMRX * accesses to FPSID, FPEXC, MVFR0, MVFR1, MVFR2, and false for all other = insns. */ -static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled) +static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled) { if (s->fp_excp_el) { - if (arm_dc_feature(s, ARM_FEATURE_M)) { - /* - * M-profile mostly catches the "FPU disabled" case early, in - * disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP) - * which do coprocessor-checks are outside the large ranges of - * the encoding space handled by the patterns in m-nocp.decode, - * and for them we may need to raise NOCP here. - */ - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, - syn_uncategorized(), s->fp_excp_el); - } else { - gen_exception_insn(s, s->pc_curr, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, false), - s->fp_excp_el); - } + gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + syn_fp_access_trap(1, 0xe, false), s->fp_excp_e= l); return false; } =20 @@ -222,17 +209,39 @@ static bool full_vfp_access_check(DisasContext *s, bo= ol ignore_vfp_enabled) unallocated_encoding(s); return false; } + return true; +} =20 - if (arm_dc_feature(s, ARM_FEATURE_M)) { - /* Handle M-profile lazy FP state mechanics */ - - /* Trigger lazy-state preservation if necessary */ - gen_preserve_fp_state(s); - - /* Update ownership of FP context and create new FP context if nee= ded */ - gen_update_fp_context(s); +/* + * Check that VFP access is enabled, M-profile specific version. + * + * If VFP is enabled, do the necessary M-profile lazy-FP handling and then + * return true. If not, emit code to generate an appropriate exception and + * return false. + */ +static bool vfp_access_check_m(DisasContext *s) +{ + if (s->fp_excp_el) { + /* + * M-profile mostly catches the "FPU disabled" case early, in + * disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP) + * which do coprocessor-checks are outside the large ranges of + * the encoding space handled by the patterns in m-nocp.decode, + * and for them we may need to raise NOCP here. + */ + gen_exception_insn(s, s->pc_curr, EXCP_NOCP, + syn_uncategorized(), s->fp_excp_el); + return false; } =20 + /* Handle M-profile lazy FP state mechanics */ + + /* Trigger lazy-state preservation if necessary */ + gen_preserve_fp_state(s); + + /* Update ownership of FP context and create new FP context if needed = */ + gen_update_fp_context(s); + return true; } =20 @@ -242,7 +251,11 @@ static bool full_vfp_access_check(DisasContext *s, boo= l ignore_vfp_enabled) */ bool vfp_access_check(DisasContext *s) { - return full_vfp_access_check(s, false); + if (arm_dc_feature(s, ARM_FEATURE_M)) { + return vfp_access_check_m(s); + } else { + return vfp_access_check_a(s, false); + } } =20 static bool trans_VSEL(DisasContext *s, arg_VSEL *a) @@ -732,7 +745,11 @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_= VMRS *a) return false; } =20 - if (!full_vfp_access_check(s, ignore_vfp_enabled)) { + /* + * Call vfp_access_check_a() directly, because we need to tell + * it to ignore FPEXC.EN for some register accesses. + */ + if (!vfp_access_check_a(s, ignore_vfp_enabled)) { return true; } =20 --=20 2.20.1 From nobody Sat May 4 07:03:10 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1624025670; cv=none; d=zohomail.com; s=zohoarc; b=gAQIYFrJOdSR0d4hIinevWoh/kf05G0V7xu0zdQLssrTY/3LxB28d1gQgZKCKikgr1oAC9mX1bzEnECCG2gK1bPKIsec9ZO1AV+g6q6bS8Ov4MYqU2ATpbyG9OltpAXdS1TE6DAgBMZSFi81l5NbIzsvh1eHokK/fImtNONiDSU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1624025670; h=Content-Transfer-Encoding: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=+molS8q3eWVbDwFlz/CHxm2K6ekh34kuREu48aIPmN0=; b=Egq5jemMl9PIdTQIQmRXN6bDis0jCVin0i8ObSCdxFEg/e2N5G/aMzCPImXjQZ9hr31hYcjanjcEptwZuFZqASDpSksrvsQzTfq7sV+NbLWY7NoLoRi0ZkwaBDrVeIfJeKbXOOcSbntGskA9kmXnqHMretmV2MVMgI5mRYnqlDk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1624025670009871.2486167246277; Fri, 18 Jun 2021 07:14:30 -0700 (PDT) Received: from localhost ([::1]:60818 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1luFGO-0004o6-W2 for importer@patchew.org; Fri, 18 Jun 2021 10:14:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49832) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1luFD4-0007qy-1u for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:11:02 -0400 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:33509) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1luFCX-00022E-0E for qemu-devel@nongnu.org; Fri, 18 Jun 2021 10:10:56 -0400 Received: by mail-wr1-x42a.google.com with SMTP id d11so8561946wrm.0 for ; Fri, 18 Jun 2021 07:10:28 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id j11sm7751661wmq.4.2021.06.18.07.10.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Jun 2021 07:10:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+molS8q3eWVbDwFlz/CHxm2K6ekh34kuREu48aIPmN0=; b=hnQY7VSOol020/lQfDwncAEBW8biMqYG6KM8/euk+rR+bRtjsTTPQEieb2+jXGfhG0 XAFEX8E+ftqkm0CaiEePoPwuFkjCU5W23wmbpttzSIo+I/6slAvL4xPLZOTqh0kl8io0 zFMTHPK+QC1rJj+CH4ucizdai4D0GiDl8ZGbI2JEVkGLAGv4v2PFoYGX9GIe+2eYZlxK 1Mr9MbVOWuVvPBHF5JeKEY9wLttUjy/86r7xF4pt6FiSQtrAF+ZJdXODm8M2JIyQD0O7 Z7KeAqeWNu0tqbfeEdHjwpQJyGvZkZ8grhdFbxKcthSVv2qPhWm8brUeFXnbXvpD4+94 aELQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+molS8q3eWVbDwFlz/CHxm2K6ekh34kuREu48aIPmN0=; b=kNWTGlbclboEL/fLA+j88M9mzW13Nu5nFFbLVAZ/7Ytw2iMeXu7wUraHtndHdz66vv vIhV6woZcEOegkS0DODqeYa8KzGMbcWW8xb1KQJ9ykiyo2SzVVpXjY5rfly1NGyMUjmj C5CNKJYUcNvqWfim9WzQae2hduDipZi4yLZtQWnlEpGAyJhbA8alpXEybhPOhYHDK33X co3HYkaJzT8HCFQw/bqXYz51lrnkgIyYZVkJXdGURhAzEeIbVvRePJYMEC30rmU4CI0X rW1JfubLtk2IP25brzHj9AHIENr6rA6K9rEZNEyX0kQNCJ06zvuDdcmdTVMRZCPVqayC xf4A== X-Gm-Message-State: AOAM532wxB54z45S0LWYtXRn6YMLDwGDPTeUJpeK7yff2vm+YRMLnqmL n2cYVrohrIqSu5kihlVh5JD6jw== X-Google-Smtp-Source: ABdhPJwiD06KO42PWDPXdQwKbcNjkaWfvp8xbSlp7N7H+ktkHxSorMG7CrvyDXK4A8TyEWYPly1L1w== X-Received: by 2002:adf:c3d4:: with SMTP id d20mr12690820wrg.183.1624025427481; Fri, 18 Jun 2021 07:10:27 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH 7/7] target/arm: Handle FPU check for FPCXT_NS insns via vfp_access_check_m() Date: Fri, 18 Jun 2021 15:10:19 +0100 Message-Id: <20210618141019.10671-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210618141019.10671-1-peter.maydell@linaro.org> References: <20210618141019.10671-1-peter.maydell@linaro.org> 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=2a00:1450:4864:20::42a; envelope-from=peter.maydell@linaro.org; helo=mail-wr1-x42a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @linaro.org) Content-Type: text/plain; charset="utf-8" Instead of open-coding the "take NOCP exception if FPU disabled, otherwise call gen_preserve_fp_state()" code in the accessors for FPCXT_NS, add an argument to vfp_access_check_m() which tells it to skip the gen_update_fp_context() call, so we can use it for the FPCXT_NS case. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/translate-a32.h | 2 +- target/arm/translate-m-nocp.c | 10 ++-------- target/arm/translate-vfp.c | 13 ++++++++----- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h index abb3ecb6bc9..23264053006 100644 --- a/target/arm/translate-a32.h +++ b/target/arm/translate-a32.h @@ -32,7 +32,7 @@ bool disas_neon_shared(DisasContext *s, uint32_t insn); void load_reg_var(DisasContext *s, TCGv_i32 var, int reg); void arm_gen_condlabel(DisasContext *s); bool vfp_access_check(DisasContext *s); -void gen_preserve_fp_state(DisasContext *s); +bool vfp_access_check_m(DisasContext *s, bool skip_context_update); void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop); void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop); void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop); diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index 312a25f0589..5eab04832cd 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -371,9 +371,7 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, * otherwise PreserveFPState(), and then FPCXT_NS writes * behave the same as FPCXT_S writes. */ - if (s->fp_excp_el) { - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, - syn_uncategorized(), s->fp_excp_el); + if (!vfp_access_check_m(s, true)) { /* * This was only a conditional exception, so override * gen_exception_insn()'s default to DISAS_NORETURN @@ -381,7 +379,6 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int = regno, s->base.is_jmp =3D DISAS_NEXT; break; } - gen_preserve_fp_state(s); } /* fall through */ case ARM_VFP_FPCXT_S: @@ -527,9 +524,7 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, * otherwise PreserveFPState(), and then FPCXT_NS * reads the same as FPCXT_S. */ - if (s->fp_excp_el) { - gen_exception_insn(s, s->pc_curr, EXCP_NOCP, - syn_uncategorized(), s->fp_excp_el); + if (!vfp_access_check_m(s, true)) { /* * This was only a conditional exception, so override * gen_exception_insn()'s default to DISAS_NORETURN @@ -537,7 +532,6 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int r= egno, s->base.is_jmp =3D DISAS_NEXT; break; } - gen_preserve_fp_state(s); tmp =3D tcg_temp_new_i32(); sfpa =3D tcg_temp_new_i32(); fpscr =3D tcg_temp_new_i32(); diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index d89c7834faa..86e43c02dcd 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -109,7 +109,7 @@ static inline long vfp_f16_offset(unsigned reg, bool to= p) * Generate code for M-profile lazy FP state preservation if needed; * this corresponds to the pseudocode PreserveFPState() function. */ -void gen_preserve_fp_state(DisasContext *s) +static void gen_preserve_fp_state(DisasContext *s) { if (s->v7m_lspact) { /* @@ -218,8 +218,9 @@ static bool vfp_access_check_a(DisasContext *s, bool ig= nore_vfp_enabled) * If VFP is enabled, do the necessary M-profile lazy-FP handling and then * return true. If not, emit code to generate an appropriate exception and * return false. + * skip_context_update is true to skip the "update FP context" part of thi= s. */ -static bool vfp_access_check_m(DisasContext *s) +bool vfp_access_check_m(DisasContext *s, bool skip_context_update) { if (s->fp_excp_el) { /* @@ -239,8 +240,10 @@ static bool vfp_access_check_m(DisasContext *s) /* Trigger lazy-state preservation if necessary */ gen_preserve_fp_state(s); =20 - /* Update ownership of FP context and create new FP context if needed = */ - gen_update_fp_context(s); + if (!skip_context_update) { + /* Update ownership of FP context and create new FP context if nee= ded */ + gen_update_fp_context(s); + } =20 return true; } @@ -252,7 +255,7 @@ static bool vfp_access_check_m(DisasContext *s) bool vfp_access_check(DisasContext *s) { if (arm_dc_feature(s, ARM_FEATURE_M)) { - return vfp_access_check_m(s); + return vfp_access_check_m(s, false); } else { return vfp_access_check_a(s, false); } --=20 2.20.1