From nobody Tue Feb 10 03:56:04 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1565050007; cv=none; d=zoho.com; s=zohoarc; b=nAVyPThUpcvDBcx0L3OrlZwMrCyurJ5617eaMdbafLr0/eYva8Qww7ysI3F7ptkSZyUDHNiFsZ9qgR1alFDO8nctEEYyazSjepOyULibb4lq3OuW+awtvMV6A3XIcMwADQ7KD4+9QFZoiQ7ep2BTcaBRluCxCcpCi84EBGszBqc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565050007; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=q3fMzXTaQgWcqA1jzonJJWI6KonpSOhpHjOAjFnriUA=; b=DWbUGdjs65N4yLSGjIM2NMLQ/mKalSdHQkLvlx1CjmWcGY/S/1033bJ8/2GPyxP38mZ/Lx/YhOmvWUW42y/jwZz9EjKG/H7tXgsZrWPg8norUqgiBRoxjzfpvGOl7jqhHQZ8cP4IYozcH8B8fOLFf3TWnAXrTEVkJqYocManOQk= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1565050007833646.6134477862937; Mon, 5 Aug 2019 17:06:47 -0700 (PDT) Received: from localhost ([::1]:57606 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hun02-0007rK-OJ for importer@patchew.org; Mon, 05 Aug 2019 20:06:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33661) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1humyZ-0003x7-GF for qemu-devel@nongnu.org; Mon, 05 Aug 2019 20:05:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1humyW-0008ED-Px for qemu-devel@nongnu.org; Mon, 05 Aug 2019 20:05:15 -0400 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]:45133) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1humyW-0008Dl-Hs for qemu-devel@nongnu.org; Mon, 05 Aug 2019 20:05:12 -0400 Received: by mail-pg1-x543.google.com with SMTP id o13so40529940pgp.12 for ; Mon, 05 Aug 2019 17:05:12 -0700 (PDT) Received: from localhost.localdomain (97-113-7-119.tukw.qwest.net. [97.113.7.119]) by smtp.gmail.com with ESMTPSA id i3sm92149782pfo.138.2019.08.05.17.05.09 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 05 Aug 2019 17:05:10 -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=q3fMzXTaQgWcqA1jzonJJWI6KonpSOhpHjOAjFnriUA=; b=Td4dCObyB69MfMWp17LHApSABP0W0K4ZGlODyP4AmFxjtqmrTvO67Ruz5m4Q6DONd8 7BjOREVdhEvqq1JMYGAHLq0eA88cEmuBlFRiqdfapooPJbFLRRL/gVyl9PTbLsMAl/L+ MBD0+P1dunAy67o4plvvXMbZAMGZp8FDDbf1B3efhhvNHJWk82sr8blyEXY/WsE8RvgW yFqecIcPi/3ukofzCYO8k1U8v4pJRJpeDQ3m32t7srv5iVtZoU9u/CdLZuamxyOg9RE5 Q4maoKamugRV/7K/zzxm8LCX37AvlQFuPTRp44J+nVyfBaMdQTr3YMwmmhrSJU574hPp Vp5A== 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=q3fMzXTaQgWcqA1jzonJJWI6KonpSOhpHjOAjFnriUA=; b=iFvbHXz/spIVlleylT5IyOivTqkL6EDr43zL96cysZTB4vjERh0TOEx84AhMP/1AKl xDBbasfoIoEz7bu8NkwrZGaK/2L0KHGrbsH4ipysx/muvF680Zt/Lo24ayJbyZ2OLctK f1GrlYR2r7X12YMFCcCRzsFNNIaUYaSGu38ly8YUvmgfDpkdwJSgb7FRuwSNe61OeiDv oknbjL27QupIyZWd0FnUi2Y1Cb6c5IqJgxhtEfe3xmO/9dE3StN4ErPWt4TeyBL4I7SJ YgJQfbA0d1GDwQaZSDkHQ8wEICubA7KjmJ1BPX+wEBLEpuhlMkxHWDo1A9hxXyZIAhcc HPyQ== X-Gm-Message-State: APjAAAXiz87bdVN/WB5qybZjr8WYIDUEkjrM+8nNYsSLSaRjN6TXPbjt RvciGvyQ/rvp/hWV5wPPwSt33hrPQ3o= X-Google-Smtp-Source: APXvYqy15pBDDKVn44OMS433RMZ0bY22N9aG0EQBsJXpYq+y95Ecv9Ozn3QzGE61T6/7zxS0SguzGA== X-Received: by 2002:a17:90a:8591:: with SMTP id m17mr309706pjn.100.1565049910997; Mon, 05 Aug 2019 17:05:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 5 Aug 2019 17:05:04 -0700 Message-Id: <20190806000506.10833-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190806000506.10833-1-richard.henderson@linaro.org> References: <20190806000506.10833-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::543 Subject: [Qemu-devel] [PATCH v4 1/3] target/arm: Split out recompute_hflags et al 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: peter.maydell@linaro.org, qemu-arm@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Create functions to compute the values of the a64 and a32 hflags, as well as one to compute the values that are shared between them. For now, the env->hflags variable is not used, and the results are fed back to cpu_get_tb_cpu_state. Tested-by: Alex Benn=C3=A9e Reviewed-by: Alex Benn=C3=A9e Signed-off-by: Richard Henderson --- v3: Do not cache VECLEN, VECSTRIDE, VFPEN. Move HANDLER and STACKCHECK to rebuild_hflags_a32. v4: Do not cache XSCALE_CPAR now that it overlaps VECSTRIDE. --- target/arm/cpu.h | 35 +++-- target/arm/helper.h | 3 + target/arm/internals.h | 3 + target/arm/helper.c | 322 ++++++++++++++++++++++++----------------- 4 files changed, 218 insertions(+), 145 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 94c990cddb..c13633e6a0 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -231,6 +231,9 @@ typedef struct CPUARMState { uint32_t pstate; uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.n= RW */ =20 + /* Cached TBFLAGS state. See below for which bits are included. */ + uint32_t hflags; + /* Frequently accessed CPSR bits are stored separately for efficiency. This contains all the other bits. Use cpsr_{read,write} to access the whole CPSR. */ @@ -3130,27 +3133,31 @@ typedef ARMCPU ArchCPU; =20 #include "exec/cpu-all.h" =20 -/* Bit usage in the TB flags field: bit 31 indicates whether we are +/* + * Bit usage in the TB flags field: bit 31 indicates whether we are * in 32 or 64 bit mode. The meaning of the other bits depends on that. * We put flags which are shared between 32 and 64 bit mode at the top * of the word, and flags which apply to only one mode at the bottom. + * + * Unless otherwise noted, these bits are cached in env->hflags. */ FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1) FIELD(TBFLAG_ANY, MMUIDX, 28, 3) FIELD(TBFLAG_ANY, SS_ACTIVE, 27, 1) -FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1) +FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1) /* Not cached. */ /* Target EL if we take a floating-point-disabled exception */ FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2) FIELD(TBFLAG_ANY, BE_DATA, 23, 1) =20 /* Bit usage when in AArch32 state: */ -FIELD(TBFLAG_A32, THUMB, 0, 1) -FIELD(TBFLAG_A32, VECLEN, 1, 3) -FIELD(TBFLAG_A32, VECSTRIDE, 4, 2) +FIELD(TBFLAG_A32, THUMB, 0, 1) /* Not cached. */ +FIELD(TBFLAG_A32, VECLEN, 1, 3) /* Not cached. */ +FIELD(TBFLAG_A32, VECSTRIDE, 4, 2) /* Not cached. */ /* * We store the bottom two bits of the CPAR as TB flags and handle * checks on the other bits at runtime. This shares the same bits as * VECSTRIDE, which is OK as no XScale CPU has VFP. + * Not cached, because VECLEN+VECSTRIDE are not cached. */ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2) /* @@ -3159,15 +3166,15 @@ FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2) * the same thing as the current security state of the processor! */ FIELD(TBFLAG_A32, NS, 6, 1) -FIELD(TBFLAG_A32, VFPEN, 7, 1) -FIELD(TBFLAG_A32, CONDEXEC, 8, 8) +FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Not cached. */ +FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */ FIELD(TBFLAG_A32, SCTLR_B, 16, 1) /* For M profile only, set if FPCCR.LSPACT is set */ -FIELD(TBFLAG_A32, LSPACT, 18, 1) +FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */ /* For M profile only, set if we must create a new FP context */ -FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1) +FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1) /* Not cached. */ /* For M profile only, set if FPCCR.S does not match current security stat= e */ -FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1) +FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1) /* Not cached. */ /* For M profile only, Handler (ie not Thread) mode */ FIELD(TBFLAG_A32, HANDLER, 21, 1) /* For M profile only, whether we should generate stack-limit checks */ @@ -3179,7 +3186,7 @@ FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2) FIELD(TBFLAG_A64, ZCR_LEN, 4, 4) FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1) FIELD(TBFLAG_A64, BT, 9, 1) -FIELD(TBFLAG_A64, BTYPE, 10, 2) +FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */ FIELD(TBFLAG_A64, TBID, 12, 2) =20 static inline bool bswap_code(bool sctlr_b) @@ -3264,6 +3271,12 @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, AR= MELChangeHookFn *hook, void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void *opaque); =20 +/** + * arm_rebuild_hflags: + * Rebuild the cached TBFLAGS for arbitrary changed processor state. + */ +void arm_rebuild_hflags(CPUARMState *env); + /** * aa32_vfp_dreg: * Return a pointer to the Dn register within env in 32-bit mode. diff --git a/target/arm/helper.h b/target/arm/helper.h index 132aa1682e..3919acbe63 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -91,6 +91,9 @@ DEF_HELPER_4(msr_banked, void, env, i32, i32, i32) DEF_HELPER_2(get_user_reg, i32, env, i32) DEF_HELPER_3(set_user_reg, void, env, i32, i32) =20 +DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, i32) +DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, i32) + DEF_HELPER_1(vfp_get_fpscr, i32, env) DEF_HELPER_2(vfp_set_fpscr, void, env, i32) =20 diff --git a/target/arm/internals.h b/target/arm/internals.h index 232d963875..db6f010798 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -992,6 +992,9 @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *en= v, uint64_t va, ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va, ARMMMUIdx mmu_idx, bool data); =20 +uint32_t rebuild_hflags_a32(CPUARMState *env, int el); +uint32_t rebuild_hflags_a64(CPUARMState *env, int el); + static inline int exception_target_el(CPUARMState *env) { int target_el =3D MAX(1, arm_current_el(env)); diff --git a/target/arm/helper.c b/target/arm/helper.c index b74c23a9bc..43b7c41f11 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11013,165 +11013,219 @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env) } #endif =20 -void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, - target_ulong *cs_base, uint32_t *pflags) +static uint32_t common_hflags(CPUARMState *env, int el, ARMMMUIdx mmu_idx, + int fp_el, uint32_t flags) { - ARMMMUIdx mmu_idx =3D arm_mmu_idx(env); - int current_el =3D arm_current_el(env); - int fp_el =3D fp_exception_el(env, current_el); - uint32_t flags =3D 0; - - if (is_a64(env)) { - ARMCPU *cpu =3D env_archcpu(env); - uint64_t sctlr; - - *pc =3D env->pc; - flags =3D FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1); - - /* Get control bits for tagged addresses. */ - { - ARMMMUIdx stage1 =3D stage_1_mmu_idx(mmu_idx); - ARMVAParameters p0 =3D aa64_va_parameters_both(env, 0, stage1); - int tbii, tbid; - - /* FIXME: ARMv8.1-VHE S2 translation regime. */ - if (regime_el(env, stage1) < 2) { - ARMVAParameters p1 =3D aa64_va_parameters_both(env, -1, st= age1); - tbid =3D (p1.tbi << 1) | p0.tbi; - tbii =3D tbid & ~((p1.tbid << 1) | p0.tbid); - } else { - tbid =3D p0.tbi; - tbii =3D tbid & !p0.tbid; - } - - flags =3D FIELD_DP32(flags, TBFLAG_A64, TBII, tbii); - flags =3D FIELD_DP32(flags, TBFLAG_A64, TBID, tbid); - } - - if (cpu_isar_feature(aa64_sve, cpu)) { - int sve_el =3D sve_exception_el(env, current_el); - uint32_t zcr_len; - - /* If SVE is disabled, but FP is enabled, - * then the effective len is 0. - */ - if (sve_el !=3D 0 && fp_el =3D=3D 0) { - zcr_len =3D 0; - } else { - zcr_len =3D sve_zcr_len_for_el(env, current_el); - } - flags =3D FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el); - flags =3D FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len); - } - - sctlr =3D arm_sctlr(env, current_el); - - if (cpu_isar_feature(aa64_pauth, cpu)) { - /* - * In order to save space in flags, we record only whether - * pauth is "inactive", meaning all insns are implemented as - * a nop, or "active" when some action must be performed. - * The decision of which action to take is left to a helper. - */ - if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB= )) { - flags =3D FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1); - } - } - - if (cpu_isar_feature(aa64_bti, cpu)) { - /* Note that SCTLR_EL[23].BT =3D=3D SCTLR_BT1. */ - if (sctlr & (current_el =3D=3D 0 ? SCTLR_BT0 : SCTLR_BT1)) { - flags =3D FIELD_DP32(flags, TBFLAG_A64, BT, 1); - } - flags =3D FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype); - } - } else { - *pc =3D env->regs[15]; - flags =3D FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb); - flags =3D FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len); - flags =3D FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_st= ride); - flags =3D FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bi= ts); - flags =3D FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env)); - flags =3D FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env= )); - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) - || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) { - flags =3D FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1); - } - /* Note that XSCALE_CPAR shares bits with VECSTRIDE */ - if (arm_feature(env, ARM_FEATURE_XSCALE)) { - flags =3D FIELD_DP32(flags, TBFLAG_A32, - XSCALE_CPAR, env->cp15.c15_cpar); - } - } - - flags =3D FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mm= u_idx)); - - /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine - * states defined in the ARM ARM for software singlestep: - * SS_ACTIVE PSTATE.SS State - * 0 x Inactive (the TB flag for SS is always 0) - * 1 0 Active-pending - * 1 1 Active-not-pending - */ - if (arm_singlestep_active(env)) { - flags =3D FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1); - if (is_a64(env)) { - if (env->pstate & PSTATE_SS) { - flags =3D FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1); - } - } else { - if (env->uncached_cpsr & PSTATE_SS) { - flags =3D FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1); - } - } - } + flags =3D FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el); + flags =3D FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, + arm_to_core_mmu_idx(mmu_idx)); if (arm_cpu_data_is_big_endian(env)) { flags =3D FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1); } - flags =3D FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el); + if (arm_singlestep_active(env)) { + flags =3D FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1); + } + return flags; +} + +uint32_t rebuild_hflags_a32(CPUARMState *env, int el) +{ + uint32_t flags =3D 0; + ARMMMUIdx mmu_idx; + int fp_el; + + flags =3D FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env)); + flags =3D FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env)); =20 if (arm_v7m_is_handler_mode(env)) { flags =3D FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1); } =20 - /* v8M always applies stack limit checks unless CCR.STKOFHFNMIGN is - * suppressing them because the requested execution priority is less t= han 0. + mmu_idx =3D arm_mmu_idx(env); + + /* + * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN + * is suppressing them because the requested execution priority + * is less than 0. */ if (arm_feature(env, ARM_FEATURE_V8) && arm_feature(env, ARM_FEATURE_M) && - !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) && + !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) && (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) { flags =3D FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1); } =20 - if (arm_feature(env, ARM_FEATURE_M_SECURITY) && - FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) !=3D env->v7m.se= cure) { - flags =3D FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1); + fp_el =3D fp_exception_el(env, el); + return common_hflags(env, el, mmu_idx, fp_el, flags); +} + +uint32_t rebuild_hflags_a64(CPUARMState *env, int el) +{ + ARMCPU *cpu =3D env_archcpu(env); + ARMMMUIdx mmu_idx =3D arm_mmu_idx(env); + ARMMMUIdx stage1 =3D stage_1_mmu_idx(mmu_idx); + ARMVAParameters p0 =3D aa64_va_parameters_both(env, 0, stage1); + int fp_el =3D fp_exception_el(env, el); + uint32_t flags =3D 0; + uint64_t sctlr; + int tbii, tbid; + + flags =3D FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1); + + /* Get control bits for tagged addresses. */ + /* FIXME: ARMv8.1-VHE S2 translation regime. */ + if (regime_el(env, stage1) < 2) { + ARMVAParameters p1 =3D aa64_va_parameters_both(env, -1, stage1); + tbid =3D (p1.tbi << 1) | p0.tbi; + tbii =3D tbid & ~((p1.tbid << 1) | p0.tbid); + } else { + tbid =3D p0.tbi; + tbii =3D tbid & !p0.tbid; } =20 - if (arm_feature(env, ARM_FEATURE_M) && - (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) && - (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) || - (env->v7m.secure && - !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) { - /* - * ASPEN is set, but FPCA/SFPA indicate that there is no active - * FP context; we must create a new FP context before executing - * any FP insn. + flags =3D FIELD_DP32(flags, TBFLAG_A64, TBII, tbii); + flags =3D FIELD_DP32(flags, TBFLAG_A64, TBID, tbid); + + if (cpu_isar_feature(aa64_sve, cpu)) { + int sve_el =3D sve_exception_el(env, el); + uint32_t zcr_len; + + /* If SVE is disabled, but FP is enabled, + * then the effective len is 0. */ - flags =3D FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1); + if (sve_el !=3D 0 && fp_el =3D=3D 0) { + zcr_len =3D 0; + } else { + zcr_len =3D sve_zcr_len_for_el(env, el); + } + flags =3D FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el); + flags =3D FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len); } =20 - if (arm_feature(env, ARM_FEATURE_M)) { - bool is_secure =3D env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK; - - if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) { - flags =3D FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1); + if (el =3D=3D 0) { + /* FIXME: ARMv8.1-VHE S2 translation regime. */ + sctlr =3D env->cp15.sctlr_el[1]; + } else { + sctlr =3D env->cp15.sctlr_el[el]; + } + if (cpu_isar_feature(aa64_pauth, cpu)) { + /* + * In order to save space in flags, we record only whether + * pauth is "inactive", meaning all insns are implemented as + * a nop, or "active" when some action must be performed. + * The decision of which action to take is left to a helper. + */ + if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) { + flags =3D FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1); } } =20 - *pflags =3D flags; + if (cpu_isar_feature(aa64_bti, cpu)) { + /* Note that SCTLR_EL[23].BT =3D=3D SCTLR_BT1. */ + if (sctlr & (el =3D=3D 0 ? SCTLR_BT0 : SCTLR_BT1)) { + flags =3D FIELD_DP32(flags, TBFLAG_A64, BT, 1); + } + } + + return common_hflags(env, el, mmu_idx, fp_el, flags); +} + +void arm_rebuild_hflags(CPUARMState *env) +{ + int el =3D arm_current_el(env); + env->hflags =3D (is_a64(env) + ? rebuild_hflags_a64(env, el) + : rebuild_hflags_a32(env, el)); +} + +void HELPER(rebuild_hflags_a32)(CPUARMState *env, uint32_t el) +{ + tcg_debug_assert(!is_a64(env)); + env->hflags =3D rebuild_hflags_a32(env, el); +} + +void HELPER(rebuild_hflags_a64)(CPUARMState *env, uint32_t el) +{ + tcg_debug_assert(is_a64(env)); + env->hflags =3D rebuild_hflags_a64(env, el); +} + +void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, + target_ulong *cs_base, uint32_t *pflags) +{ + int current_el =3D arm_current_el(env); + uint32_t flags; + uint32_t pstate_for_ss; + *cs_base =3D 0; + if (is_a64(env)) { + *pc =3D env->pc; + flags =3D rebuild_hflags_a64(env, current_el); + flags =3D FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype); + pstate_for_ss =3D env->pstate; + } else { + *pc =3D env->regs[15]; + flags =3D rebuild_hflags_a32(env, current_el); + flags =3D FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb); + flags =3D FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bi= ts); + /* Note that XSCALE_CPAR shares bits with VECSTRIDE */ + if (arm_feature(env, ARM_FEATURE_XSCALE)) { + flags =3D FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, + env->cp15.c15_cpar); + } else { + flags =3D FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_l= en); + flags =3D FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, + env->vfp.vec_stride); + } + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30) + || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) { + flags =3D FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1); + } + + /* TODO: Perhaps cache these bits too? */ + if (arm_feature(env, ARM_FEATURE_M)) { + if (arm_feature(env, ARM_FEATURE_M_SECURITY) && + FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) + !=3D env->v7m.secure) { + flags =3D FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1); + } + + if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK)= && + (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) || + (env->v7m.secure && + !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))= ) { + /* + * ASPEN is set, but FPCA/SFPA indicate that there is no + * active FP context; we must create a new FP context + * before executing any FP insn. + */ + flags =3D FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED= , 1); + } + + bool is_secure =3D env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MAS= K; + if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) { + flags =3D FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1); + } + } + + pstate_for_ss =3D env->uncached_cpsr; + } + + /* + * The SS_ACTIVE and PSTATE_SS bits correspond to the state machine + * states defined in the ARM ARM for software singlestep: + * SS_ACTIVE PSTATE.SS State + * 0 x Inactive (the TB flag for SS is always 0) + * 1 0 Active-pending + * 1 1 Active-not-pending + * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB. + */ + if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) + && (pstate_for_ss & PSTATE_SS)) { + flags =3D FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1); + } + + *pflags =3D flags; } =20 #ifdef TARGET_AARCH64 --=20 2.17.1