diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 98f73f2f..68bed60c 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3494,6 +3494,7 @@ #define bif_op bif_op_aarch64 #define bit_op bit_op_aarch64 #define bsl_op bsl_op_aarch64 +#define clean_data_tbi clean_data_tbi_aarch64 #define cpu_mmu_index cpu_mmu_index_aarch64 #define cpu_reg cpu_reg_aarch64 #define cpu_reg_sp cpu_reg_sp_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index df4bb459..f4305ae9 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3494,6 +3494,7 @@ #define bif_op bif_op_aarch64eb #define bit_op bit_op_aarch64eb #define bsl_op bsl_op_aarch64eb +#define clean_data_tbi clean_data_tbi_aarch64eb #define cpu_mmu_index cpu_mmu_index_aarch64eb #define cpu_reg cpu_reg_aarch64eb #define cpu_reg_sp cpu_reg_sp_aarch64eb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 0cefec01..44a537ee 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3634,6 +3634,7 @@ aarch64_symbols = ( 'bif_op', 'bit_op', 'bsl_op', + 'clean_data_tbi', 'cpu_mmu_index', 'cpu_reg', 'cpu_reg_sp', diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 4781dc12..8fb62c5d 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -351,7 +351,7 @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src) * Always return a fresh temporary that we can increment independently * of the write-back address. */ -static TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr) +TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr) { TCGv_i64 clean = new_tmp_a64(s); #ifdef CONFIG_USER_ONLY diff --git a/qemu/target/arm/translate-a64.h b/qemu/target/arm/translate-a64.h index 931d387d..36948782 100644 --- a/qemu/target/arm/translate-a64.h +++ b/qemu/target/arm/translate-a64.h @@ -119,6 +119,7 @@ bool disas_sve(DisasContext *, uint32_t); void gen_gvec_rax1(TCGContext *s, unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz); +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); TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, diff --git a/qemu/target/arm/translate-sve.c b/qemu/target/arm/translate-sve.c index 3fee36f5..2ab992e8 100644 --- a/qemu/target/arm/translate-sve.c +++ b/qemu/target/arm/translate-sve.c @@ -4738,9 +4738,8 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, * For e.g. LD4, there are not enough arguments to pass all 4 * registers as pointers, so encode the regno into the data field. * For consistency, do this even for LD1. - * TODO: mte_n check here while callers are updated. */ - if (mte_n && s->mte_active[0]) { + if (s->mte_active[0]) { int msz = dtype_msz(dtype); desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s)); @@ -4750,6 +4749,8 @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz); desc = FIELD_DP32(desc, MTEDESC, TSIZE, mte_n << msz); desc <<= SVE_MTEDESC_SHIFT; + } else { + addr = clean_data_tbi(s, addr); } desc = simd_desc(vsz, vsz, zt | desc); t_desc = tcg_const_i32(tcg_ctx, desc);