Prepare to track changes to tbflags across the TB.
Signed-off-by: Richard Henderson <[email protected]>
---
target/arm/tcg/translate.h | 9 ++++
target/arm/tcg/translate-a64.c | 95 ++++++++++++++++++----------------
target/arm/tcg/translate.c | 60 ++++++++++-----------
3 files changed, 89 insertions(+), 75 deletions(-)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 57e45ea872..b9254d5524 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -75,6 +75,15 @@ typedef struct DisasContext {
bool eci_handled;
int sctlr_b;
MemOp be_data;
+
+ /*
+ * Current tbflags. During translation, starts as tb->flags
+ * but updated for known changes to cpu state. If at some
+ * point we encounter some unknowable change, set tbflags_invalid.
+ */
+ CPUARMTBFlags tbflags;
+ bool tbflags_invalid;
+
#if !defined(CONFIG_USER_ONLY)
int user;
#endif
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 0c712e7ac2..d8b6c1df41 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -497,6 +497,7 @@ static void a64_test_cc(DisasCompare64 *c64, int cc)
static void gen_rebuild_hflags(DisasContext *s)
{
gen_helper_rebuild_hflags_a64(tcg_env, tcg_constant_i32(s->current_el));
+ s->tbflags_invalid = true;
}
static void gen_exception_internal_insn(DisasContext *s, int excp)
@@ -11004,68 +11005,70 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
DisasContext *dc = container_of(dcbase, DisasContext, base);
CPUARMState *env = cpu_env(cpu);
ARMCPU *arm_cpu = env_archcpu(env);
- CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
int bound, core_mmu_idx;
dc->isar = &arm_cpu->isar;
dc->condjmp = 0;
dc->pc_save = dc->base.pc_first;
dc->aarch64 = true;
+
+ dc->tbflags = arm_tbflags_from_tb(dc->base.tb);
+
dc->thumb = false;
dc->sctlr_b = 0;
- dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
+ dc->be_data = EX_TBFLAG_ANY(dc->tbflags, BE_DATA) ? MO_BE : MO_LE;
dc->condexec_mask = 0;
dc->condexec_cond = 0;
- core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
+ core_mmu_idx = EX_TBFLAG_ANY(dc->tbflags, MMUIDX);
dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
- dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
- dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
- dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
+ dc->tbii = EX_TBFLAG_A64(dc->tbflags, TBII);
+ dc->tbid = EX_TBFLAG_A64(dc->tbflags, TBID);
+ dc->tcma = EX_TBFLAG_A64(dc->tbflags, TCMA);
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
#if !defined(CONFIG_USER_ONLY)
dc->user = (dc->current_el == 0);
#endif
- dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
- dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
- dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
- dc->pstate_uinj = EX_TBFLAG_ANY(tb_flags, PSTATE__UINJ);
- dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
- dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
- dc->trap_eret = EX_TBFLAG_A64(tb_flags, TRAP_ERET);
- dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
- dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
- dc->zt0_excp_el = EX_TBFLAG_A64(tb_flags, ZT0EXC_EL);
- dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
- dc->svl = (EX_TBFLAG_A64(tb_flags, SVL) + 1) * 16;
+ dc->fp_excp_el = EX_TBFLAG_ANY(dc->tbflags, FPEXC_EL);
+ dc->align_mem = EX_TBFLAG_ANY(dc->tbflags, ALIGN_MEM);
+ dc->pstate_il = EX_TBFLAG_ANY(dc->tbflags, PSTATE__IL);
+ dc->pstate_uinj = EX_TBFLAG_ANY(dc->tbflags, PSTATE__UINJ);
+ dc->fgt_active = EX_TBFLAG_ANY(dc->tbflags, FGT_ACTIVE);
+ dc->fgt_svc = EX_TBFLAG_ANY(dc->tbflags, FGT_SVC);
+ dc->trap_eret = EX_TBFLAG_A64(dc->tbflags, TRAP_ERET);
+ dc->sve_excp_el = EX_TBFLAG_A64(dc->tbflags, SVEEXC_EL);
+ dc->sme_excp_el = EX_TBFLAG_A64(dc->tbflags, SMEEXC_EL);
+ dc->zt0_excp_el = EX_TBFLAG_A64(dc->tbflags, ZT0EXC_EL);
+ dc->vl = (EX_TBFLAG_A64(dc->tbflags, VL) + 1) * 16;
+ dc->svl = (EX_TBFLAG_A64(dc->tbflags, SVL) + 1) * 16;
dc->max_svl = arm_cpu->sme_max_vq * 16;
dc->max_any_vl = MAX(dc->max_svl, arm_cpu->sve_max_vq * 16);
- dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
- dc->bt = EX_TBFLAG_A64(tb_flags, BT);
- dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
- dc->unpriv = EX_TBFLAG_A64(tb_flags, UNPRIV);
- dc->ata[0] = EX_TBFLAG_A64(tb_flags, ATA);
- dc->ata[1] = EX_TBFLAG_A64(tb_flags, ATA0);
- dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
- dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
- dc->mte_store_only[0] = EX_TBFLAG_A64(tb_flags, MTE_STORE_ONLY);
- dc->mte_store_only[1] = EX_TBFLAG_A64(tb_flags, MTE0_STORE_ONLY);
- dc->mtx = EX_TBFLAG_A64(tb_flags, MTX);
- dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
- dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
- dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
- dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
- dc->e2h = EX_TBFLAG_A64(tb_flags, E2H);
- dc->nv = EX_TBFLAG_A64(tb_flags, NV);
- dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
- dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
+ dc->pauth_active = EX_TBFLAG_A64(dc->tbflags, PAUTH_ACTIVE);
+ dc->bt = EX_TBFLAG_A64(dc->tbflags, BT);
+ dc->btype = EX_TBFLAG_A64(dc->tbflags, BTYPE);
+ dc->unpriv = EX_TBFLAG_A64(dc->tbflags, UNPRIV);
+ dc->ata[0] = EX_TBFLAG_A64(dc->tbflags, ATA);
+ dc->ata[1] = EX_TBFLAG_A64(dc->tbflags, ATA0);
+ dc->mte_active[0] = EX_TBFLAG_A64(dc->tbflags, MTE_ACTIVE);
+ dc->mte_active[1] = EX_TBFLAG_A64(dc->tbflags, MTE0_ACTIVE);
+ dc->mte_store_only[0] = EX_TBFLAG_A64(dc->tbflags, MTE_STORE_ONLY);
+ dc->mte_store_only[1] = EX_TBFLAG_A64(dc->tbflags, MTE0_STORE_ONLY);
+ dc->mtx = EX_TBFLAG_A64(dc->tbflags, MTX);
+ dc->pstate_sm = EX_TBFLAG_A64(dc->tbflags, PSTATE_SM);
+ dc->pstate_za = EX_TBFLAG_A64(dc->tbflags, PSTATE_ZA);
+ dc->sme_trap_nonstreaming = EX_TBFLAG_A64(dc->tbflags,
SME_TRAP_NONSTREAMING);
+ dc->naa = EX_TBFLAG_A64(dc->tbflags, NAA);
+ dc->e2h = EX_TBFLAG_A64(dc->tbflags, E2H);
+ dc->nv = EX_TBFLAG_A64(dc->tbflags, NV);
+ dc->nv1 = EX_TBFLAG_A64(dc->tbflags, NV1);
+ dc->nv2 = EX_TBFLAG_A64(dc->tbflags, NV2);
dc->nv2_mem_e20 = dc->nv2 && dc->e2h;
- dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
- dc->fpcr_ah = EX_TBFLAG_A64(tb_flags, AH);
- dc->fpcr_nep = EX_TBFLAG_A64(tb_flags, NEP);
- dc->gcs_en = EX_TBFLAG_A64(tb_flags, GCS_EN);
- dc->gcs_rvcen = EX_TBFLAG_A64(tb_flags, GCS_RVCEN);
- dc->gcsstr_el = EX_TBFLAG_A64(tb_flags, GCSSTR_EL);
- dc->fpmr_el = EX_TBFLAG_A64(tb_flags, FPMR_EL);
+ dc->nv2_mem_be = EX_TBFLAG_A64(dc->tbflags, NV2_MEM_BE);
+ dc->fpcr_ah = EX_TBFLAG_A64(dc->tbflags, AH);
+ dc->fpcr_nep = EX_TBFLAG_A64(dc->tbflags, NEP);
+ dc->gcs_en = EX_TBFLAG_A64(dc->tbflags, GCS_EN);
+ dc->gcs_rvcen = EX_TBFLAG_A64(dc->tbflags, GCS_RVCEN);
+ dc->gcsstr_el = EX_TBFLAG_A64(dc->tbflags, GCSSTR_EL);
+ dc->fpmr_el = EX_TBFLAG_A64(dc->tbflags, FPMR_EL);
dc->vec_len = 0;
dc->vec_stride = 0;
dc->cp_regs = arm_cpu->cp_regs;
@@ -11095,8 +11098,8 @@ static void
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
* emit code to generate a software step exception
* end the TB
*/
- dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
- dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
+ dc->ss_active = EX_TBFLAG_ANY(dc->tbflags, SS_ACTIVE);
+ dc->pstate_ss = EX_TBFLAG_ANY(dc->tbflags, PSTATE__SS);
dc->is_ldex = false;
/* Bound the number of insns to execute to those left on the page. */
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
index 6983153ffc..49d327de54 100644
--- a/target/arm/tcg/translate.c
+++ b/target/arm/tcg/translate.c
@@ -6389,7 +6389,6 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
DisasContext *dc = container_of(dcbase, DisasContext, base);
CPUARMState *env = cpu_env(cs);
ARMCPU *cpu = env_archcpu(env);
- CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
uint32_t condexec, core_mmu_idx;
bool d32dis = false;
@@ -6397,9 +6396,12 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
dc->condjmp = 0;
dc->pc_save = dc->base.pc_first;
dc->aarch64 = false;
- dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
- dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
- condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
+
+ dc->tbflags = arm_tbflags_from_tb(dc->base.tb);
+
+ dc->thumb = EX_TBFLAG_AM32(dc->tbflags, THUMB);
+ dc->be_data = EX_TBFLAG_ANY(dc->tbflags, BE_DATA) ? MO_BE : MO_LE;
+ condexec = EX_TBFLAG_AM32(dc->tbflags, CONDEXEC);
/*
* the CONDEXEC TB flags are CPSR bits [15:10][26:25]. On A-profile this
* is always the IT bits. On M-profile, some of the reserved encodings
@@ -6422,40 +6424,40 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
}
}
- core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
+ core_mmu_idx = EX_TBFLAG_ANY(dc->tbflags, MMUIDX);
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
#if !defined(CONFIG_USER_ONLY)
dc->user = (dc->current_el == 0);
#endif
- dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
- dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
- dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
- dc->pstate_uinj = EX_TBFLAG_ANY(tb_flags, PSTATE__UINJ);
- dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
- dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
+ dc->fp_excp_el = EX_TBFLAG_ANY(dc->tbflags, FPEXC_EL);
+ dc->align_mem = EX_TBFLAG_ANY(dc->tbflags, ALIGN_MEM);
+ dc->pstate_il = EX_TBFLAG_ANY(dc->tbflags, PSTATE__IL);
+ dc->pstate_uinj = EX_TBFLAG_ANY(dc->tbflags, PSTATE__UINJ);
+ dc->fgt_active = EX_TBFLAG_ANY(dc->tbflags, FGT_ACTIVE);
+ dc->fgt_svc = EX_TBFLAG_ANY(dc->tbflags, FGT_SVC);
if (arm_feature(env, ARM_FEATURE_M)) {
dc->vfp_enabled = 1;
- dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
- dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
- dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
- dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
+ dc->v7m_handler_mode = EX_TBFLAG_M32(dc->tbflags, HANDLER);
+ dc->v8m_secure = EX_TBFLAG_M32(dc->tbflags, SECURE);
+ dc->v8m_stackcheck = EX_TBFLAG_M32(dc->tbflags, STACKCHECK);
+ dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(dc->tbflags, FPCCR_S_WRONG);
dc->v7m_new_fp_ctxt_needed =
- EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
- dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
- dc->mve_no_pred = EX_TBFLAG_M32(tb_flags, MVE_NO_PRED);
+ EX_TBFLAG_M32(dc->tbflags, NEW_FP_CTXT_NEEDED);
+ dc->v7m_lspact = EX_TBFLAG_M32(dc->tbflags, LSPACT);
+ dc->mve_no_pred = EX_TBFLAG_M32(dc->tbflags, MVE_NO_PRED);
} else {
- dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
- dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
- dc->ns = EX_TBFLAG_A32(tb_flags, NS);
- dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
- dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
- dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
+ dc->sctlr_b = EX_TBFLAG_A32(dc->tbflags, SCTLR__B);
+ dc->hstr_active = EX_TBFLAG_A32(dc->tbflags, HSTR_ACTIVE);
+ dc->ns = EX_TBFLAG_A32(dc->tbflags, NS);
+ dc->vfp_enabled = EX_TBFLAG_A32(dc->tbflags, VFPEN);
+ dc->vec_len = EX_TBFLAG_A32(dc->tbflags, VECLEN);
+ dc->vec_stride = EX_TBFLAG_A32(dc->tbflags, VECSTRIDE);
dc->sme_trap_nonstreaming =
- EX_TBFLAG_A32(tb_flags, SME_TRAP_NONSTREAMING);
- dc->neon_excp_el = EX_TBFLAG_A32(tb_flags, NEONEXC_EL);
- d32dis = EX_TBFLAG_A32(tb_flags, D32DIS);
+ EX_TBFLAG_A32(dc->tbflags, SME_TRAP_NONSTREAMING);
+ dc->neon_excp_el = EX_TBFLAG_A32(dc->tbflags, NEONEXC_EL);
+ d32dis = EX_TBFLAG_A32(dc->tbflags, D32DIS);
}
dc->invalid_vfp_dreg_mask =
@@ -6481,8 +6483,8 @@ static void arm_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
* emit code to generate a software step exception
* end the TB
*/
- dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
- dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
+ dc->ss_active = EX_TBFLAG_ANY(dc->tbflags, SS_ACTIVE);
+ dc->pstate_ss = EX_TBFLAG_ANY(dc->tbflags, PSTATE__SS);
dc->is_ldex = false;
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
--
2.53.0