diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-06-06 10:19:37 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-06-06 10:19:37 +0100 |
commit | 3b97520c86e704b0533627c26b98173b71834bad (patch) | |
tree | 49ee5a074d3b5cd741a0b30bd1c67d51f14f57fa | |
parent | 0a9091424d71bcb4638daee6260bbeed498310c4 (diff) |
target/arm: Pass single_memop to gen_mte_checkN
Pass the individual memop to gen_mte_checkN.
For the moment, do nothing with it.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20230530191438.411344-14-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | target/arm/tcg/translate-a64.c | 31 | ||||
-rw-r--r-- | target/arm/tcg/translate-a64.h | 2 | ||||
-rw-r--r-- | target/arm/tcg/translate-sve.c | 4 |
3 files changed, 22 insertions, 15 deletions
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 85d896e975..0b60069596 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -285,7 +285,7 @@ TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write, * For MTE, check multiple logical sequential accesses. */ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, - bool tag_checked, int size) + bool tag_checked, int total_size, MemOp single_mop) { if (tag_checked && s->mte_active[0]) { TCGv_i64 ret; @@ -295,7 +295,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, 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, size - 1); + desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1); ret = tcg_temp_new_i64(); gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr); @@ -2841,14 +2841,12 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) bool is_vector = extract32(insn, 26, 1); bool is_load = extract32(insn, 22, 1); int opc = extract32(insn, 30, 2); - bool is_signed = false; bool postindex = false; bool wback = false; bool set_tag = false; - TCGv_i64 clean_addr, dirty_addr; - + MemOp mop; int size; if (opc == 3) { @@ -2931,12 +2929,17 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } } + if (is_vector) { + mop = finalize_memop_asimd(s, size); + } else { + mop = finalize_memop(s, size); + } clean_addr = gen_mte_checkN(s, dirty_addr, !is_load, - (wback || rn != 31) && !set_tag, 2 << size); + (wback || rn != 31) && !set_tag, + 2 << size, mop); if (is_vector) { - MemOp mop = finalize_memop_asimd(s, size); - + /* LSE2 does not merge FP pairs; leave these as separate operations. */ if (is_load) { do_fp_ld(s, rt, clean_addr, mop); } else { @@ -2951,9 +2954,11 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } else { TCGv_i64 tcg_rt = cpu_reg(s, rt); TCGv_i64 tcg_rt2 = cpu_reg(s, rt2); - MemOp mop = size + 1; /* + * We built mop above for the single logical access -- rebuild it + * now for the paired operation. + * * With LSE2, non-sign-extending pairs are treated atomically if * aligned, and if unaligned one of the pair will be completely * within a 16-byte block and that element will be atomic. @@ -2963,6 +2968,7 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) * This treats sign-extending loads like zero-extending loads, * since that reuses the most code below. */ + mop = size + 1; if (s->align_mem) { mop |= (size == 2 ? MO_ALIGN_4 : MO_ALIGN_8); } @@ -3741,7 +3747,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn) * promote consecutive little-endian elements below. */ clean_addr = gen_mte_checkN(s, tcg_rn, is_store, is_postidx || rn != 31, - total); + total, finalize_memop(s, size)); /* * Consecutive little-endian elements from a single register @@ -3899,10 +3905,11 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn) total = selem << scale; tcg_rn = cpu_reg_sp(s, rn); - clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31, - total); mop = finalize_memop(s, scale); + clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31, + total, mop); + tcg_ebytes = tcg_constant_i64(1 << scale); for (xs = 0; xs < selem; xs++) { if (replicate) { diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h index cecf2bab8f..b55dc435fc 100644 --- a/target/arm/tcg/translate-a64.h +++ b/target/arm/tcg/translate-a64.h @@ -51,7 +51,7 @@ 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, MemOp memop); TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, - bool tag_checked, int size); + bool tag_checked, int total_size, MemOp memop); /* We should have at some point before trying to access an FP register * done the necessary access check, so assert that diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c index 671d2efa85..ff050626e6 100644 --- a/target/arm/tcg/translate-sve.c +++ b/target/arm/tcg/translate-sve.c @@ -4176,7 +4176,7 @@ void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs, dirty_addr = tcg_temp_new_i64(); tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); - clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len); + clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8); /* * Note that unpredicated load/store of vector/predicate registers @@ -4278,7 +4278,7 @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs, dirty_addr = tcg_temp_new_i64(); tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); - clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len); + clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8); /* Note that unpredicated load/store of vector/predicate registers * are defined as a stream of bytes, which equates to little-endian |