mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
target/arm: Implement GCSSTR, GCSSTTR
Note that CreateAccDescGCS() does not enable tagchecked, and Data Aborts from GCS instructions do not set iss.isv. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20251008215613.300150-47-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
0e15a9a53c
commit
6a5596bad3
@@ -571,6 +571,9 @@ LDAPR_i 10 011001 10 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext
|
||||
LDAPR_i 00 011001 11 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext=1 sz=0
|
||||
LDAPR_i 01 011001 11 0 ......... 00 ..... ..... @ldapr_stlr_i sign=1 ext=1 sz=1
|
||||
|
||||
# GCSSTR, GCSSTTR
|
||||
GCSSTR 11011001 000 11111 000 unpriv:1 11 rn:5 rt:5
|
||||
|
||||
# Load/store multiple structures
|
||||
# The 4-bit opcode in [15:12] encodes repeat count and structure elements
|
||||
&ldst_mult rm rn rt sz q p rpt selem
|
||||
|
||||
@@ -139,6 +139,12 @@ static int core_a64_user_mem_index(DisasContext *s, bool unpriv)
|
||||
return arm_to_core_mmu_idx(full_a64_user_mem_index(s, unpriv));
|
||||
}
|
||||
|
||||
/* For a given translation regime, return the core mmu_idx for gcs access. */
|
||||
static int core_gcs_mem_index(ARMMMUIdx armidx)
|
||||
{
|
||||
return arm_to_core_mmu_idx(regime_to_gcs(armidx));
|
||||
}
|
||||
|
||||
static void set_btype_raw(int val)
|
||||
{
|
||||
tcg_gen_st_i32(tcg_constant_i32(val), tcg_env,
|
||||
@@ -3989,6 +3995,42 @@ static bool trans_STLR_i(DisasContext *s, arg_ldapr_stlr_i *a)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_GCSSTR(DisasContext *s, arg_GCSSTR *a)
|
||||
{
|
||||
ARMMMUIdx armidx;
|
||||
|
||||
if (!dc_isar_feature(aa64_gcs, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The pseudocode for GCSSTTR is
|
||||
*
|
||||
* effective_el = AArch64.IsUnprivAccessPriv() ? PSTATE.EL : EL0;
|
||||
* if (effective_el == PSTATE.EL) CheckGCSSTREnabled();
|
||||
*
|
||||
* We have cached the result of IsUnprivAccessPriv in DisasContext,
|
||||
* but since we need the result of full_a64_user_mem_index anyway,
|
||||
* use the mmu_idx test as a proxy for the effective_el test.
|
||||
*/
|
||||
armidx = full_a64_user_mem_index(s, a->unpriv);
|
||||
if (armidx == s->mmu_idx && s->gcsstr_el != 0) {
|
||||
gen_exception_insn_el(s, 0, EXCP_UDEF,
|
||||
syn_gcs_gcsstr(a->rn, a->rt),
|
||||
s->gcsstr_el);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a->rn == 31) {
|
||||
gen_check_sp_alignment(s);
|
||||
}
|
||||
tcg_gen_qemu_st_i64(cpu_reg(s, a->rt),
|
||||
clean_data_tbi(s, cpu_reg_sp(s, a->rn)),
|
||||
core_gcs_mem_index(armidx),
|
||||
finalize_memop(s, MO_64 | MO_ALIGN));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_LD_mult(DisasContext *s, arg_ldst_mult *a)
|
||||
{
|
||||
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
|
||||
|
||||
Reference in New Issue
Block a user