From patchwork Mon Jun 14 15:09:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 12319137 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3563DC2B9F4 for ; Mon, 14 Jun 2021 15:13:05 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CCE6561352 for ; Mon, 14 Jun 2021 15:13:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CCE6561352 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lsoGt-00051d-Qf for qemu-devel@archiver.kernel.org; Mon, 14 Jun 2021 11:13:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47020) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lsoEI-0000Cx-KH for qemu-devel@nongnu.org; Mon, 14 Jun 2021 11:10:23 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:34518) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lsoEA-00006Y-FL for qemu-devel@nongnu.org; Mon, 14 Jun 2021 11:10:22 -0400 Received: by mail-wr1-x433.google.com with SMTP id q5so14961866wrm.1 for ; Mon, 14 Jun 2021 08:10:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bFPKFp45nN5eO3FRKR4QtYKgBEs29nCxbPeGKlUZ72Q=; b=w/kpVhWyIn7cDRCLMLbfOUw6zjwNxJmOQTZSIcGTobq6KsYTkYZIGEHA92f/jQlVxk X4rf/jyrTAEQmb2cNg4PAPBO5U+8UDxBNtP0Vm1zIxsvge1GdIqhZ+U2QawnDlfhYD41 k/jaWXjuSrj/qKjg6XmD7RyyiEvtsInQGW7YJ8iSpiWiZWiYSG0HUif1dl67p6E2Am/S YHIaUEDkTVq7LDbGj5fiTfdBdugP2YSsdYvpDCZiU4hTGQePeC/n35uq3Xvdva1oPFWk H2pmxXhprvmgk135lTWXcSs1HLelcOZeVFbCOpZrjmaPpgZPgFQ47feuKBdB/TSJAkJ+ GyFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bFPKFp45nN5eO3FRKR4QtYKgBEs29nCxbPeGKlUZ72Q=; b=Q7T/h5FCmhGecgMUdv11qwV9t7YKpGXUsul8NtPhyhLMxfiTEPpmcnsc6MuykzSmTN RDUqwjPw/or3R9gactUBLDLB8+hz/2MN43jErnKGlTlmdF6Y5/sDj3Obo2wfMLfescun ir3RPQIlP+RRtuHTTHH23RgM4NL327AOWvcCG9l4kB3pQcWRuc9QaKMwj7QMoBEhOC4a K4QSGIxXIgtDdYAeZa/MG1pdvD8Xvy312iQ3k2lfRi1/x7VelJv8IcESX2vhMj7JWbh7 hGW79L5klRgfaWfVzW35iHX3fKJPi5hCusf//IyBZ9iDfY3u5vAp0y8jNQoXo2ag8IgH FnJA== X-Gm-Message-State: AOAM532VSB9gebmBvMNS6xOowCYYWbHKdWXxokjXHIdMIXOl4xJbumRp APgUNMuxMAOD1fugHejiGKVN8Q== X-Google-Smtp-Source: ABdhPJycHgMU+DFc1+U9NWjhXpWGXiWI/UJfsIurtWBkOW7kexcYXRCS0aFpxFpQkcJBYX1NjntNiQ== X-Received: by 2002:adf:d1c9:: with SMTP id b9mr19382409wrd.101.1623683412857; Mon, 14 Jun 2021 08:10:12 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id b8sm20865639wmd.35.2021.06.14.08.10.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Jun 2021 08:10:12 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 03/57] target/arm: Handle VPR semantics in existing code Date: Mon, 14 Jun 2021 16:09:13 +0100 Message-Id: <20210614151007.4545-4-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210614151007.4545-1-peter.maydell@linaro.org> References: <20210614151007.4545-1-peter.maydell@linaro.org> MIME-Version: 1.0 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: , Cc: Richard Henderson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" When MVE is supported, the VPR register has a place on the exception stack frame in a previously reserved slot just above the FPSCR. It must also be zeroed in various situations when we invalidate FPU context. Update the code which handles the stack frames (exception entry and exit code, VLLDM, and VLSTM) to save/restore VPR. Update code which invalidates FP registers (mostly also exception entry and exit code, but also VSCCLRM and the code in full_vfp_access_check() that corresponds to the ExecuteFPCheck() pseudocode) to zero VPR. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/m_helper.c | 54 +++++++++++++++++++++++++++++------ target/arm/translate-m-nocp.c | 5 +++- target/arm/translate-vfp.c | 9 ++++-- 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index 074c5434550..7a1e35ab5b6 100644 --- a/target/arm/m_helper.c +++ b/target/arm/m_helper.c @@ -378,7 +378,7 @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env) uint32_t shi = extract64(dn, 32, 32); if (i >= 16) { - faddr += 8; /* skip the slot for the FPSCR */ + faddr += 8; /* skip the slot for the FPSCR/VPR */ } stacked_ok = stacked_ok && v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) && @@ -388,6 +388,11 @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env) stacked_ok = stacked_ok && v7m_stack_write(cpu, fpcar + 0x40, vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP); + if (cpu_isar_feature(aa32_mve, cpu)) { + stacked_ok = stacked_ok && + v7m_stack_write(cpu, fpcar + 0x44, + env->v7m.vpr, mmu_idx, STACK_LAZYFP); + } } /* @@ -410,16 +415,19 @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env) env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK; if (ts) { - /* Clear s0 to s31 and the FPSCR */ + /* Clear s0 to s31 and the FPSCR and VPR */ int i; for (i = 0; i < 32; i += 2) { *aa32_vfp_dreg(env, i / 2) = 0; } vfp_set_fpscr(env, 0); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = 0; + } } /* - * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them + * Otherwise s0 to s15, FPSCR and VPR are UNKNOWN; we choose to leave them * unchanged. */ } @@ -1044,6 +1052,7 @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr, void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) { /* fptr is the value of Rn, the frame pointer we store the FP regs to */ + ARMCPU *cpu = env_archcpu(env); bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK; bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK; uintptr_t ra = GETPC(); @@ -1092,9 +1101,12 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) cpu_stl_data_ra(env, faddr + 4, shi, ra); } cpu_stl_data_ra(env, fptr + 0x40, vfp_get_fpscr(env), ra); + if (cpu_isar_feature(aa32_mve, cpu)) { + cpu_stl_data_ra(env, fptr + 0x44, env->v7m.vpr, ra); + } /* - * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to + * If TS is 0 then s0 to s15, FPSCR and VPR are UNKNOWN; we choose to * leave them unchanged, matching our choice in v7m_preserve_fp_state. */ if (ts) { @@ -1102,6 +1114,9 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) *aa32_vfp_dreg(env, i / 2) = 0; } vfp_set_fpscr(env, 0); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = 0; + } } } else { v7m_update_fpccr(env, fptr, false); @@ -1112,6 +1127,7 @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr) void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr) { + ARMCPU *cpu = env_archcpu(env); uintptr_t ra = GETPC(); /* fptr is the value of Rn, the frame pointer we load the FP regs from */ @@ -1144,7 +1160,7 @@ void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr) uint32_t faddr = fptr + 4 * i; if (i >= 16) { - faddr += 8; /* skip the slot for the FPSCR */ + faddr += 8; /* skip the slot for the FPSCR and VPR */ } slo = cpu_ldl_data_ra(env, faddr, ra); @@ -1155,6 +1171,9 @@ void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr) } fpscr = cpu_ldl_data_ra(env, fptr + 0x40, ra); vfp_set_fpscr(env, fpscr); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = cpu_ldl_data_ra(env, fptr + 0x44, ra); + } } env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK; @@ -1298,7 +1317,7 @@ static bool v7m_push_stack(ARMCPU *cpu) uint32_t shi = extract64(dn, 32, 32); if (i >= 16) { - faddr += 8; /* skip the slot for the FPSCR */ + faddr += 8; /* skip the slot for the FPSCR and VPR */ } stacked_ok = stacked_ok && v7m_stack_write(cpu, faddr, slo, @@ -1309,11 +1328,19 @@ static bool v7m_push_stack(ARMCPU *cpu) stacked_ok = stacked_ok && v7m_stack_write(cpu, frameptr + 0x60, vfp_get_fpscr(env), mmu_idx, STACK_NORMAL); + if (cpu_isar_feature(aa32_mve, cpu)) { + stacked_ok = stacked_ok && + v7m_stack_write(cpu, frameptr + 0x64, + env->v7m.vpr, mmu_idx, STACK_NORMAL); + } if (cpacr_pass) { for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) { *aa32_vfp_dreg(env, i / 2) = 0; } vfp_set_fpscr(env, 0); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = 0; + } } } else { /* Lazy stacking enabled, save necessary info to stack later */ @@ -1536,13 +1563,16 @@ static void do_v7m_exception_exit(ARMCPU *cpu) v7m_exception_taken(cpu, excret, true, false); } } - /* Clear s0..s15 and FPSCR; TODO also VPR when MVE is implemented */ + /* Clear s0..s15, FPSCR and VPR */ int i; for (i = 0; i < 16; i += 2) { *aa32_vfp_dreg(env, i / 2) = 0; } vfp_set_fpscr(env, 0); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = 0; + } } } @@ -1771,7 +1801,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) uint32_t faddr = frameptr + 0x20 + 4 * i; if (i >= 16) { - faddr += 8; /* Skip the slot for the FPSCR */ + faddr += 8; /* Skip the slot for the FPSCR and VPR */ } pop_ok = pop_ok && @@ -1790,6 +1820,11 @@ static void do_v7m_exception_exit(ARMCPU *cpu) if (pop_ok) { vfp_set_fpscr(env, fpscr); } + if (cpu_isar_feature(aa32_mve, cpu)) { + pop_ok = pop_ok && + v7m_stack_read(cpu, &env->v7m.vpr, + frameptr + 0x64, mmu_idx); + } if (!pop_ok) { /* * These regs are 0 if security extension present; @@ -1799,6 +1834,9 @@ static void do_v7m_exception_exit(ARMCPU *cpu) *aa32_vfp_dreg(env, i / 2) = 0; } vfp_set_fpscr(env, 0); + if (cpu_isar_feature(aa32_mve, cpu)) { + env->v7m.vpr = 0; + } } } } diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c index d47eb8e1535..365810e582d 100644 --- a/target/arm/translate-m-nocp.c +++ b/target/arm/translate-m-nocp.c @@ -173,7 +173,10 @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a) btmreg++; } assert(btmreg == topreg + 1); - /* TODO: when MVE is implemented, zero VPR here */ + if (dc_isar_feature(aa32_mve, s)) { + TCGv_i32 z32 = tcg_const_i32(0); + store_cpu_field(z32, v7m.vpr); + } return true; } diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c index 728856dfd45..49f44347ad9 100644 --- a/target/arm/translate-vfp.c +++ b/target/arm/translate-vfp.c @@ -180,8 +180,8 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled) if (s->v7m_new_fp_ctxt_needed) { /* - * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA - * and the FPSCR. + * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA, + * the FPSCR, and VPR. */ TCGv_i32 control, fpscr; uint32_t bits = R_V7M_CONTROL_FPCA_MASK; @@ -189,6 +189,11 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled) fpscr = 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 = 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