From 0a9091424d71bcb4638daee6260bbeed498310c4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 6 Jun 2023 10:19:37 +0100 Subject: [PATCH] target/arm: Pass memop to gen_mte_check1* Pass the completed memop to gen_mte_check1_mmuidx. For the moment, do nothing more than extract the size. Reviewed-by: Peter Maydell Signed-off-by: Richard Henderson Message-id: 20230530191438.411344-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell --- target/arm/tcg/translate-a64.c | 82 ++++++++++++++++++---------------- target/arm/tcg/translate-a64.h | 2 +- target/arm/tcg/translate-sve.c | 7 +-- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 3e93f6e848..85d896e975 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -253,7 +253,7 @@ static void gen_probe_access(DisasContext *s, TCGv_i64 ptr, */ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr, bool is_write, bool tag_checked, - int log2_size, bool is_unpriv, + MemOp memop, bool is_unpriv, int core_idx) { if (tag_checked && s->mte_active[is_unpriv]) { @@ -264,7 +264,7 @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr, desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid); desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma); desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write); - desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << log2_size) - 1); + desc = FIELD_DP32(desc, MTEDESC, SIZEM1, memop_size(memop) - 1); ret = tcg_temp_new_i64(); gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr); @@ -275,9 +275,9 @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr, } TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write, - bool tag_checked, int log2_size) + bool tag_checked, MemOp memop) { - return gen_mte_check1_mmuidx(s, addr, is_write, tag_checked, log2_size, + return gen_mte_check1_mmuidx(s, addr, is_write, tag_checked, memop, false, get_mem_index(s)); } @@ -2369,19 +2369,31 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, int rn, int size, bool is_pair) { int idx = get_mem_index(s); - MemOp memop; TCGv_i64 dirty_addr, clean_addr; + MemOp memop; + + /* + * For pairs: + * if size == 2, the operation is single-copy atomic for the doubleword. + * if size == 3, the operation is single-copy atomic for *each* doubleword, + * not the entire quadword, however it must be quadword aligned. + */ + memop = size + is_pair; + if (memop == MO_128) { + memop = finalize_memop_atom(s, MO_128 | MO_ALIGN, + MO_ATOM_IFALIGN_PAIR); + } else { + memop = finalize_memop(s, memop | MO_ALIGN); + } s->is_ldex = true; dirty_addr = cpu_reg_sp(s, rn); - clean_addr = gen_mte_check1(s, dirty_addr, false, rn != 31, size); + clean_addr = gen_mte_check1(s, dirty_addr, false, rn != 31, memop); g_assert(size <= 3); if (is_pair) { g_assert(size >= 2); if (size == 2) { - /* The pair must be single-copy atomic for the doubleword. */ - memop = finalize_memop(s, MO_64 | MO_ALIGN); tcg_gen_qemu_ld_i64(cpu_exclusive_val, clean_addr, idx, memop); if (s->be_data == MO_LE) { tcg_gen_extract_i64(cpu_reg(s, rt), cpu_exclusive_val, 0, 32); @@ -2391,16 +2403,8 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, int rn, tcg_gen_extract_i64(cpu_reg(s, rt2), cpu_exclusive_val, 0, 32); } } else { - /* - * The pair must be single-copy atomic for *each* doubleword, not - * the entire quadword, however it must be quadword aligned. - * Expose the complete load to tcg, for ease of tlb lookup, - * but indicate that only 8-byte atomicity is required. - */ TCGv_i128 t16 = tcg_temp_new_i128(); - memop = finalize_memop_atom(s, MO_128 | MO_ALIGN_16, - MO_ATOM_IFALIGN_PAIR); tcg_gen_qemu_ld_i128(t16, clean_addr, idx, memop); if (s->be_data == MO_LE) { @@ -2414,7 +2418,6 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2, int rn, tcg_gen_mov_i64(cpu_reg(s, rt2), cpu_exclusive_high); } } else { - memop = finalize_memop(s, size | MO_ALIGN); tcg_gen_qemu_ld_i64(cpu_exclusive_val, clean_addr, idx, memop); tcg_gen_mov_i64(cpu_reg(s, rt), cpu_exclusive_val); } @@ -2439,9 +2442,13 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, TCGLabel *fail_label = gen_new_label(); TCGLabel *done_label = gen_new_label(); TCGv_i64 tmp, dirty_addr, clean_addr; + MemOp memop; + + memop = (size + is_pair) | MO_ALIGN; + memop = finalize_memop(s, memop); dirty_addr = cpu_reg_sp(s, rn); - clean_addr = gen_mte_check1(s, dirty_addr, true, rn != 31, size); + clean_addr = gen_mte_check1(s, dirty_addr, true, rn != 31, memop); tcg_gen_brcond_i64(TCG_COND_NE, clean_addr, cpu_exclusive_addr, fail_label); @@ -2455,8 +2462,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, } tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr, cpu_exclusive_val, tmp, - get_mem_index(s), - MO_64 | MO_ALIGN | s->be_data); + get_mem_index(s), memop); tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val); } else { TCGv_i128 t16 = tcg_temp_new_i128(); @@ -2474,8 +2480,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, } tcg_gen_atomic_cmpxchg_i128(t16, cpu_exclusive_addr, c16, t16, - get_mem_index(s), - MO_128 | MO_ALIGN | s->be_data); + get_mem_index(s), memop); a = tcg_temp_new_i64(); b = tcg_temp_new_i64(); @@ -2493,8 +2498,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, } } else { tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr, cpu_exclusive_val, - cpu_reg(s, rt), get_mem_index(s), - size | MO_ALIGN | s->be_data); + cpu_reg(s, rt), get_mem_index(s), memop); tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val); } tcg_gen_mov_i64(cpu_reg(s, rd), tmp); @@ -2513,13 +2517,15 @@ static void gen_compare_and_swap(DisasContext *s, int rs, int rt, TCGv_i64 tcg_rt = cpu_reg(s, rt); int memidx = get_mem_index(s); TCGv_i64 clean_addr; + MemOp memop; if (rn == 31) { gen_check_sp_alignment(s); } - clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, size); - tcg_gen_atomic_cmpxchg_i64(tcg_rs, clean_addr, tcg_rs, tcg_rt, memidx, - size | MO_ALIGN | s->be_data); + memop = finalize_memop(s, size | MO_ALIGN); + clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, memop); + tcg_gen_atomic_cmpxchg_i64(tcg_rs, clean_addr, tcg_rs, tcg_rt, + memidx, memop); } static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt, @@ -2531,13 +2537,15 @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt, TCGv_i64 t2 = cpu_reg(s, rt + 1); TCGv_i64 clean_addr; int memidx = get_mem_index(s); + MemOp memop; if (rn == 31) { gen_check_sp_alignment(s); } /* This is a single atomic access, despite the "pair". */ - clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, size + 1); + memop = finalize_memop(s, (size + 1) | MO_ALIGN); + clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, memop); if (size == 2) { TCGv_i64 cmp = tcg_temp_new_i64(); @@ -2551,8 +2559,7 @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt, tcg_gen_concat32_i64(cmp, s2, s1); } - tcg_gen_atomic_cmpxchg_i64(cmp, clean_addr, cmp, val, memidx, - MO_64 | MO_ALIGN | s->be_data); + tcg_gen_atomic_cmpxchg_i64(cmp, clean_addr, cmp, val, memidx, memop); if (s->be_data == MO_LE) { tcg_gen_extr32_i64(s1, s2, cmp); @@ -2571,8 +2578,7 @@ static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt, tcg_gen_concat_i64_i128(cmp, s2, s1); } - tcg_gen_atomic_cmpxchg_i128(cmp, clean_addr, cmp, val, memidx, - MO_128 | MO_ALIGN | s->be_data); + tcg_gen_atomic_cmpxchg_i128(cmp, clean_addr, cmp, val, memidx, memop); if (s->be_data == MO_LE) { tcg_gen_extr_i128_i64(s1, s2, cmp); @@ -2661,7 +2667,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) /* TODO: ARMv8.4-LSE SCTLR.nAA */ memop = finalize_memop(s, size | MO_ALIGN); clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), - true, rn != 31, size); + true, rn != 31, memop); do_gpr_st(s, cpu_reg(s, rt), clean_addr, memop, true, rt, disas_ldst_compute_iss_sf(size, false, 0), is_lasr); return; @@ -2680,7 +2686,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) /* TODO: ARMv8.4-LSE SCTLR.nAA */ memop = finalize_memop(s, size | MO_ALIGN); clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), - false, rn != 31, size); + false, rn != 31, memop); do_gpr_ld(s, cpu_reg(s, rt), clean_addr, memop, false, true, rt, disas_ldst_compute_iss_sf(size, false, 0), is_lasr); tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ); @@ -3223,7 +3229,7 @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn, tcg_gen_add_i64(dirty_addr, dirty_addr, tcg_rm); memop = finalize_memop(s, size + is_signed * MO_SIGN); - clean_addr = gen_mte_check1(s, dirty_addr, is_store, true, size); + clean_addr = gen_mte_check1(s, dirty_addr, is_store, true, memop); if (is_vector) { if (is_store) { @@ -3309,7 +3315,7 @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn, tcg_gen_addi_i64(dirty_addr, dirty_addr, offset); memop = finalize_memop(s, size + is_signed * MO_SIGN); - clean_addr = gen_mte_check1(s, dirty_addr, is_store, rn != 31, size); + clean_addr = gen_mte_check1(s, dirty_addr, is_store, rn != 31, memop); if (is_vector) { if (is_store) { @@ -3404,7 +3410,7 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn, if (rn == 31) { gen_check_sp_alignment(s); } - clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), false, rn != 31, size); + clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), false, rn != 31, mop); if (o3_opc == 014) { /* @@ -3491,7 +3497,7 @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn, /* Note that "clean" and "dirty" here refer to TBI not PAC. */ clean_addr = gen_mte_check1(s, dirty_addr, false, - is_wback || rn != 31, size); + is_wback || rn != 31, memop); tcg_rt = cpu_reg(s, rt); do_gpr_ld(s, tcg_rt, clean_addr, memop, diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h index 0576c4ea12..cecf2bab8f 100644 --- a/target/arm/tcg/translate-a64.h +++ b/target/arm/tcg/translate-a64.h @@ -49,7 +49,7 @@ static inline bool sme_smza_enabled_check(DisasContext *s) TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr); TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write, - bool tag_checked, int log2_size); + bool tag_checked, MemOp memop); TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, bool tag_checked, int size); diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index 57051a4729..671d2efa85 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -5009,6 +5009,7 @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a) unsigned msz = dtype_msz(a->dtype); TCGLabel *over; TCGv_i64 temp, clean_addr; + MemOp memop; if (!dc_isar_feature(aa64_sve, s)) { return false; @@ -5038,10 +5039,10 @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a) /* Load the data. */ temp = tcg_temp_new_i64(); tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << msz); - clean_addr = gen_mte_check1(s, temp, false, true, msz); - tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s), - finalize_memop(s, dtype_mop[a->dtype])); + memop = finalize_memop(s, dtype_mop[a->dtype]); + clean_addr = gen_mte_check1(s, temp, false, true, memop); + tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s), memop); /* Broadcast to *all* elements. */ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd), -- 2.30.2