Pass the individual memop to gen_mte_checkN. For the moment, do nothing with it.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/arm/translate-a64.h | 2 +- target/arm/translate-a64.c | 26 +++++++++++++++----------- target/arm/translate-sve.c | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h index 3fc39763d0..b7518f9d34 100644 --- a/target/arm/translate-a64.h +++ b/target/arm/translate-a64.h @@ -54,7 +54,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 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/translate-a64.c b/target/arm/translate-a64.c index e02bdd3e7c..1117a1cc41 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -288,7 +288,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; @@ -298,7 +298,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 = new_tmp_a64(s); gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr); @@ -2983,14 +2983,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) { @@ -3073,11 +3071,13 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } } + 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(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 { @@ -3092,9 +3092,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) | s->be_data; /* + * 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. @@ -3104,6 +3106,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) | s->be_data; mop |= size << MO_ATMAX_SHIFT; mop |= s->atom_data; if (s->align_mem) { @@ -3887,7 +3890,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 @@ -4045,10 +4048,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/translate-sve.c b/target/arm/translate-sve.c index f283322cda..6a89126fc5 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -4321,7 +4321,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); tcg_temp_free_i64(dirty_addr); /* @@ -4450,7 +4450,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); tcg_temp_free_i64(dirty_addr); /* Note that unpredicated load/store of vector/predicate registers -- 2.34.1