From e41139eaad1d6ea7c52b8ebb5def2dcb84ff57e1 Mon Sep 17 00:00:00 2001 From: Zejun Zhao Date: Mon, 13 Oct 2025 21:32:42 +0800 Subject: [PATCH 01/25] hw/riscv: Correct mmu-type property of sifive_u harts in device tree Correct mmu-type property of sifive_u harts from Sv48 to Sv39 in 64-bit mode since it's the only supported SATP mode. Signed-off-by: Zejun Zhao Reviewed-by: Daniel Henrique Barboza Message-ID: <20251013133242.1945681-1-jelly.zhao.42@gmail.com> Signed-off-by: Alistair Francis Cc: qemu-stable@nongnu.org --- hw/riscv/sifive_u.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index d69f942cfb..3e1ed209ca 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -176,7 +176,7 @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, if (is_32_bit) { qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32"); } else { - qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); + qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv39"); } riscv_isa_write_fdt(&s->soc.u_cpus.harts[cpu - 1], fdt, nodename); } else { From 73ae67fd4e655021290abf7ccffd622e6e23ebab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:33 +0200 Subject: [PATCH 02/25] target/riscv: Explode MO_TExx -> MO_TE | MO_xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the implicit MO_TE definition in order to replace it in the next commit. Mechanical change using: $ for n in UW UL UQ UO SW SL SQ; do \ sed -i -e "s/MO_TE$n/MO_TE | MO_$n/" \ $(git grep -l MO_TE$n target/hexagon); \ done Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-3-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rva.c.inc | 44 ++++----- target/riscv/insn_trans/trans_rvd.c.inc | 4 +- target/riscv/insn_trans/trans_rvf.c.inc | 4 +- target/riscv/insn_trans/trans_rvi.c.inc | 22 ++--- target/riscv/insn_trans/trans_rvzabha.c.inc | 20 ++--- target/riscv/insn_trans/trans_rvzacas.c.inc | 8 +- target/riscv/insn_trans/trans_rvzce.c.inc | 10 +-- target/riscv/insn_trans/trans_rvzfh.c.inc | 4 +- target/riscv/insn_trans/trans_rvzicfiss.c.inc | 4 +- target/riscv/insn_trans/trans_xthead.c.inc | 90 +++++++++---------- target/riscv/op_helper.c | 16 ++-- 11 files changed, 113 insertions(+), 113 deletions(-) diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index 9cf3ae8019..10e4c55efd 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -99,142 +99,142 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a) { REQUIRE_A_OR_ZALRSC(ctx); - return gen_lr(ctx, a, (MO_ALIGN | MO_TESL)); + return gen_lr(ctx, a, (MO_ALIGN | MO_TE | MO_SL)); } static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) { REQUIRE_A_OR_ZALRSC(ctx); - return gen_sc(ctx, a, (MO_ALIGN | MO_TESL)); + return gen_sc(ctx, a, (MO_ALIGN | MO_TE | MO_SL)); } static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_SL); } static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_SL); } static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_SL); } static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_SL); } static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_SL); } static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_SL); } static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_SL); } static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_SL); } static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_SL); } static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZALRSC(ctx); - return gen_lr(ctx, a, MO_ALIGN | MO_TEUQ); + return gen_lr(ctx, a, MO_ALIGN | MO_TE | MO_UQ); } static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZALRSC(ctx); - return gen_sc(ctx, a, (MO_ALIGN | MO_TEUQ)); + return gen_sc(ctx, a, (MO_ALIGN | MO_TE | MO_UQ)); } static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_UQ); } static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_UQ); } static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_UQ); } static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_UQ); } static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_UQ); } static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_UQ); } static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_UQ); } static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_UQ); } static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TEUQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_UQ); } diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc index 30883ea37c..3385820678 100644 --- a/target/riscv/insn_trans/trans_rvd.c.inc +++ b/target/riscv/insn_trans/trans_rvd.c.inc @@ -42,7 +42,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) { TCGv addr; - MemOp memop = MO_TEUQ; + MemOp memop = MO_TE | MO_UQ; REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); @@ -72,7 +72,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) static bool trans_fsd(DisasContext *ctx, arg_fsd *a) { TCGv addr; - MemOp memop = MO_TEUQ; + MemOp memop = MO_TE | MO_UQ; REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc index ed73afe089..150e2b9a7d 100644 --- a/target/riscv/insn_trans/trans_rvf.c.inc +++ b/target/riscv/insn_trans/trans_rvf.c.inc @@ -43,7 +43,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) { TCGv_i64 dest; TCGv addr; - MemOp memop = MO_TEUL; + MemOp memop = MO_TE | MO_UL; REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); @@ -65,7 +65,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) static bool trans_fsw(DisasContext *ctx, arg_fsw *a) { TCGv addr; - MemOp memop = MO_TEUL; + MemOp memop = MO_TE | MO_UL; REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index b9c7160468..34012caf1e 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -426,24 +426,24 @@ static bool trans_lb(DisasContext *ctx, arg_lb *a) static bool trans_lh(DisasContext *ctx, arg_lh *a) { - return gen_load(ctx, a, MO_TESW); + return gen_load(ctx, a, MO_TE | MO_SW); } static bool trans_lw(DisasContext *ctx, arg_lw *a) { - return gen_load(ctx, a, MO_TESL); + return gen_load(ctx, a, MO_TE | MO_SL); } static bool trans_ld(DisasContext *ctx, arg_ld *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_load(ctx, a, MO_TESQ); + return gen_load(ctx, a, MO_TE | MO_SQ); } static bool trans_lq(DisasContext *ctx, arg_lq *a) { REQUIRE_128BIT(ctx); - return gen_load(ctx, a, MO_TEUO); + return gen_load(ctx, a, MO_TE | MO_UO); } static bool trans_lbu(DisasContext *ctx, arg_lbu *a) @@ -453,19 +453,19 @@ static bool trans_lbu(DisasContext *ctx, arg_lbu *a) static bool trans_lhu(DisasContext *ctx, arg_lhu *a) { - return gen_load(ctx, a, MO_TEUW); + return gen_load(ctx, a, MO_TE | MO_UW); } static bool trans_lwu(DisasContext *ctx, arg_lwu *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_load(ctx, a, MO_TEUL); + return gen_load(ctx, a, MO_TE | MO_UL); } static bool trans_ldu(DisasContext *ctx, arg_ldu *a) { REQUIRE_128BIT(ctx); - return gen_load(ctx, a, MO_TEUQ); + return gen_load(ctx, a, MO_TE | MO_UQ); } static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop) @@ -521,24 +521,24 @@ static bool trans_sb(DisasContext *ctx, arg_sb *a) static bool trans_sh(DisasContext *ctx, arg_sh *a) { - return gen_store(ctx, a, MO_TESW); + return gen_store(ctx, a, MO_TE | MO_SW); } static bool trans_sw(DisasContext *ctx, arg_sw *a) { - return gen_store(ctx, a, MO_TESL); + return gen_store(ctx, a, MO_TE | MO_SL); } static bool trans_sd(DisasContext *ctx, arg_sd *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_store(ctx, a, MO_TEUQ); + return gen_store(ctx, a, MO_TE | MO_UQ); } static bool trans_sq(DisasContext *ctx, arg_sq *a) { REQUIRE_128BIT(ctx); - return gen_store(ctx, a, MO_TEUO); + return gen_store(ctx, a, MO_TE | MO_UO); } static bool trans_addd(DisasContext *ctx, arg_addd *a) diff --git a/target/riscv/insn_trans/trans_rvzabha.c.inc b/target/riscv/insn_trans/trans_rvzabha.c.inc index ce8edcba62..25db42d24c 100644 --- a/target/riscv/insn_trans/trans_rvzabha.c.inc +++ b/target/riscv/insn_trans/trans_rvzabha.c.inc @@ -79,55 +79,55 @@ static bool trans_amomaxu_b(DisasContext *ctx, arg_amomaxu_b *a) static bool trans_amoswap_h(DisasContext *ctx, arg_amoswap_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_SW); } static bool trans_amoadd_h(DisasContext *ctx, arg_amoadd_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_SW); } static bool trans_amoxor_h(DisasContext *ctx, arg_amoxor_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_SW); } static bool trans_amoand_h(DisasContext *ctx, arg_amoand_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_SW); } static bool trans_amoor_h(DisasContext *ctx, arg_amoor_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_SW); } static bool trans_amomin_h(DisasContext *ctx, arg_amomin_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_SW); } static bool trans_amomax_h(DisasContext *ctx, arg_amomax_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_SW); } static bool trans_amominu_h(DisasContext *ctx, arg_amominu_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_SW); } static bool trans_amomaxu_h(DisasContext *ctx, arg_amomaxu_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TESW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_SW); } static bool trans_amocas_b(DisasContext *ctx, arg_amocas_b *a) @@ -141,5 +141,5 @@ static bool trans_amocas_h(DisasContext *ctx, arg_amocas_h *a) { REQUIRE_ZACAS(ctx); REQUIRE_ZABHA(ctx); - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TESW); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_SW); } diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc index 15e688a033..5e7c7c92b7 100644 --- a/target/riscv/insn_trans/trans_rvzacas.c.inc +++ b/target/riscv/insn_trans/trans_rvzacas.c.inc @@ -25,7 +25,7 @@ static bool trans_amocas_w(DisasContext *ctx, arg_amocas_w *a) { REQUIRE_ZACAS(ctx); - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TESL); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_SL); } static TCGv_i64 get_gpr_pair(DisasContext *ctx, int reg_num) @@ -88,10 +88,10 @@ static bool trans_amocas_d(DisasContext *ctx, arg_amocas_d *a) REQUIRE_ZACAS(ctx); switch (get_ol(ctx)) { case MXL_RV32: - return gen_cmpxchg64(ctx, a, MO_ALIGN | MO_TEUQ); + return gen_cmpxchg64(ctx, a, MO_ALIGN | MO_TE | MO_UQ); case MXL_RV64: case MXL_RV128: - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TEUQ); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_UQ); default: g_assert_not_reached(); } @@ -123,7 +123,7 @@ static bool trans_amocas_q(DisasContext *ctx, arg_amocas_q *a) tcg_gen_concat_i64_i128(dest, destl, desth); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); tcg_gen_atomic_cmpxchg_i128(dest, src1, dest, src2, ctx->mem_idx, - (MO_ALIGN | MO_TEUO)); + (MO_ALIGN | MO_TE | MO_UO)); tcg_gen_extr_i128_i64(destl, desth, dest); diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index dd15af0f54..d130179432 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -88,13 +88,13 @@ static bool trans_c_lbu(DisasContext *ctx, arg_c_lbu *a) static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a) { REQUIRE_ZCB(ctx); - return gen_load(ctx, a, MO_TEUW); + return gen_load(ctx, a, MO_TE | MO_UW); } static bool trans_c_lh(DisasContext *ctx, arg_c_lh *a) { REQUIRE_ZCB(ctx); - return gen_load(ctx, a, MO_TESW); + return gen_load(ctx, a, MO_TE | MO_SW); } static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a) @@ -106,7 +106,7 @@ static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a) static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a) { REQUIRE_ZCB(ctx); - return gen_store(ctx, a, MO_TEUW); + return gen_store(ctx, a, MO_TE | MO_UW); } #define X_S0 8 @@ -175,7 +175,7 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) return false; } - MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TEUL : MO_TEUQ; + MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TE | MO_UL : MO_TE | MO_UQ; int reg_size = memop_size(memop); target_ulong stack_adj = ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + a->spimm; @@ -228,7 +228,7 @@ static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a) return false; } - MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TEUL : MO_TEUQ; + MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TE | MO_UL : MO_TE | MO_UQ; int reg_size = memop_size(memop); target_ulong stack_adj = ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + a->spimm; diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc index bece48e600..eec478afcb 100644 --- a/target/riscv/insn_trans/trans_rvzfh.c.inc +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc @@ -57,7 +57,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) } dest = cpu_fpr[a->rd]; - tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TEUW); + tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TE | MO_UW); gen_nanbox_h(dest, dest); mark_fs_dirty(ctx); @@ -79,7 +79,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) t0 = temp; } - tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW); + tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TE | MO_UW); return true; } diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc index f4a1c12ca0..c555596617 100644 --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc @@ -105,7 +105,7 @@ static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a) src1 = get_address(ctx, a->rs1, 0); tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), - (MO_ALIGN | MO_TESL)); + (MO_ALIGN | MO_TE | MO_SL)); gen_set_gpr(ctx, a->rd, dest); return true; } @@ -134,7 +134,7 @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a) src1 = get_address(ctx, a->rs1, 0); tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), - (MO_ALIGN | MO_TESQ)); + (MO_ALIGN | MO_TE | MO_SQ)); gen_set_gpr(ctx, a->rd, dest); return true; } diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 22488412d4..754cb80e22 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -379,7 +379,7 @@ static bool trans_th_flrd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fload_idx(ctx, a, MO_TEUQ, false); + return gen_fload_idx(ctx, a, MO_TE | MO_UQ, false); } static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a) @@ -387,7 +387,7 @@ static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fload_idx(ctx, a, MO_TEUL, false); + return gen_fload_idx(ctx, a, MO_TE | MO_UL, false); } static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a) @@ -395,7 +395,7 @@ static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fload_idx(ctx, a, MO_TEUQ, true); + return gen_fload_idx(ctx, a, MO_TE | MO_UQ, true); } static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a) @@ -403,7 +403,7 @@ static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fload_idx(ctx, a, MO_TEUL, true); + return gen_fload_idx(ctx, a, MO_TE | MO_UL, true); } static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a) @@ -411,7 +411,7 @@ static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fstore_idx(ctx, a, MO_TEUQ, false); + return gen_fstore_idx(ctx, a, MO_TE | MO_UQ, false); } static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a) @@ -419,7 +419,7 @@ static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fstore_idx(ctx, a, MO_TEUL, false); + return gen_fstore_idx(ctx, a, MO_TE | MO_UL, false); } static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a) @@ -427,7 +427,7 @@ static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fstore_idx(ctx, a, MO_TEUQ, true); + return gen_fstore_idx(ctx, a, MO_TE | MO_UQ, true); } static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a) @@ -435,7 +435,7 @@ static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fstore_idx(ctx, a, MO_TEUL, true); + return gen_fstore_idx(ctx, a, MO_TE | MO_UL, true); } /* XTheadFmv */ @@ -598,64 +598,64 @@ static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TESQ, false); + return gen_load_inc(ctx, a, MO_TE | MO_SQ, false); } static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TESQ, true); + return gen_load_inc(ctx, a, MO_TE | MO_SQ, true); } static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TESL, false); + return gen_load_inc(ctx, a, MO_TE | MO_SL, false); } static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TESL, true); + return gen_load_inc(ctx, a, MO_TE | MO_SL, true); } static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TEUL, false); + return gen_load_inc(ctx, a, MO_TE | MO_UL, false); } static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TEUL, true); + return gen_load_inc(ctx, a, MO_TE | MO_UL, true); } static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TESW, false); + return gen_load_inc(ctx, a, MO_TE | MO_SW, false); } static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TESW, true); + return gen_load_inc(ctx, a, MO_TE | MO_SW, true); } static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TEUW, false); + return gen_load_inc(ctx, a, MO_TE | MO_UW, false); } static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TEUW, true); + return gen_load_inc(ctx, a, MO_TE | MO_UW, true); } static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a) @@ -686,38 +686,38 @@ static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_inc(ctx, a, MO_TESQ, false); + return gen_store_inc(ctx, a, MO_TE | MO_SQ, false); } static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_inc(ctx, a, MO_TESQ, true); + return gen_store_inc(ctx, a, MO_TE | MO_SQ, true); } static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TESL, false); + return gen_store_inc(ctx, a, MO_TE | MO_SL, false); } static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TESL, true); + return gen_store_inc(ctx, a, MO_TE | MO_SL, true); } static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TESW, false); + return gen_store_inc(ctx, a, MO_TE | MO_SW, false); } static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TESW, true); + return gen_store_inc(ctx, a, MO_TE | MO_SW, true); } static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a) @@ -769,32 +769,32 @@ static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TESQ, false); + return gen_load_idx(ctx, a, MO_TE | MO_SQ, false); } static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TESL, false); + return gen_load_idx(ctx, a, MO_TE | MO_SL, false); } static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TEUL, false); + return gen_load_idx(ctx, a, MO_TE | MO_UL, false); } static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TESW, false); + return gen_load_idx(ctx, a, MO_TE | MO_SW, false); } static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TEUW, false); + return gen_load_idx(ctx, a, MO_TE | MO_UW, false); } static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a) @@ -813,19 +813,19 @@ static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_idx(ctx, a, MO_TESQ, false); + return gen_store_idx(ctx, a, MO_TE | MO_SQ, false); } static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TESL, false); + return gen_store_idx(ctx, a, MO_TE | MO_SL, false); } static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TESW, false); + return gen_store_idx(ctx, a, MO_TE | MO_SW, false); } static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a) @@ -837,32 +837,32 @@ static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TESQ, true); + return gen_load_idx(ctx, a, MO_TE | MO_SQ, true); } static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TESL, true); + return gen_load_idx(ctx, a, MO_TE | MO_SL, true); } static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TEUL, true); + return gen_load_idx(ctx, a, MO_TE | MO_UL, true); } static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TESW, true); + return gen_load_idx(ctx, a, MO_TE | MO_SW, true); } static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TEUW, true); + return gen_load_idx(ctx, a, MO_TE | MO_UW, true); } static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a) @@ -881,19 +881,19 @@ static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_idx(ctx, a, MO_TESQ, true); + return gen_store_idx(ctx, a, MO_TE | MO_SQ, true); } static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TESL, true); + return gen_store_idx(ctx, a, MO_TE | MO_SL, true); } static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TESW, true); + return gen_store_idx(ctx, a, MO_TE | MO_SW, true); } static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a) @@ -931,19 +931,19 @@ static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); REQUIRE_64BIT(ctx); - return gen_loadpair_tl(ctx, a, MO_TESQ, 4); + return gen_loadpair_tl(ctx, a, MO_TE | MO_SQ, 4); } static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_loadpair_tl(ctx, a, MO_TESL, 3); + return gen_loadpair_tl(ctx, a, MO_TE | MO_SL, 3); } static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_loadpair_tl(ctx, a, MO_TEUL, 3); + return gen_loadpair_tl(ctx, a, MO_TE | MO_UL, 3); } static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, @@ -967,13 +967,13 @@ static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); REQUIRE_64BIT(ctx); - return gen_storepair_tl(ctx, a, MO_TESQ, 4); + return gen_storepair_tl(ctx, a, MO_TE | MO_SQ, 4); } static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_storepair_tl(ctx, a, MO_TESL, 3); + return gen_storepair_tl(ctx, a, MO_TE | MO_SL, 3); } /* XTheadSync */ diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 8382aa94cb..c486f771d3 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -633,7 +633,7 @@ target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); return cpu_ldw_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -642,7 +642,7 @@ target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); return cpu_ldl_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -651,7 +651,7 @@ target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UQ, mmu_idx); return cpu_ldq_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -669,7 +669,7 @@ void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); cpu_stw_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -678,7 +678,7 @@ void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); cpu_stl_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -687,7 +687,7 @@ void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UQ, mmu_idx); cpu_stq_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -703,7 +703,7 @@ target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, true, ra); - MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); return cpu_ldw_code_mmu(env, addr, oi, GETPC()); } @@ -712,7 +712,7 @@ target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, true, ra); - MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx); + MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); return cpu_ldl_code_mmu(env, addr, oi, ra); } From cb2725db0cc314242dd8315823c90057e1b4e1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:34 +0200 Subject: [PATCH 03/25] target/riscv: Conceal MO_TE within gen_amo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_amo() set the MO_TE flag. Set it once in the callee. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-4-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rva.c.inc | 36 ++++++++++----------- target/riscv/insn_trans/trans_rvzabha.c.inc | 18 +++++------ target/riscv/translate.c | 1 + 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index 10e4c55efd..e0fbfafdde 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -111,55 +111,55 @@ static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_SL); } static bool trans_amoadd_w(DisasContext *ctx, arg_amoadd_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_SL); } static bool trans_amoxor_w(DisasContext *ctx, arg_amoxor_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_SL); } static bool trans_amoand_w(DisasContext *ctx, arg_amoand_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_SL); } static bool trans_amoor_w(DisasContext *ctx, arg_amoor_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_SL); } static bool trans_amomin_w(DisasContext *ctx, arg_amomin_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_SL); } static bool trans_amomax_w(DisasContext *ctx, arg_amomax_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_SL); } static bool trans_amominu_w(DisasContext *ctx, arg_amominu_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_SL); } static bool trans_amomaxu_w(DisasContext *ctx, arg_amomaxu_w *a) { REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_SL); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_SL); } static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) @@ -180,61 +180,61 @@ static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_UQ); } static bool trans_amoadd_d(DisasContext *ctx, arg_amoadd_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_UQ); } static bool trans_amoxor_d(DisasContext *ctx, arg_amoxor_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_UQ); } static bool trans_amoand_d(DisasContext *ctx, arg_amoand_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_UQ); } static bool trans_amoor_d(DisasContext *ctx, arg_amoor_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_UQ); } static bool trans_amomin_d(DisasContext *ctx, arg_amomin_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_UQ); } static bool trans_amomax_d(DisasContext *ctx, arg_amomax_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_UQ); } static bool trans_amominu_d(DisasContext *ctx, arg_amominu_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_UQ); } static bool trans_amomaxu_d(DisasContext *ctx, arg_amomaxu_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZAAMO(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_UQ); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_UQ); } diff --git a/target/riscv/insn_trans/trans_rvzabha.c.inc b/target/riscv/insn_trans/trans_rvzabha.c.inc index 25db42d24c..c1f99b65f0 100644 --- a/target/riscv/insn_trans/trans_rvzabha.c.inc +++ b/target/riscv/insn_trans/trans_rvzabha.c.inc @@ -79,55 +79,55 @@ static bool trans_amomaxu_b(DisasContext *ctx, arg_amomaxu_b *a) static bool trans_amoswap_h(DisasContext *ctx, arg_amoswap_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_xchg_tl, MO_SW); } static bool trans_amoadd_h(DisasContext *ctx, arg_amoadd_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_add_tl, MO_SW); } static bool trans_amoxor_h(DisasContext *ctx, arg_amoxor_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_xor_tl, MO_SW); } static bool trans_amoand_h(DisasContext *ctx, arg_amoand_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_and_tl, MO_SW); } static bool trans_amoor_h(DisasContext *ctx, arg_amoor_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_or_tl, MO_SW); } static bool trans_amomin_h(DisasContext *ctx, arg_amomin_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smin_tl, MO_SW); } static bool trans_amomax_h(DisasContext *ctx, arg_amomax_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_smax_tl, MO_SW); } static bool trans_amominu_h(DisasContext *ctx, arg_amominu_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umin_tl, MO_SW); } static bool trans_amomaxu_h(DisasContext *ctx, arg_amomaxu_h *a) { REQUIRE_ZABHA(ctx); - return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_TE | MO_SW); + return gen_amo(ctx, a, &tcg_gen_atomic_fetch_umax_tl, MO_SW); } static bool trans_amocas_b(DisasContext *ctx, arg_amocas_b *a) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 9a53aecbfe..94af9853cf 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -1135,6 +1135,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a, TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); MemOp size = mop & MO_SIZE; + mop |= MO_TE; if (ctx->cfg_ptr->ext_zama16b && size >= MO_32) { mop |= MO_ATOM_WITHIN16; } else { From 133080735cf2e7b0aabdf164d766690b65eb5418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:35 +0200 Subject: [PATCH 04/25] target/riscv: Conceal MO_TE within gen_inc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_inc() set the MO_TE flag. Set it once in the callee. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-5-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_xthead.c.inc | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 754cb80e22..7e69906e5b 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -568,6 +568,7 @@ static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop, TCGv rd = dest_gpr(ctx, a->rd); TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); + memop |= MO_TE; tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop); tcg_gen_addi_tl(rs1, rs1, imm); gen_set_gpr(ctx, a->rd, rd); @@ -588,6 +589,7 @@ static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop, TCGv data = get_gpr(ctx, a->rd, EXT_NONE); TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); + memop |= MO_TE; tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop); tcg_gen_addi_tl(rs1, rs1, imm); gen_set_gpr(ctx, a->rs1, rs1); @@ -598,64 +600,64 @@ static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SQ, false); + return gen_load_inc(ctx, a, MO_SQ, false); } static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SQ, true); + return gen_load_inc(ctx, a, MO_SQ, true); } static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SL, false); + return gen_load_inc(ctx, a, MO_SL, false); } static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SL, true); + return gen_load_inc(ctx, a, MO_SL, true); } static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_UL, false); + return gen_load_inc(ctx, a, MO_UL, false); } static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_UL, true); + return gen_load_inc(ctx, a, MO_UL, true); } static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SW, false); + return gen_load_inc(ctx, a, MO_SW, false); } static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_SW, true); + return gen_load_inc(ctx, a, MO_SW, true); } static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_UW, false); + return gen_load_inc(ctx, a, MO_UW, false); } static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_inc(ctx, a, MO_TE | MO_UW, true); + return gen_load_inc(ctx, a, MO_UW, true); } static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a) @@ -686,38 +688,38 @@ static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SQ, false); + return gen_store_inc(ctx, a, MO_SQ, false); } static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SQ, true); + return gen_store_inc(ctx, a, MO_SQ, true); } static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SL, false); + return gen_store_inc(ctx, a, MO_SL, false); } static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SL, true); + return gen_store_inc(ctx, a, MO_SL, true); } static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SW, false); + return gen_store_inc(ctx, a, MO_SW, false); } static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_inc(ctx, a, MO_TE | MO_SW, true); + return gen_store_inc(ctx, a, MO_SW, true); } static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a) From 5ed09d6f7bf497f49d7ccfdfa664095dafa72c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:36 +0200 Subject: [PATCH 05/25] target/riscv: Conceal MO_TE within gen_load() / gen_store() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_load() / gen_store() set the MO_TE flag. Set it once in the callees. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-6-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvi.c.inc | 24 ++++++++++++----------- target/riscv/insn_trans/trans_rvzce.c.inc | 6 +++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 34012caf1e..9a03058f46 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -402,6 +402,7 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) { bool out; + memop |= MO_TE; if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } @@ -426,24 +427,24 @@ static bool trans_lb(DisasContext *ctx, arg_lb *a) static bool trans_lh(DisasContext *ctx, arg_lh *a) { - return gen_load(ctx, a, MO_TE | MO_SW); + return gen_load(ctx, a, MO_SW); } static bool trans_lw(DisasContext *ctx, arg_lw *a) { - return gen_load(ctx, a, MO_TE | MO_SL); + return gen_load(ctx, a, MO_SL); } static bool trans_ld(DisasContext *ctx, arg_ld *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_load(ctx, a, MO_TE | MO_SQ); + return gen_load(ctx, a, MO_SQ); } static bool trans_lq(DisasContext *ctx, arg_lq *a) { REQUIRE_128BIT(ctx); - return gen_load(ctx, a, MO_TE | MO_UO); + return gen_load(ctx, a, MO_UO); } static bool trans_lbu(DisasContext *ctx, arg_lbu *a) @@ -453,19 +454,19 @@ static bool trans_lbu(DisasContext *ctx, arg_lbu *a) static bool trans_lhu(DisasContext *ctx, arg_lhu *a) { - return gen_load(ctx, a, MO_TE | MO_UW); + return gen_load(ctx, a, MO_UW); } static bool trans_lwu(DisasContext *ctx, arg_lwu *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_load(ctx, a, MO_TE | MO_UL); + return gen_load(ctx, a, MO_UL); } static bool trans_ldu(DisasContext *ctx, arg_ldu *a) { REQUIRE_128BIT(ctx); - return gen_load(ctx, a, MO_TE | MO_UQ); + return gen_load(ctx, a, MO_UQ); } static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop) @@ -503,6 +504,7 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop) static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) { + memop |= MO_TE; if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } @@ -521,24 +523,24 @@ static bool trans_sb(DisasContext *ctx, arg_sb *a) static bool trans_sh(DisasContext *ctx, arg_sh *a) { - return gen_store(ctx, a, MO_TE | MO_SW); + return gen_store(ctx, a, MO_SW); } static bool trans_sw(DisasContext *ctx, arg_sw *a) { - return gen_store(ctx, a, MO_TE | MO_SL); + return gen_store(ctx, a, MO_SL); } static bool trans_sd(DisasContext *ctx, arg_sd *a) { REQUIRE_64_OR_128BIT(ctx); - return gen_store(ctx, a, MO_TE | MO_UQ); + return gen_store(ctx, a, MO_UQ); } static bool trans_sq(DisasContext *ctx, arg_sq *a) { REQUIRE_128BIT(ctx); - return gen_store(ctx, a, MO_TE | MO_UO); + return gen_store(ctx, a, MO_UO); } static bool trans_addd(DisasContext *ctx, arg_addd *a) diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index d130179432..c8dc102c8e 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -88,13 +88,13 @@ static bool trans_c_lbu(DisasContext *ctx, arg_c_lbu *a) static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a) { REQUIRE_ZCB(ctx); - return gen_load(ctx, a, MO_TE | MO_UW); + return gen_load(ctx, a, MO_UW); } static bool trans_c_lh(DisasContext *ctx, arg_c_lh *a) { REQUIRE_ZCB(ctx); - return gen_load(ctx, a, MO_TE | MO_SW); + return gen_load(ctx, a, MO_SW); } static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a) @@ -106,7 +106,7 @@ static bool trans_c_sb(DisasContext *ctx, arg_c_sb *a) static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a) { REQUIRE_ZCB(ctx); - return gen_store(ctx, a, MO_TE | MO_UW); + return gen_store(ctx, a, MO_UW); } #define X_S0 8 From 23a56ce74ba6d00362693a3aba7fe4f76a720698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:37 +0200 Subject: [PATCH 06/25] target/riscv: Conceal MO_TE within gen_load_idx() / gen_store_idx() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_load_idx() / gen_store_idx() set the MO_TE flag. Set it once in the callees. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-7-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_xthead.c.inc | 34 ++++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 7e69906e5b..70c563664a 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -745,6 +745,7 @@ static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv rd = dest_gpr(ctx, a->rd); TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); + memop |= MO_TE; tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop); gen_set_gpr(ctx, a->rd, rd); @@ -762,6 +763,7 @@ static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv data = get_gpr(ctx, a->rd, EXT_NONE); TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); + memop |= MO_TE; tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop); return true; @@ -771,32 +773,32 @@ static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SQ, false); + return gen_load_idx(ctx, a, MO_SQ, false); } static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SL, false); + return gen_load_idx(ctx, a, MO_SL, false); } static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_UL, false); + return gen_load_idx(ctx, a, MO_UL, false); } static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SW, false); + return gen_load_idx(ctx, a, MO_SW, false); } static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_UW, false); + return gen_load_idx(ctx, a, MO_UW, false); } static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a) @@ -815,19 +817,19 @@ static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SQ, false); + return gen_store_idx(ctx, a, MO_SQ, false); } static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SL, false); + return gen_store_idx(ctx, a, MO_SL, false); } static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SW, false); + return gen_store_idx(ctx, a, MO_SW, false); } static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a) @@ -839,32 +841,32 @@ static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SQ, true); + return gen_load_idx(ctx, a, MO_SQ, true); } static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SL, true); + return gen_load_idx(ctx, a, MO_SL, true); } static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_UL, true); + return gen_load_idx(ctx, a, MO_UL, true); } static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_SW, true); + return gen_load_idx(ctx, a, MO_SW, true); } static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_load_idx(ctx, a, MO_TE | MO_UW, true); + return gen_load_idx(ctx, a, MO_UW, true); } static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a) @@ -883,19 +885,19 @@ static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); REQUIRE_64BIT(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SQ, true); + return gen_store_idx(ctx, a, MO_SQ, true); } static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SL, true); + return gen_store_idx(ctx, a, MO_SL, true); } static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a) { REQUIRE_XTHEADMEMIDX(ctx); - return gen_store_idx(ctx, a, MO_TE | MO_SW, true); + return gen_store_idx(ctx, a, MO_SW, true); } static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a) From d46fa71ea99c4efd2e7fad0aa5c6efad15bc982b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:38 +0200 Subject: [PATCH 07/25] target/riscv: Conceal MO_TE within gen_fload_idx() / gen_fstore_idx() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_fload_idx() / gen_fstore_idx() set the MO_TE flag. Set it once in the callees. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-8-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_xthead.c.inc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 70c563664a..859cbc26cb 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -349,6 +349,7 @@ static bool gen_fload_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv_i64 rd = cpu_fpr[a->rd]; TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); + memop |= MO_TE; tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop); if ((memop & MO_SIZE) == MO_32) { gen_nanbox_s(rd, rd); @@ -369,6 +370,7 @@ static bool gen_fstore_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv_i64 rd = cpu_fpr[a->rd]; TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); + memop |= MO_TE; tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop); return true; @@ -379,7 +381,7 @@ static bool trans_th_flrd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fload_idx(ctx, a, MO_TE | MO_UQ, false); + return gen_fload_idx(ctx, a, MO_UQ, false); } static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a) @@ -387,7 +389,7 @@ static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fload_idx(ctx, a, MO_TE | MO_UL, false); + return gen_fload_idx(ctx, a, MO_UL, false); } static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a) @@ -395,7 +397,7 @@ static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fload_idx(ctx, a, MO_TE | MO_UQ, true); + return gen_fload_idx(ctx, a, MO_UQ, true); } static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a) @@ -403,7 +405,7 @@ static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fload_idx(ctx, a, MO_TE | MO_UL, true); + return gen_fload_idx(ctx, a, MO_UL, true); } static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a) @@ -411,7 +413,7 @@ static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fstore_idx(ctx, a, MO_TE | MO_UQ, false); + return gen_fstore_idx(ctx, a, MO_UQ, false); } static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a) @@ -419,7 +421,7 @@ static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fstore_idx(ctx, a, MO_TE | MO_UL, false); + return gen_fstore_idx(ctx, a, MO_UL, false); } static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a) @@ -427,7 +429,7 @@ static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); - return gen_fstore_idx(ctx, a, MO_TE | MO_UQ, true); + return gen_fstore_idx(ctx, a, MO_UQ, true); } static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a) @@ -435,7 +437,7 @@ static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a) REQUIRE_XTHEADFMEMIDX(ctx); REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - return gen_fstore_idx(ctx, a, MO_TE | MO_UL, true); + return gen_fstore_idx(ctx, a, MO_UL, true); } /* XTheadFmv */ From 6a58a38655fb242051e4b7c29aebe0fecbea37b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:39 +0200 Subject: [PATCH 08/25] target/riscv: Conceal MO_TE within gen_storepair_tl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_storepair_tl() set the MO_TE flag. Set it once in the callee. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-9-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_xthead.c.inc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 859cbc26cb..2f31842791 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -926,6 +926,7 @@ static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, addr1 = get_address(ctx, a->rs, imm); addr2 = get_address(ctx, a->rs, memop_size(memop) + imm); + memop |= MO_TE; tcg_gen_qemu_ld_tl(t1, addr1, ctx->mem_idx, memop); tcg_gen_qemu_ld_tl(t2, addr2, ctx->mem_idx, memop); gen_set_gpr(ctx, a->rd1, t1); @@ -937,19 +938,19 @@ static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); REQUIRE_64BIT(ctx); - return gen_loadpair_tl(ctx, a, MO_TE | MO_SQ, 4); + return gen_loadpair_tl(ctx, a, MO_SQ, 4); } static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_loadpair_tl(ctx, a, MO_TE | MO_SL, 3); + return gen_loadpair_tl(ctx, a, MO_SL, 3); } static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_loadpair_tl(ctx, a, MO_TE | MO_UL, 3); + return gen_loadpair_tl(ctx, a, MO_UL, 3); } static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, @@ -964,6 +965,7 @@ static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, addr1 = get_address(ctx, a->rs, imm); addr2 = get_address(ctx, a->rs, memop_size(memop) + imm); + memop |= MO_TE; tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop); tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop); return true; @@ -973,13 +975,13 @@ static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); REQUIRE_64BIT(ctx); - return gen_storepair_tl(ctx, a, MO_TE | MO_SQ, 4); + return gen_storepair_tl(ctx, a, MO_SQ, 4); } static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a) { REQUIRE_XTHEADMEMPAIR(ctx); - return gen_storepair_tl(ctx, a, MO_TE | MO_SL, 3); + return gen_storepair_tl(ctx, a, MO_SL, 3); } /* XTheadSync */ From 9f14d9d98dc32fb8fe99ba5ae57a2fec3912d544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:40 +0200 Subject: [PATCH 09/25] target/riscv: Conceal MO_TE within gen_cmpxchg*() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_cmpxchg() / gen_cmpxchg64() set the MO_TE flag. Set it once in the callees. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-10-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvzabha.c.inc | 2 +- target/riscv/insn_trans/trans_rvzacas.c.inc | 7 ++++--- target/riscv/translate.c | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvzabha.c.inc b/target/riscv/insn_trans/trans_rvzabha.c.inc index c1f99b65f0..302c63f2a3 100644 --- a/target/riscv/insn_trans/trans_rvzabha.c.inc +++ b/target/riscv/insn_trans/trans_rvzabha.c.inc @@ -141,5 +141,5 @@ static bool trans_amocas_h(DisasContext *ctx, arg_amocas_h *a) { REQUIRE_ZACAS(ctx); REQUIRE_ZABHA(ctx); - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_SW); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_SW); } diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc index 5e7c7c92b7..d850b14264 100644 --- a/target/riscv/insn_trans/trans_rvzacas.c.inc +++ b/target/riscv/insn_trans/trans_rvzacas.c.inc @@ -25,7 +25,7 @@ static bool trans_amocas_w(DisasContext *ctx, arg_amocas_w *a) { REQUIRE_ZACAS(ctx); - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_SL); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_SL); } static TCGv_i64 get_gpr_pair(DisasContext *ctx, int reg_num) @@ -76,6 +76,7 @@ static bool gen_cmpxchg64(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGv src1 = get_address(ctx, a->rs1, 0); TCGv_i64 src2 = get_gpr_pair(ctx, a->rs2); + mop |= MO_TE; decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); tcg_gen_atomic_cmpxchg_i64(dest, src1, dest, src2, ctx->mem_idx, mop); @@ -88,10 +89,10 @@ static bool trans_amocas_d(DisasContext *ctx, arg_amocas_d *a) REQUIRE_ZACAS(ctx); switch (get_ol(ctx)) { case MXL_RV32: - return gen_cmpxchg64(ctx, a, MO_ALIGN | MO_TE | MO_UQ); + return gen_cmpxchg64(ctx, a, MO_ALIGN | MO_UQ); case MXL_RV64: case MXL_RV128: - return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TE | MO_UQ); + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_UQ); default: g_assert_not_reached(); } diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 94af9853cf..2e6f39aa02 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -1156,6 +1156,7 @@ static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGv src1 = get_address(ctx, a->rs1, 0); TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + mop |= MO_TE; decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop); From c62bcc0048746c5dbfbf8cf390dafc473be31139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:41 +0200 Subject: [PATCH 10/25] target/riscv: Conceal MO_TE|MO_ALIGN within gen_lr() / gen_sc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers of gen_lr() / gen_sc() set the MO_TE and MO_ALIGN flags. Set them once in the callees. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-11-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rva.c.inc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index e0fbfafdde..8737e8d60d 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -34,6 +34,9 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop) { TCGv src1; + mop |= MO_ALIGN; + mop |= MO_TE; + decode_save_opc(ctx, 0); src1 = get_address(ctx, a->rs1, 0); if (a->rl) { @@ -61,6 +64,9 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGLabel *l1 = gen_new_label(); TCGLabel *l2 = gen_new_label(); + mop |= MO_ALIGN; + mop |= MO_TE; + decode_save_opc(ctx, 0); src1 = get_address(ctx, a->rs1, 0); tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1); @@ -99,13 +105,13 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) static bool trans_lr_w(DisasContext *ctx, arg_lr_w *a) { REQUIRE_A_OR_ZALRSC(ctx); - return gen_lr(ctx, a, (MO_ALIGN | MO_TE | MO_SL)); + return gen_lr(ctx, a, MO_SL); } static bool trans_sc_w(DisasContext *ctx, arg_sc_w *a) { REQUIRE_A_OR_ZALRSC(ctx); - return gen_sc(ctx, a, (MO_ALIGN | MO_TE | MO_SL)); + return gen_sc(ctx, a, MO_SL); } static bool trans_amoswap_w(DisasContext *ctx, arg_amoswap_w *a) @@ -166,14 +172,14 @@ static bool trans_lr_d(DisasContext *ctx, arg_lr_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZALRSC(ctx); - return gen_lr(ctx, a, MO_ALIGN | MO_TE | MO_UQ); + return gen_lr(ctx, a, MO_UQ); } static bool trans_sc_d(DisasContext *ctx, arg_sc_d *a) { REQUIRE_64BIT(ctx); REQUIRE_A_OR_ZALRSC(ctx); - return gen_sc(ctx, a, (MO_ALIGN | MO_TE | MO_UQ)); + return gen_sc(ctx, a, MO_UQ); } static bool trans_amoswap_d(DisasContext *ctx, arg_amoswap_d *a) From 6f825fd4911f61d198e11457eab9f707a925f34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:42 +0200 Subject: [PATCH 11/25] target/riscv: Factor MemOp variable out when MO_TE is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of automatically replacing the MO_TE flag in the next commit, use an local @memop variable. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-12-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rvd.c.inc | 6 ++++-- target/riscv/insn_trans/trans_rvf.c.inc | 6 ++++-- target/riscv/insn_trans/trans_rvzacas.c.inc | 5 +++-- target/riscv/insn_trans/trans_rvzce.c.inc | 6 ++++-- target/riscv/insn_trans/trans_rvzfh.c.inc | 8 ++++++-- target/riscv/insn_trans/trans_rvzicfiss.c.inc | 10 ++++++---- 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc index 3385820678..62b7535815 100644 --- a/target/riscv/insn_trans/trans_rvd.c.inc +++ b/target/riscv/insn_trans/trans_rvd.c.inc @@ -42,7 +42,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) { TCGv addr; - MemOp memop = MO_TE | MO_UQ; + MemOp memop = MO_UQ; REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); @@ -60,6 +60,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) } else { memop |= MO_ATOM_IFALIGN; } + memop |= MO_TE; decode_save_opc(ctx, 0); addr = get_address(ctx, a->rs1, a->imm); @@ -72,7 +73,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) static bool trans_fsd(DisasContext *ctx, arg_fsd *a) { TCGv addr; - MemOp memop = MO_TE | MO_UQ; + MemOp memop = MO_UQ; REQUIRE_FPU; REQUIRE_EXT(ctx, RVD); @@ -84,6 +85,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) } else { memop |= MO_ATOM_IFALIGN; } + memop |= MO_TE; decode_save_opc(ctx, 0); addr = get_address(ctx, a->rs1, a->imm); diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc index 150e2b9a7d..878417eae9 100644 --- a/target/riscv/insn_trans/trans_rvf.c.inc +++ b/target/riscv/insn_trans/trans_rvf.c.inc @@ -43,11 +43,12 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) { TCGv_i64 dest; TCGv addr; - MemOp memop = MO_TE | MO_UL; + MemOp memop = MO_UL; REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); + memop |= MO_TE; if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } @@ -65,11 +66,12 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) static bool trans_fsw(DisasContext *ctx, arg_fsw *a) { TCGv addr; - MemOp memop = MO_TE | MO_UL; + MemOp memop = MO_UL; REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); + memop |= MO_TE; if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc index d850b14264..6458ac4f24 100644 --- a/target/riscv/insn_trans/trans_rvzacas.c.inc +++ b/target/riscv/insn_trans/trans_rvzacas.c.inc @@ -119,12 +119,13 @@ static bool trans_amocas_q(DisasContext *ctx, arg_amocas_q *a) TCGv_i64 src2h = get_gpr(ctx, a->rs2 == 0 ? 0 : a->rs2 + 1, EXT_NONE); TCGv_i64 destl = get_gpr(ctx, a->rd, EXT_NONE); TCGv_i64 desth = get_gpr(ctx, a->rd == 0 ? 0 : a->rd + 1, EXT_NONE); + MemOp memop = MO_ALIGN | MO_UO; + memop |= MO_TE; tcg_gen_concat_i64_i128(src2, src2l, src2h); tcg_gen_concat_i64_i128(dest, destl, desth); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); - tcg_gen_atomic_cmpxchg_i128(dest, src1, dest, src2, ctx->mem_idx, - (MO_ALIGN | MO_TE | MO_UO)); + tcg_gen_atomic_cmpxchg_i128(dest, src1, dest, src2, ctx->mem_idx, memop); tcg_gen_extr_i128_i64(destl, desth, dest); diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index c8dc102c8e..172c2c19c1 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -175,7 +175,7 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) return false; } - MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TE | MO_UL : MO_TE | MO_UQ; + MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_UL : MO_UQ; int reg_size = memop_size(memop); target_ulong stack_adj = ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + a->spimm; @@ -185,6 +185,7 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) tcg_gen_addi_tl(addr, sp, stack_adj - reg_size); + memop |= MO_TE; for (i = X_Sn + 11; i >= 0; i--) { if (reg_bitmap & (1 << i)) { TCGv dest = dest_gpr(ctx, i); @@ -228,7 +229,7 @@ static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a) return false; } - MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TE | MO_UL : MO_TE | MO_UQ; + MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_UL : MO_UQ; int reg_size = memop_size(memop); target_ulong stack_adj = ROUND_UP(ctpop32(reg_bitmap) * reg_size, 16) + a->spimm; @@ -238,6 +239,7 @@ static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a) tcg_gen_subi_tl(addr, sp, reg_size); + memop |= MO_TE; for (i = X_Sn + 11; i >= 0; i--) { if (reg_bitmap & (1 << i)) { TCGv val = get_gpr(ctx, i, EXT_NONE); diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc index eec478afcb..5355cd46c3 100644 --- a/target/riscv/insn_trans/trans_rvzfh.c.inc +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc @@ -42,12 +42,14 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) { + MemOp memop = MO_UW; TCGv_i64 dest; TCGv t0; REQUIRE_FPU; REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx); + memop |= MO_TE; decode_save_opc(ctx, 0); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { @@ -57,7 +59,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) } dest = cpu_fpr[a->rd]; - tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TE | MO_UW); + tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, memop); gen_nanbox_h(dest, dest); mark_fs_dirty(ctx); @@ -66,11 +68,13 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) static bool trans_fsh(DisasContext *ctx, arg_fsh *a) { + MemOp memop = MO_UW; TCGv t0; REQUIRE_FPU; REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx); + memop |= MO_TE; decode_save_opc(ctx, 0); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { @@ -79,7 +83,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) t0 = temp; } - tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TE | MO_UW); + tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, memop); return true; } diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc index c555596617..89eed00758 100644 --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc @@ -100,12 +100,13 @@ static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a) TCGv dest = dest_gpr(ctx, a->rd); TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); + MemOp memop = MO_ALIGN | MO_SL; decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); src1 = get_address(ctx, a->rs1, 0); - tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), - (MO_ALIGN | MO_TE | MO_SL)); + memop |= MO_TE; + tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), memop); gen_set_gpr(ctx, a->rd, dest); return true; } @@ -129,12 +130,13 @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a) TCGv dest = dest_gpr(ctx, a->rd); TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); + MemOp memop = MO_ALIGN | MO_SQ; decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); src1 = get_address(ctx, a->rs1, 0); - tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), - (MO_ALIGN | MO_TE | MO_SQ)); + memop |= MO_TE; + tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), memop); gen_set_gpr(ctx, a->rd, dest); return true; } From 504f7f304ff6a05da44571103832315910531d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:43 +0200 Subject: [PATCH 12/25] target/riscv: Introduce mo_endian() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mo_endian() returns the target endianness from DisasContext. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Heinrich Schuchardt Reviewed-by: Richard Henderson Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-13-philmd@linaro.org> Signed-off-by: Alistair Francis --- target/riscv/insn_trans/trans_rva.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvd.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvf.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvi.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvzacas.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvzce.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvzfh.c.inc | 4 ++-- target/riscv/insn_trans/trans_rvzicfiss.c.inc | 4 ++-- target/riscv/insn_trans/trans_xthead.c.inc | 16 ++++++++-------- target/riscv/translate.c | 18 +++++++++++++++--- 10 files changed, 39 insertions(+), 27 deletions(-) diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc index 8737e8d60d..a7a3278d24 100644 --- a/target/riscv/insn_trans/trans_rva.c.inc +++ b/target/riscv/insn_trans/trans_rva.c.inc @@ -35,7 +35,7 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGv src1; mop |= MO_ALIGN; - mop |= MO_TE; + mop |= mo_endian(ctx); decode_save_opc(ctx, 0); src1 = get_address(ctx, a->rs1, 0); @@ -65,7 +65,7 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGLabel *l2 = gen_new_label(); mop |= MO_ALIGN; - mop |= MO_TE; + mop |= mo_endian(ctx); decode_save_opc(ctx, 0); src1 = get_address(ctx, a->rs1, 0); diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc index 62b7535815..ffea0c2a1f 100644 --- a/target/riscv/insn_trans/trans_rvd.c.inc +++ b/target/riscv/insn_trans/trans_rvd.c.inc @@ -60,7 +60,7 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a) } else { memop |= MO_ATOM_IFALIGN; } - memop |= MO_TE; + memop |= mo_endian(ctx); decode_save_opc(ctx, 0); addr = get_address(ctx, a->rs1, a->imm); @@ -85,7 +85,7 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a) } else { memop |= MO_ATOM_IFALIGN; } - memop |= MO_TE; + memop |= mo_endian(ctx); decode_save_opc(ctx, 0); addr = get_address(ctx, a->rs1, a->imm); diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc index 878417eae9..89fb0f604a 100644 --- a/target/riscv/insn_trans/trans_rvf.c.inc +++ b/target/riscv/insn_trans/trans_rvf.c.inc @@ -48,7 +48,7 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - memop |= MO_TE; + memop |= mo_endian(ctx); if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } @@ -71,7 +71,7 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a) REQUIRE_FPU; REQUIRE_EXT(ctx, RVF); - memop |= MO_TE; + memop |= mo_endian(ctx); if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 9a03058f46..54b9b4f241 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -402,7 +402,7 @@ static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) { bool out; - memop |= MO_TE; + memop |= mo_endian(ctx); if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } @@ -504,7 +504,7 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop) static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop) { - memop |= MO_TE; + memop |= mo_endian(ctx); if (ctx->cfg_ptr->ext_zama16b) { memop |= MO_ATOM_WITHIN16; } diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc index 6458ac4f24..8d94b83ce9 100644 --- a/target/riscv/insn_trans/trans_rvzacas.c.inc +++ b/target/riscv/insn_trans/trans_rvzacas.c.inc @@ -76,7 +76,7 @@ static bool gen_cmpxchg64(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGv src1 = get_address(ctx, a->rs1, 0); TCGv_i64 src2 = get_gpr_pair(ctx, a->rs2); - mop |= MO_TE; + mop |= mo_endian(ctx); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); tcg_gen_atomic_cmpxchg_i64(dest, src1, dest, src2, ctx->mem_idx, mop); @@ -121,7 +121,7 @@ static bool trans_amocas_q(DisasContext *ctx, arg_amocas_q *a) TCGv_i64 desth = get_gpr(ctx, a->rd == 0 ? 0 : a->rd + 1, EXT_NONE); MemOp memop = MO_ALIGN | MO_UO; - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_concat_i64_i128(src2, src2l, src2h); tcg_gen_concat_i64_i128(dest, destl, desth); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index 172c2c19c1..0d3ba40e52 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -185,7 +185,7 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) tcg_gen_addi_tl(addr, sp, stack_adj - reg_size); - memop |= MO_TE; + memop |= mo_endian(ctx); for (i = X_Sn + 11; i >= 0; i--) { if (reg_bitmap & (1 << i)) { TCGv dest = dest_gpr(ctx, i); @@ -239,7 +239,7 @@ static bool trans_cm_push(DisasContext *ctx, arg_cm_push *a) tcg_gen_subi_tl(addr, sp, reg_size); - memop |= MO_TE; + memop |= mo_endian(ctx); for (i = X_Sn + 11; i >= 0; i--) { if (reg_bitmap & (1 << i)) { TCGv val = get_gpr(ctx, i, EXT_NONE); diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc index 5355cd46c3..791ee51f65 100644 --- a/target/riscv/insn_trans/trans_rvzfh.c.inc +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc @@ -49,7 +49,7 @@ static bool trans_flh(DisasContext *ctx, arg_flh *a) REQUIRE_FPU; REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx); - memop |= MO_TE; + memop |= mo_endian(ctx); decode_save_opc(ctx, 0); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { @@ -74,7 +74,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a) REQUIRE_FPU; REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx); - memop |= MO_TE; + memop |= mo_endian(ctx); decode_save_opc(ctx, 0); t0 = get_gpr(ctx, a->rs1, EXT_NONE); if (a->imm) { diff --git a/target/riscv/insn_trans/trans_rvzicfiss.c.inc b/target/riscv/insn_trans/trans_rvzicfiss.c.inc index 89eed00758..0b6ad57965 100644 --- a/target/riscv/insn_trans/trans_rvzicfiss.c.inc +++ b/target/riscv/insn_trans/trans_rvzicfiss.c.inc @@ -105,7 +105,7 @@ static bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a) decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); src1 = get_address(ctx, a->rs1, 0); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), memop); gen_set_gpr(ctx, a->rd, dest); return true; @@ -135,7 +135,7 @@ static bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a) decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); src1 = get_address(ctx, a->rs1, 0); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), memop); gen_set_gpr(ctx, a->rd, dest); return true; diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc index 2f31842791..f8b95c6498 100644 --- a/target/riscv/insn_trans/trans_xthead.c.inc +++ b/target/riscv/insn_trans/trans_xthead.c.inc @@ -349,7 +349,7 @@ static bool gen_fload_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv_i64 rd = cpu_fpr[a->rd]; TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop); if ((memop & MO_SIZE) == MO_32) { gen_nanbox_s(rd, rd); @@ -370,7 +370,7 @@ static bool gen_fstore_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv_i64 rd = cpu_fpr[a->rd]; TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop); return true; @@ -570,7 +570,7 @@ static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop, TCGv rd = dest_gpr(ctx, a->rd); TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop); tcg_gen_addi_tl(rs1, rs1, imm); gen_set_gpr(ctx, a->rd, rd); @@ -591,7 +591,7 @@ static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop, TCGv data = get_gpr(ctx, a->rd, EXT_NONE); TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop); tcg_gen_addi_tl(rs1, rs1, imm); gen_set_gpr(ctx, a->rs1, rs1); @@ -747,7 +747,7 @@ static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv rd = dest_gpr(ctx, a->rd); TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop); gen_set_gpr(ctx, a->rd, rd); @@ -765,7 +765,7 @@ static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop, TCGv data = get_gpr(ctx, a->rd, EXT_NONE); TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop); return true; @@ -926,7 +926,7 @@ static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, addr1 = get_address(ctx, a->rs, imm); addr2 = get_address(ctx, a->rs, memop_size(memop) + imm); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_ld_tl(t1, addr1, ctx->mem_idx, memop); tcg_gen_qemu_ld_tl(t2, addr2, ctx->mem_idx, memop); gen_set_gpr(ctx, a->rd1, t1); @@ -965,7 +965,7 @@ static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop, addr1 = get_address(ctx, a->rs, imm); addr2 = get_address(ctx, a->rs, memop_size(memop) + imm); - memop |= MO_TE; + memop |= mo_endian(ctx); tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop); tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop); return true; diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 2e6f39aa02..e1f4dc5ffd 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -126,6 +126,18 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext) return ctx->misa_ext & ext; } +static inline MemOp mo_endian(DisasContext *ctx) +{ + /* + * A couple of bits in MSTATUS set the endianness: + * - MSTATUS_UBE (User-mode), + * - MSTATUS_SBE (Supervisor-mode), + * - MSTATUS_MBE (Machine-mode) + * but we don't implement that yet. + */ + return MO_TE; +} + #ifdef TARGET_RISCV32 #define get_xl(ctx) MXL_RV32 #elif defined(CONFIG_USER_ONLY) @@ -142,7 +154,7 @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext) #define get_address_xl(ctx) ((ctx)->address_xl) #endif -#define mxl_memop(ctx) ((get_xl(ctx) + 1) | MO_TE) +#define mxl_memop(ctx) ((get_xl(ctx) + 1) | mo_endian(ctx)) /* The word size for this machine mode. */ static inline int __attribute__((unused)) get_xlen(DisasContext *ctx) @@ -1135,7 +1147,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a, TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); MemOp size = mop & MO_SIZE; - mop |= MO_TE; + mop |= mo_endian(ctx); if (ctx->cfg_ptr->ext_zama16b && size >= MO_32) { mop |= MO_ATOM_WITHIN16; } else { @@ -1156,7 +1168,7 @@ static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop) TCGv src1 = get_address(ctx, a->rs1, 0); TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); - mop |= MO_TE; + mop |= mo_endian(ctx); decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop); From d652720ecc6e6b62d358db07fb1b1b4c2578243b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 10 Oct 2025 17:50:44 +0200 Subject: [PATCH 13/25] target/riscv: Introduce mo_endian_env() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mo_endian_env() returns the target endianness from CPUArchState. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Heinrich Schuchardt Reviewed-by: Alistair Francis Message-ID: <20251010155045.78220-14-philmd@linaro.org> [ Changes by AF: - Only define mo_endian_env() for softmmu ] Signed-off-by: Alistair Francis --- target/riscv/op_helper.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index c486f771d3..6ccc127c30 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -28,6 +28,20 @@ #include "exec/tlb-flags.h" #include "trace.h" +#ifndef CONFIG_USER_ONLY +static inline MemOp mo_endian_env(CPURISCVState *env) +{ + /* + * A couple of bits in MSTATUS set the endianness: + * - MSTATUS_UBE (User-mode), + * - MSTATUS_SBE (Supervisor-mode), + * - MSTATUS_MBE (Machine-mode) + * but we don't implement that yet. + */ + return MO_TE; +} +#endif + /* Exceptions processing helpers */ G_NORETURN void riscv_raise_exception(CPURISCVState *env, RISCVException exception, @@ -633,7 +647,7 @@ target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UW, mmu_idx); return cpu_ldw_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -642,7 +656,7 @@ target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UL, mmu_idx); return cpu_ldl_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -651,7 +665,7 @@ target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UQ, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UQ, mmu_idx); return cpu_ldq_mmu(env, adjust_addr_virt(env, addr), oi, ra); } @@ -669,7 +683,7 @@ void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UW, mmu_idx); cpu_stw_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -678,7 +692,7 @@ void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UL, mmu_idx); cpu_stl_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -687,7 +701,7 @@ void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, false, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UQ, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UQ, mmu_idx); cpu_stq_mmu(env, adjust_addr_virt(env, addr), val, oi, ra); } @@ -703,7 +717,7 @@ target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, true, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UW, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UW, mmu_idx); return cpu_ldw_code_mmu(env, addr, oi, GETPC()); } @@ -712,7 +726,7 @@ target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong addr) { uintptr_t ra = GETPC(); int mmu_idx = check_access_hlsv(env, true, ra); - MemOpIdx oi = make_memop_idx(MO_TE | MO_UL, mmu_idx); + MemOpIdx oi = make_memop_idx(mo_endian_env(env) | MO_UL, mmu_idx); return cpu_ldl_code_mmu(env, addr, oi, ra); } From e530e5d034daf6865239b94705dd57c8c45cf4e4 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Oct 2025 13:00:46 -0700 Subject: [PATCH 14/25] hw/net/cadence_gem: Support two Ethernet interfaces connected to single MDIO bus The Microchip PolarFire SoC Icicle Kit supports two Ethernet interfaces. The PHY on each may be connected to separate MDIO busses, or both may be connected on the same MDIO bus using different PHY addresses. To be able to support two PHY instances on a single MDIO bus, two properties are needed: First, there needs to be a flag indicating if the MDIO bus on a given Ethernet interface is connected. If not, attempts to read from this bus must always return 0xffff. Implement this property as phy-connected. Second, if the MDIO bus on an interface is active, it needs a link to the consumer interface to be able to provide PHY access for it. Implement this property as phy-consumer. Signed-off-by: Guenter Roeck Acked-by: Alistair Francis Message-ID: <20251004200049.871646-2-linux@roeck-us.net> Signed-off-by: Alistair Francis --- hw/net/cadence_gem.c | 24 ++++++++++++++++++------ include/hw/net/cadence_gem.h | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 44446666de..520324adfd 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -1541,12 +1541,20 @@ static void gem_handle_phy_access(CadenceGEMState *s) { uint32_t val = s->regs[R_PHYMNTNC]; uint32_t phy_addr, reg_num; + CadenceGEMState *ps = s; + uint32_t op; phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR); + op = FIELD_EX32(val, PHYMNTNC, OP); - if (phy_addr != s->phy_addr) { - /* no phy at this address */ - if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_READ) { + /* Switch phy to consumer interface if there is an address match */ + if (s->phy_consumer && phy_addr == s->phy_consumer->phy_addr) { + ps = s->phy_consumer; + } + + if (!s->phy_connected || phy_addr != ps->phy_addr) { + /* phy not connected or no phy at this address */ + if (op == MDIO_OP_READ) { s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA, 0xffff); } return; @@ -1554,14 +1562,14 @@ static void gem_handle_phy_access(CadenceGEMState *s) reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR); - switch (FIELD_EX32(val, PHYMNTNC, OP)) { + switch (op) { case MDIO_OP_READ: s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA, - gem_phy_read(s, reg_num)); + gem_phy_read(ps, reg_num)); break; case MDIO_OP_WRITE: - gem_phy_write(s, reg_num, val); + gem_phy_write(ps, reg_num, val); break; default: @@ -1813,6 +1821,10 @@ static const Property gem_properties[] = { num_type2_screeners, 4), DEFINE_PROP_UINT16("jumbo-max-len", CadenceGEMState, jumbo_max_len, 10240), + DEFINE_PROP_BOOL("phy-connected", CadenceGEMState, phy_connected, true), + DEFINE_PROP_LINK("phy-consumer", CadenceGEMState, phy_consumer, + TYPE_CADENCE_GEM, CadenceGEMState *), + DEFINE_PROP_LINK("dma", CadenceGEMState, dma_mr, TYPE_MEMORY_REGION, MemoryRegion *), }; diff --git a/include/hw/net/cadence_gem.h b/include/hw/net/cadence_gem.h index 91ebb5c8ae..21e7319f53 100644 --- a/include/hw/net/cadence_gem.h +++ b/include/hw/net/cadence_gem.h @@ -81,6 +81,9 @@ struct CadenceGEMState { uint8_t phy_loop; /* Are we in phy loopback? */ + bool phy_connected; /* true if connected */ + struct CadenceGEMState *phy_consumer; + /* The current DMA descriptor pointers */ uint32_t rx_desc_addr[MAX_PRIORITY_QUEUES]; uint32_t tx_desc_addr[MAX_PRIORITY_QUEUES]; From a79a4b9c2e5fa276d7a3317e0fdfe42edbb04555 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Oct 2025 13:00:47 -0700 Subject: [PATCH 15/25] hw/riscv: microchip_pfsoc: Connect Ethernet PHY channels Signed-off-by: Guenter Roeck Acked-by: Alistair Francis Message-ID: <20251004200049.871646-3-linux@roeck-us.net> Signed-off-by: Alistair Francis --- hw/riscv/microchip_pfsoc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 2e74783fce..9fbfba8ece 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -414,6 +414,8 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gem0), "revision", GEM_REVISION, errp); object_property_set_int(OBJECT(&s->gem0), "phy-addr", 8, errp); + object_property_set_bool(OBJECT(&s->gem0), "phy-connected", false, errp); + sysbus_realize(SYS_BUS_DEVICE(&s->gem0), errp); sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem0), 0, memmap[MICROCHIP_PFSOC_GEM0].base); @@ -422,6 +424,8 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gem1), "revision", GEM_REVISION, errp); object_property_set_int(OBJECT(&s->gem1), "phy-addr", 9, errp); + object_property_set_link(OBJECT(&s->gem1), "phy-consumer", + OBJECT(&s->gem0), errp); sysbus_realize(SYS_BUS_DEVICE(&s->gem1), errp); sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem1), 0, memmap[MICROCHIP_PFSOC_GEM1].base); From 35a5e8792046df64df10550cd7de4bbc0a2c1018 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Oct 2025 13:00:48 -0700 Subject: [PATCH 16/25] hw/net/cadence_gem: Add pcs-enabled property The Linux kernel checks the PCS disabled bit in the R_DESCONF register to determine if SGMII is supported. If the bit is set, SGMII support is disabled. Since the Microchip Icicle devicetree file configures SGMII interface mode, enabling the Ethernet interfaces fails when booting the Linux kernel. Add pcs-enabled property to to let the driver know if PCS should be enabled. Set the flag to false by default (indicating that PCS is disabled) to match the exiting code. Signed-off-by: Guenter Roeck Acked-by: Alistair Francis Message-ID: <20251004200049.871646-4-linux@roeck-us.net> Signed-off-by: Alistair Francis --- hw/net/cadence_gem.c | 7 ++++++- include/hw/net/cadence_gem.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 520324adfd..44896f1801 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -1477,7 +1477,10 @@ static void gem_reset(DeviceState *d) s->regs[R_TXPARTIALSF] = 0x000003ff; s->regs[R_RXPARTIALSF] = 0x000003ff; s->regs[R_MODID] = s->revision; - s->regs[R_DESCONF] = 0x02D00111; + s->regs[R_DESCONF] = 0x02D00110; + if (!s->pcs_enabled) { + s->regs[R_DESCONF] |= 0x00000001; + } s->regs[R_DESCONF2] = 0x2ab10000 | s->jumbo_max_len; s->regs[R_DESCONF5] = 0x002f2045; s->regs[R_DESCONF6] = R_DESCONF6_DMA_ADDR_64B_MASK; @@ -1821,6 +1824,8 @@ static const Property gem_properties[] = { num_type2_screeners, 4), DEFINE_PROP_UINT16("jumbo-max-len", CadenceGEMState, jumbo_max_len, 10240), + DEFINE_PROP_BOOL("pcs-enabled", CadenceGEMState, + pcs_enabled, false), DEFINE_PROP_BOOL("phy-connected", CadenceGEMState, phy_connected, true), DEFINE_PROP_LINK("phy-consumer", CadenceGEMState, phy_consumer, TYPE_CADENCE_GEM, CadenceGEMState *), diff --git a/include/hw/net/cadence_gem.h b/include/hw/net/cadence_gem.h index 21e7319f53..e63941f18f 100644 --- a/include/hw/net/cadence_gem.h +++ b/include/hw/net/cadence_gem.h @@ -62,6 +62,7 @@ struct CadenceGEMState { uint8_t num_type2_screeners; uint32_t revision; uint16_t jumbo_max_len; + bool pcs_enabled; /* GEM registers backing store */ uint32_t regs[CADENCE_GEM_MAXREG]; From cdbb7c3fa6f67d3370965cb0e4bbfdbca04c0913 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Sat, 4 Oct 2025 13:00:49 -0700 Subject: [PATCH 17/25] microchip icicle: Enable PCS on Cadence Ethernet PCS needs to be enabled for SGMII to be supported by the Linux kernel. Signed-off-by: Guenter Roeck Acked-by: Alistair Francis Message-ID: <20251004200049.871646-5-linux@roeck-us.net> Signed-off-by: Alistair Francis --- hw/riscv/microchip_pfsoc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 9fbfba8ece..4c939d8e96 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -415,6 +415,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gem0), "revision", GEM_REVISION, errp); object_property_set_int(OBJECT(&s->gem0), "phy-addr", 8, errp); object_property_set_bool(OBJECT(&s->gem0), "phy-connected", false, errp); + object_property_set_bool(OBJECT(&s->gem0), "pcs-enabled", true, errp); sysbus_realize(SYS_BUS_DEVICE(&s->gem0), errp); sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem0), 0, @@ -426,6 +427,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gem1), "phy-addr", 9, errp); object_property_set_link(OBJECT(&s->gem1), "phy-consumer", OBJECT(&s->gem0), errp); + object_property_set_bool(OBJECT(&s->gem1), "pcs-enabled", true, errp); sysbus_realize(SYS_BUS_DEVICE(&s->gem1), errp); sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem1), 0, memmap[MICROCHIP_PFSOC_GEM1].base); From 5e3e066e4ac894aff3e8dd3a072bca9c1986b2ff Mon Sep 17 00:00:00 2001 From: Jialong Yang Date: Sat, 11 Oct 2025 08:54:39 +0800 Subject: [PATCH 18/25] aplic: fix mask for smsiaddrcfgh 4.5.4. Supervisor MSI address configuration (smsiaddrcfg and smsiaddrcfgh) smsiaddrcfgh: bits 22:20 LHXS(WARL) bits 11:0 High Base PPN(WARL) Signed-off-by: Jialong Yang Acked-by: Alistair Francis Message-ID: <44f3e0d1.161.199d0c338b0.Coremail.z_bajeer@yeah.net> Signed-off-by: Alistair Francis Cc: qemu-stable@nongnu.org --- hw/intc/riscv_aplic.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index a1d9fa5085..6dccca73af 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -96,7 +96,7 @@ (APLIC_xMSICFGADDR_PPN_HHX_MASK(__hhxw) << \ APLIC_xMSICFGADDR_PPN_HHX_SHIFT(__hhxs)) -#define APLIC_xMSICFGADDRH_VALID_MASK \ +#define APLIC_MMSICFGADDRH_VALID_MASK \ (APLIC_xMSICFGADDRH_L | \ (APLIC_xMSICFGADDRH_HHXS_MASK << APLIC_xMSICFGADDRH_HHXS_SHIFT) | \ (APLIC_xMSICFGADDRH_LHXS_MASK << APLIC_xMSICFGADDRH_LHXS_SHIFT) | \ @@ -104,6 +104,10 @@ (APLIC_xMSICFGADDRH_LHXW_MASK << APLIC_xMSICFGADDRH_LHXW_SHIFT) | \ APLIC_xMSICFGADDRH_BAPPN_MASK) +#define APLIC_SMSICFGADDRH_VALID_MASK \ + ((APLIC_xMSICFGADDRH_LHXS_MASK << APLIC_xMSICFGADDRH_LHXS_SHIFT) | \ + APLIC_xMSICFGADDRH_BAPPN_MASK) + #define APLIC_SETIP_BASE 0x1c00 #define APLIC_SETIPNUM 0x1cdc @@ -184,7 +188,7 @@ void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr) addr >>= APLIC_xMSICFGADDR_PPN_SHIFT; aplic->kvm_msicfgaddr = extract64(addr, 0, 32); aplic->kvm_msicfgaddrH = extract64(addr, 32, 32) & - APLIC_xMSICFGADDRH_VALID_MASK; + APLIC_MMSICFGADDRH_VALID_MASK; } #endif } @@ -409,13 +413,8 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic, msicfgaddr = aplic->kvm_msicfgaddr; msicfgaddrH = ((uint64_t)aplic->kvm_msicfgaddrH << 32); } else { - if (aplic->mmode) { - msicfgaddr = aplic_m->mmsicfgaddr; - msicfgaddrH = aplic_m->mmsicfgaddrH; - } else { - msicfgaddr = aplic_m->smsicfgaddr; - msicfgaddrH = aplic_m->smsicfgaddrH; - } + msicfgaddr = aplic_m->mmsicfgaddr; + msicfgaddrH = aplic_m->mmsicfgaddrH; } lhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXS_SHIFT) & @@ -427,6 +426,14 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic, hhxw = (msicfgaddrH >> APLIC_xMSICFGADDRH_HHXW_SHIFT) & APLIC_xMSICFGADDRH_HHXW_MASK; + if (!aplic->kvm_splitmode && !aplic->mmode) { + msicfgaddrH = aplic_m->smsicfgaddrH; + msicfgaddr = aplic_m->smsicfgaddr; + + lhxs = (msicfgaddrH >> APLIC_xMSICFGADDRH_LHXS_SHIFT) & + APLIC_xMSICFGADDRH_LHXS_MASK; + } + group_idx = hart_idx >> lhxw; addr = msicfgaddr; @@ -771,7 +778,7 @@ static void riscv_aplic_write(void *opaque, hwaddr addr, uint64_t value, } else if (aplic->mmode && aplic->msimode && (addr == APLIC_MMSICFGADDRH)) { if (!(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) { - aplic->mmsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK; + aplic->mmsicfgaddrH = value & APLIC_MMSICFGADDRH_VALID_MASK; } } else if (aplic->mmode && aplic->msimode && (addr == APLIC_SMSICFGADDR)) { @@ -792,7 +799,7 @@ static void riscv_aplic_write(void *opaque, hwaddr addr, uint64_t value, (addr == APLIC_SMSICFGADDRH)) { if (aplic->num_children && !(aplic->mmsicfgaddrH & APLIC_xMSICFGADDRH_L)) { - aplic->smsicfgaddrH = value & APLIC_xMSICFGADDRH_VALID_MASK; + aplic->smsicfgaddrH = value & APLIC_SMSICFGADDRH_VALID_MASK; } } else if ((APLIC_SETIP_BASE <= addr) && (addr < (APLIC_SETIP_BASE + aplic->bitfield_words * 4))) { From 49c24c2ae5c02ea5351f2657217befd272e5333c Mon Sep 17 00:00:00 2001 From: Djordje Todorovic Date: Sat, 18 Oct 2025 15:45:28 +0000 Subject: [PATCH 19/25] hw/intc: Allow gaps in hartids for aclint and aplic This is needed for riscv based CPUs by MIPS since those may have sparse hart-ID layouts. ACLINT and APLIC still assume a dense range, and if a hart is missing, this causes NULL derefs. Signed-off-by: Chao-ying Fu Signed-off-by: Djordje Todorovic Reviewed-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Message-ID: <20251018154522.745788-2-djordje.todorovic@htecgroup.com> Signed-off-by: Alistair Francis --- hw/intc/riscv_aclint.c | 18 ++++++++++++++++-- hw/intc/riscv_aplic.c | 13 ++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index 9f4c36e965..c6f13f647e 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -297,7 +297,12 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) s->timecmp = g_new0(uint64_t, s->num_harts); /* Claim timer interrupt bits */ for (i = 0; i < s->num_harts; i++) { - RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i)); + CPUState *cpu_by_hartid = cpu_by_arch_id(s->hartid_base + i); + if (cpu_by_hartid == NULL) { + /* Valid for sparse hart layouts - skip this hart ID */ + continue; + } + RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid); if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) { error_report("MTIP already claimed"); exit(1); @@ -489,7 +494,12 @@ static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp) /* Claim software interrupt bits */ for (i = 0; i < swi->num_harts; i++) { - RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i)); + CPUState *cpu_by_hartid = cpu_by_arch_id(swi->hartid_base + i); + if (cpu_by_hartid == NULL) { + /* Valid for sparse hart layouts - skip this hart ID */ + continue; + } + RISCVCPU *cpu = RISCV_CPU(cpu_by_hartid); /* We don't claim mip.SSIP because it is writable by software */ if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) { error_report("MSIP already claimed"); @@ -553,6 +563,10 @@ DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base, for (i = 0; i < num_harts; i++) { CPUState *cpu = cpu_by_arch_id(hartid_base + i); + if (cpu == NULL) { + /* Valid for sparse hart layouts - skip this hart ID */ + continue; + } RISCVCPU *rvcpu = RISCV_CPU(cpu); qdev_connect_gpio_out(dev, i, diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index 6dccca73af..a2041e7022 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -910,9 +910,12 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) if (!aplic->msimode) { /* Claim the CPU interrupt to be triggered by this APLIC */ for (i = 0; i < aplic->num_harts; i++) { - RISCVCPU *cpu; - - cpu = RISCV_CPU(cpu_by_arch_id(aplic->hartid_base + i)); + CPUState *temp = cpu_by_arch_id(aplic->hartid_base + i); + if (temp == NULL) { + /* Valid for sparse hart layouts - skip this hart ID */ + continue; + } + RISCVCPU *cpu = RISCV_CPU(temp); if (riscv_cpu_claim_interrupts(cpu, (aplic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) { error_report("%s already claimed", @@ -1095,6 +1098,10 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, if (!msimode) { for (i = 0; i < num_harts; i++) { CPUState *cpu = cpu_by_arch_id(hartid_base + i); + if (cpu == NULL) { + /* Valid for sparse hart layouts - skip this hart ID */ + continue; + } qdev_connect_gpio_out_named(dev, NULL, i, qdev_get_gpio_in(DEVICE(cpu), From 2a21cbee47a124edf43fc9ee156d7093e2f957fd Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Wed, 22 Oct 2025 08:11:05 -0300 Subject: [PATCH 20/25] target/riscv/kvm: fix env->priv setting in reset_regs_csr() This patch was originally made by Gitlab user Bo Gan (@ganboing) 4 months ago in the context of issue [1]. I asked the author to send a patch to the mailing list ~3 months ago and got no reply. I'm sending the patch myself because we already missed 10.1 without this fix. I'll also just post verbatim Bo Gan comment in the commit msg: "In RISCV Linux with KVM enabled, gdbstub is broken. The get_physical_address isn't able to page-walk correctly and resolve the physical page. This is due to that the vcpu is being treated as starting in M mode even if KVM enabled. However, with KVM, the vcpu is actually started in S mode. The mmu_idx will give 3 (M), instead of 1 (S), resulting in Guest PA == VA (wrong)!" Set env->priv to PRV_S in kvm_riscv_reset_regs_csr() since the VCPU is always started in S-mode for KVM. [1] https://gitlab.com/qemu-project/qemu/-/issues/2991 Cc: qemu-stable@nongnu.org Closes: https://gitlab.com/qemu-project/qemu/-/issues/2991 Originally-by: Bo Gan (@ganboing in Gitlab) Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Message-ID: <20251022111105.483992-1-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis --- target/riscv/kvm/kvm-cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 0dd0d59d41..000e44b2b7 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -705,6 +705,7 @@ static void kvm_riscv_reset_regs_csr(CPURISCVState *env) env->satp = 0; env->scounteren = 0; env->senvcfg = 0; + env->priv = PRV_S; } static int kvm_riscv_get_regs_fp(CPUState *cs) From f131f10b63fac3bfa8f96c67a446c36bfcccbe6a Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Wed, 22 Oct 2025 09:56:43 -0300 Subject: [PATCH 21/25] target/riscv/riscv-qmp-cmds.c: coverity-related fixes Coverity CID 1641401 reports that, in reg_is_ulong_integer(), we're dereferencing a NULL pointer in "reg1" when using it in strcasecmp() call. A similar case is reported with CID 1641393. In theory that will never happen - it's guaranteed that both "reg1" and "reg2" is non-NULL because we're retrieving them in compile-time from static arrays. Coverity doesn't know that though. To make Coverity happier and add a bit more clarity in the code, g_assert() each token to make it clear that those 2 values aren't supposed to be NULL ever. Do that in both reg_is_ulong_integer() and reg_is_u64_fpu(). We're also taking the opportunity to implement suggestions made by Peter in [1] in both functions: - use g_strsplit() instead of strtok(); - use g_ascii_strcasecmp() instead of strcasecmp(). [1] https://lore.kernel.org/qemu-devel/CAFEAcA_y4bwd9GANbXnpTy2mv80Vg_jp+A-VkQS5V6f0+BFRAA@mail.gmail.com/ Coverity: CID 1641393, 1641401 Fixes: e06d209aa6 ("target/riscv: implement MonitorDef HMP API") Suggested-by: Peter Maydell Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Message-ID: <20251022125643.588947-1-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis --- target/riscv/riscv-qmp-cmds.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c index c499f9b9a7..d5e9bec0f8 100644 --- a/target/riscv/riscv-qmp-cmds.c +++ b/target/riscv/riscv-qmp-cmds.c @@ -273,12 +273,13 @@ static bool reg_is_ulong_integer(CPURISCVState *env, const char *name, } for (int i = 0; i < 32; i++) { - g_autofree char *reg_name = g_strdup(reg_names[i]); - char *reg1 = strtok(reg_name, "/"); - char *reg2 = strtok(NULL, "/"); + g_auto(GStrv) reg_name = g_strsplit(reg_names[i], "/", 2); - if (strcasecmp(reg1, name) == 0 || - (reg2 && strcasecmp(reg2, name) == 0)) { + g_assert(reg_name[0]); + g_assert(reg_name[1]); + + if (g_ascii_strcasecmp(reg_name[0], name) == 0 || + g_ascii_strcasecmp(reg_name[1], name) == 0) { *val = vals[i]; return true; } @@ -294,12 +295,13 @@ static bool reg_is_u64_fpu(CPURISCVState *env, const char *name, uint64_t *val) } for (int i = 0; i < 32; i++) { - g_autofree char *reg_name = g_strdup(riscv_fpr_regnames[i]); - char *reg1 = strtok(reg_name, "/"); - char *reg2 = strtok(NULL, "/"); + g_auto(GStrv) reg_name = g_strsplit(riscv_fpr_regnames[i], "/", 2); - if (strcasecmp(reg1, name) == 0 || - (reg2 && strcasecmp(reg2, name) == 0)) { + g_assert(reg_name[0]); + g_assert(reg_name[1]); + + if (g_ascii_strcasecmp(reg_name[0], name) == 0 || + g_ascii_strcasecmp(reg_name[1], name) == 0) { *val = env->fpr[i]; return true; } From 06e01941ffca3c246a9770f477e43118793fde59 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Wed, 22 Oct 2025 09:43:40 -0300 Subject: [PATCH 22/25] target/riscv: fix riscv_cpu_sirq_pending() mask We're filtering out (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP) from S-mode pending interrupts without apparent reason. There's no special treatment for these ints as far as the spec goes, and this filtering is causing read_stopi() to miss those VS interrupts [1]. We shouldn't return delegated VS interrupts in S-mode though, so change the current mask with "~env->hideleg". Note that this is the same handling we're doing in riscv_cpu_mirq_pending() and env->mideleg. [1] https://gitlab.com/qemu-project/qemu/-/issues/2820 Closes: https://gitlab.com/qemu-project/qemu/-/issues/2820 Signed-off-by: Daniel Henrique Barboza Reviewed-by: Alistair Francis Message-ID: <20251022124340.493358-1-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis Cc: qemu-stable@nongnu.org --- target/riscv/cpu_helper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 3479a62cc7..360db133e2 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -443,8 +443,7 @@ int riscv_cpu_mirq_pending(CPURISCVState *env) int riscv_cpu_sirq_pending(CPURISCVState *env) { - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & - ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg; uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie; return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, From a66d9c37984317cf453a3d1c7341be1d54bb9863 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 21 Oct 2025 14:07:14 +0900 Subject: [PATCH 23/25] target/riscv: Fix a uninitialized variable warning riscv_cpu_validate_v() left its variable, min_vlen, uninitialized if no vector extension is available, causing a compiler warning. Re-define riscv_cpu_validate_v() as no-op when no vector extension is available to prevent the scenario that will read the unintialized variable by construction. It also simplifies its caller as a bonus. Signed-off-by: Akihiko Odaki Reviewed-by: Daniel Henrique Barboza Message-ID: <20251021-vlen-v2-1-1fb581d4c6bf@rsg.ci.i.u-tokyo.ac.jp> Signed-off-by: Alistair Francis --- target/riscv/tcg/tcg-cpu.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 1150bd1469..d3968251fa 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -426,6 +426,8 @@ static void riscv_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg, min_vlen = 64; } else if (cfg->ext_zve32x) { min_vlen = 32; + } else { + return; } if (vlen > RV_VLEN_MAX || vlen < min_vlen) { @@ -676,12 +678,10 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) return; } - if (cpu->cfg.ext_zve32x) { - riscv_cpu_validate_v(env, &cpu->cfg, &local_err); - if (local_err != NULL) { - error_propagate(errp, local_err); - return; - } + riscv_cpu_validate_v(env, &cpu->cfg, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; } /* The Zve64d extension depends on the Zve64f extension */ From 8c9a22b8d626a50985bdd4401013479a71e23f13 Mon Sep 17 00:00:00 2001 From: Jay Chang Date: Wed, 22 Oct 2025 10:41:40 +0800 Subject: [PATCH 24/25] target/riscv: Make PMP granularity configurable Previously, the PMP granularity in qemu always used a minimum granularity of 4 bytes, this patch add pmp-granularity to allow platforms to configure the value. A new CPU parameter pmp-granularity has been introduced to the QEMU command line. For example: -cpu rv64, g=true, c=true, pmp=true, pmp-granularity=1024 If no specific value is provided, the default value is 4 bytes. Signed-off-by: Jay Chang Reviewed-by: Frank Chang Reviewed-by: Jim Shu Reviewed-by: Alistair Francis Message-ID: <20251022024141.42178-2-jay.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/cpu.c | 39 +++++++++++++++++++++++++++++++ target/riscv/cpu.h | 1 + target/riscv/cpu_cfg_fields.h.inc | 1 + 3 files changed, 41 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index a877018ab0..73d4280d7c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1121,6 +1121,7 @@ static void riscv_cpu_init(Object *obj) cpu->cfg.cbop_blocksize = 64; cpu->cfg.cboz_blocksize = 64; cpu->cfg.pmp_regions = 16; + cpu->cfg.pmp_granularity = MIN_RISCV_PMP_GRANULARITY; cpu->env.vext_ver = VEXT_VERSION_1_00_0; cpu->cfg.max_satp_mode = -1; @@ -1606,6 +1607,43 @@ static const PropertyInfo prop_num_pmp_regions = { .set = prop_num_pmp_regions_set, }; +static void prop_pmp_granularity_set(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + RISCVCPU *cpu = RISCV_CPU(obj); + uint32_t value; + + visit_type_uint32(v, name, &value, errp); + + if ((value < MIN_RISCV_PMP_GRANULARITY) && (value & (value - 1))) { + error_setg(errp, "PMP granularity must be a power of 2 and at least %d", + MIN_RISCV_PMP_GRANULARITY); + return; + } + + if (cpu->cfg.pmp_granularity != value && riscv_cpu_is_vendor(obj)) { + cpu_set_prop_err(cpu, name, errp); + return; + } + + cpu_option_add_user_setting(name, value); + cpu->cfg.pmp_granularity = value; +} + +static void prop_pmp_granularity_get(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint32_t value = RISCV_CPU(obj)->cfg.pmp_granularity; + + visit_type_uint32(v, name, &value, errp); +} + +static const PropertyInfo prop_pmp_granularity = { + .description = "pmp-granularity", + .get = prop_pmp_granularity_get, + .set = prop_pmp_granularity_set, +}; + static int priv_spec_from_str(const char *priv_spec_str) { int priv_version = -1; @@ -2606,6 +2644,7 @@ static const Property riscv_cpu_properties[] = { {.name = "mmu", .info = &prop_mmu}, {.name = "pmp", .info = &prop_pmp}, {.name = "num-pmp-regions", .info = &prop_num_pmp_regions}, + {.name = "pmp-granularity", .info = &prop_pmp_granularity}, {.name = "priv_spec", .info = &prop_priv_spec}, {.name = "vext_spec", .info = &prop_vext_spec}, diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 4c13012442..36e7f10037 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -176,6 +176,7 @@ extern RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[]; #define MAX_RISCV_PMPS (64) #define OLD_MAX_RISCV_PMPS (16) +#define MIN_RISCV_PMP_GRANULARITY 4 #if !defined(CONFIG_USER_ONLY) #include "pmp.h" diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc index e2d116f0df..a154ecdc79 100644 --- a/target/riscv/cpu_cfg_fields.h.inc +++ b/target/riscv/cpu_cfg_fields.h.inc @@ -166,6 +166,7 @@ TYPED_FIELD(uint16_t, cbom_blocksize, 0) TYPED_FIELD(uint16_t, cbop_blocksize, 0) TYPED_FIELD(uint16_t, cboz_blocksize, 0) TYPED_FIELD(uint8_t, pmp_regions, 0) +TYPED_FIELD(uint32_t, pmp_granularity, 0) TYPED_FIELD(int8_t, max_satp_mode, -1) From eccf20c02a5ad913a910444dc6bbe5de0952d254 Mon Sep 17 00:00:00 2001 From: Jay Chang Date: Wed, 22 Oct 2025 10:41:41 +0800 Subject: [PATCH 25/25] target/riscv: Make PMP CSRs conform to WARL constraints This patch ensure pmpcfg and pmpaddr comply with WARL constraints. When the PMP granularity is greater than 4 bytes, NA4 mode is not valid per the spec and will be silently ignored. According to the spec, changing pmpcfg.A only affects the "read" value of pmpaddr. When G > 2 and pmpcfg.A is NAPOT, bits pmpaddr[G-2:0] read as all ones. When G > 1 and pmpcfg.A is OFF or TOR, bits pmpaddr[G-1:0] read as all zeros. This allows software to read back the correct granularity value. In addition, when updating the PMP address rule in TOR mode, the start and end addresses of the PMP region should be aligned to the PMP granularity. (The current SPEC only state in TOR mode that bits pmpaddr[G-1:0] do not affect the TOR address-matching logic.) Signed-off-by: Jay Chang Reviewed-by: Frank Chang Reviewed-by: Jim Shu Reviewed-by: Alistair Francis Message-ID: <20251022024141.42178-3-jay.chang@sifive.com> Signed-off-by: Alistair Francis --- target/riscv/pmp.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index 72f1372a49..3ef62d26ad 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -108,6 +108,17 @@ static int pmp_is_invalid_smepmp_cfg(CPURISCVState *env, uint8_t val) g_assert_not_reached(); } } +/* + * Calculate PMP granularity value 'g' + * + * The granularity value 'g' is defined as log2(granularity) - 2, where + * granularity is the minimum alignment requirement for PMP regions in bytes. + */ +static inline int pmp_get_granularity_g(CPURISCVState *env) +{ + return __builtin_ctz(riscv_cpu_cfg(env)->pmp_granularity >> 2); +} + /* * Count the number of active rules. @@ -153,6 +164,15 @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - invalid\n"); } else { + uint8_t a_field = pmp_get_a_field(val); + /* + * When granularity g >= 1 (i.e., granularity > 4 bytes), + * the NA4 (Naturally Aligned 4-byte) mode is not selectable + */ + if ((riscv_cpu_cfg(env)->pmp_granularity > + MIN_RISCV_PMP_GRANULARITY) && (a_field == PMP_AMATCH_NA4)) { + return false; + } env->pmp_state.pmp[pmp_index].cfg_reg = val; pmp_update_rule_addr(env, pmp_index); return true; @@ -199,6 +219,7 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) target_ulong prev_addr = 0u; hwaddr sa = 0u; hwaddr ea = 0u; + int g = pmp_get_granularity_g(env); if (pmp_index >= 1u) { prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg; @@ -211,6 +232,11 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) break; case PMP_AMATCH_TOR: + /* Bits pmpaddr[G-1:0] do not affect the TOR address-matching logic. */ + if (g >= 1) { + prev_addr &= ~((1ULL << g) - 1ULL); + this_addr &= ~((1ULL << g) - 1ULL); + } if (prev_addr >= this_addr) { sa = ea = 0u; break; @@ -577,6 +603,7 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, /* * Handle a read from a pmpaddr CSR + * Change A field of pmpcfg affects the read value of pmpaddr */ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index) { @@ -585,6 +612,25 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index) if (addr_index < pmp_regions) { val = env->pmp_state.pmp[addr_index].addr_reg; + int g = pmp_get_granularity_g(env); + switch (pmp_get_a_field(env->pmp_state.pmp[addr_index].cfg_reg)) { + case PMP_AMATCH_OFF: + /* fallthrough */ + case PMP_AMATCH_TOR: + /* Bit [g-1:0] read all zero */ + if (g >= 1 && g < TARGET_LONG_BITS) { + val &= ~((1ULL << g) - 1ULL); + } + break; + case PMP_AMATCH_NAPOT: + /* Bit [g-2:0] read all one */ + if (g >= 2 && g < TARGET_LONG_BITS) { + val |= ((1ULL << (g - 1)) - 1ULL); + } + break; + default: + break; + } trace_pmpaddr_csr_read(env->mhartid, addr_index, val); } else { qemu_log_mask(LOG_GUEST_ERROR,