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>
This commit is contained in:
Richard Henderson 2023-06-06 10:19:37 +01:00 committed by Peter Maydell
parent 0a9091424d
commit 3b97520c86
3 changed files with 22 additions and 15 deletions

View File

@ -285,7 +285,7 @@ TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
* For MTE, check multiple logical sequential accesses. * For MTE, check multiple logical sequential accesses.
*/ */
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, 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]) { if (tag_checked && s->mte_active[0]) {
TCGv_i64 ret; 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, TBI, s->tbid);
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma); desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write); 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(); ret = tcg_temp_new_i64();
gen_helper_mte_check(ret, cpu_env, tcg_constant_i32(desc), addr); 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_vector = extract32(insn, 26, 1);
bool is_load = extract32(insn, 22, 1); bool is_load = extract32(insn, 22, 1);
int opc = extract32(insn, 30, 2); int opc = extract32(insn, 30, 2);
bool is_signed = false; bool is_signed = false;
bool postindex = false; bool postindex = false;
bool wback = false; bool wback = false;
bool set_tag = false; bool set_tag = false;
TCGv_i64 clean_addr, dirty_addr; TCGv_i64 clean_addr, dirty_addr;
MemOp mop;
int size; int size;
if (opc == 3) { 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, 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) { if (is_vector) {
MemOp mop = finalize_memop_asimd(s, size); /* LSE2 does not merge FP pairs; leave these as separate operations. */
if (is_load) { if (is_load) {
do_fp_ld(s, rt, clean_addr, mop); do_fp_ld(s, rt, clean_addr, mop);
} else { } else {
@ -2951,9 +2954,11 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
} else { } else {
TCGv_i64 tcg_rt = cpu_reg(s, rt); TCGv_i64 tcg_rt = cpu_reg(s, rt);
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2); 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 * With LSE2, non-sign-extending pairs are treated atomically if
* aligned, and if unaligned one of the pair will be completely * aligned, and if unaligned one of the pair will be completely
* within a 16-byte block and that element will be atomic. * 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, * This treats sign-extending loads like zero-extending loads,
* since that reuses the most code below. * since that reuses the most code below.
*/ */
mop = size + 1;
if (s->align_mem) { if (s->align_mem) {
mop |= (size == 2 ? MO_ALIGN_4 : MO_ALIGN_8); 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. * promote consecutive little-endian elements below.
*/ */
clean_addr = gen_mte_checkN(s, tcg_rn, is_store, is_postidx || rn != 31, 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 * 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; total = selem << scale;
tcg_rn = cpu_reg_sp(s, rn); 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); 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); tcg_ebytes = tcg_constant_i64(1 << scale);
for (xs = 0; xs < selem; xs++) { for (xs = 0; xs < selem; xs++) {
if (replicate) { if (replicate) {

View File

@ -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, TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
bool tag_checked, MemOp memop); bool tag_checked, MemOp memop);
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, 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 /* We should have at some point before trying to access an FP register
* done the necessary access check, so assert that * done the necessary access check, so assert that

View File

@ -4176,7 +4176,7 @@ void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
dirty_addr = tcg_temp_new_i64(); dirty_addr = tcg_temp_new_i64();
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); 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 * 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(); dirty_addr = tcg_temp_new_i64();
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm); 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 /* Note that unpredicated load/store of vector/predicate registers
* are defined as a stream of bytes, which equates to little-endian * are defined as a stream of bytes, which equates to little-endian