From e15aa7c5a76e2f731aed8b107ed742529f1b647d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 25 Feb 2021 15:10:36 -0500 Subject: [PATCH] target/arm: Implement the STGP instruction Backports commit 6439d67fc944cf29de94a160e9450a2063c7b515 from qemu --- qemu/target/arm/translate-a64.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 33cb474c..62222bdc 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -2877,7 +2877,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn) * +-----+-------+---+---+-------+---+-------+-------+------+------+ * * opc: LDP/STP/LDNP/STNP 00 -> 32 bit, 10 -> 64 bit - * LDPSW 01 + * LDPSW/STGP 01 * LDP/STP/LDNP/STNP (SIMD) 00 -> 32 bit, 01 -> 64 bit, 10 -> 128 bit * V: 0 -> GPR, 1 -> Vector * idx: 00 -> signed offset with non-temporal hint, 01 -> post-index, @@ -2903,6 +2903,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) bool is_signed = false; bool postindex = false; bool wback = false; + bool set_tag = false; TCGv_i64 clean_addr, dirty_addr; int size; @@ -2914,6 +2915,14 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) if (is_vector) { size = 2 + opc; + } else if (opc == 1 && !is_load) { + /* STGP */ + if (!dc_isar_feature(aa64_mte_insn_reg, s) || index == 0) { + unallocated_encoding(s); + return; + } + size = 3; + set_tag = true; } else { size = 2 + extract32(opc, 1, 1); is_signed = extract32(opc, 0, 1); @@ -2954,7 +2963,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) return; } - offset <<= size; + offset <<= (set_tag ? LOG2_TAG_GRANULE : size); if (rn == 31) { gen_check_sp_alignment(s); @@ -2964,8 +2973,22 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) if (!postindex) { tcg_gen_addi_i64(tcg_ctx, dirty_addr, dirty_addr, offset); } - clean_addr = clean_data_tbi(s, dirty_addr); + if (set_tag) { + if (!s->ata) { + /* + * TODO: We could rely on the stores below, at least for + * system mode, if we arrange to add MO_ALIGN_16. + */ + gen_helper_stg_stub(tcg_ctx, tcg_ctx->cpu_env, dirty_addr); + } else if (tb_cflags(s->base.tb) & CF_PARALLEL) { + gen_helper_stg_parallel(tcg_ctx, tcg_ctx->cpu_env, dirty_addr, dirty_addr); + } else { + gen_helper_stg(tcg_ctx, tcg_ctx->cpu_env, dirty_addr, dirty_addr); + } + } + + clean_addr = clean_data_tbi(s, dirty_addr); if (is_vector) { if (is_load) { do_fp_ld(s, rt, clean_addr, size);