Commit 56b72d92da for qemu.org

commit 56b72d92dae51e81a7d7b3814f32236eeec8f965
Author: Bibo Mao <maobibo@loongson.cn>
Date:   Thu Nov 5 11:21:16 2026 +0800

    target/loongarch: Add asrtle_du()/asrtgt_du() helpers

    According to the LoongArch manual, ldle/ldgt/stle/stgt and
    fldle/fldgt/fstle/fstgt perform unsigned address comparison, whereas
    asrtle/asrtgt perform signed address comparison.

    Add the asrtle_du() and asrtgt_du() helpers, and use them for the
    instructions that perform unsigned address comparison.

    Signed-off-by: Bibo Mao <maobibo@loongson.cn>
    Reviewed-by: Xianglai Li <lixianglai@loongson.cn>

diff --git a/target/loongarch/tcg/helper.h b/target/loongarch/tcg/helper.h
index e76c73c775..7ee655b027 100644
--- a/target/loongarch/tcg/helper.h
+++ b/target/loongarch/tcg/helper.h
@@ -7,6 +7,8 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)

 DEF_HELPER_FLAGS_3(asrtle_d, TCG_CALL_NO_WG, void, env, tl, tl)
 DEF_HELPER_FLAGS_3(asrtgt_d, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(asrtle_du, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(asrtgt_du, TCG_CALL_NO_WG, void, env, tl, tl)

 DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
diff --git a/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc b/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
index 628b33330b..9ad90f4379 100644
--- a/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
@@ -81,7 +81,7 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop)

     CHECK_FPE;

-    gen_helper_asrtgt_d(tcg_env, src1, src2);
+    gen_helper_asrtgt_du(tcg_env, src1, src2);
     addr = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
@@ -99,7 +99,7 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop)

     CHECK_FPE;

-    gen_helper_asrtgt_d(tcg_env, src1, src2);
+    gen_helper_asrtgt_du(tcg_env, src1, src2);
     addr = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);

@@ -115,7 +115,7 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop)

     CHECK_FPE;

-    gen_helper_asrtle_d(tcg_env, src1, src2);
+    gen_helper_asrtle_du(tcg_env, src1, src2);
     addr = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
@@ -133,7 +133,7 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop)

     CHECK_FPE;

-    gen_helper_asrtle_d(tcg_env, src1, src2);
+    gen_helper_asrtle_du(tcg_env, src1, src2);
     addr = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);

diff --git a/target/loongarch/tcg/insn_trans/trans_memory.c.inc b/target/loongarch/tcg/insn_trans/trans_memory.c.inc
index dcecf02e54..ae2a0dbf30 100644
--- a/target/loongarch/tcg/insn_trans/trans_memory.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_memory.c.inc
@@ -79,7 +79,7 @@ static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);

-    gen_helper_asrtgt_d(tcg_env, src1, src2);
+    gen_helper_asrtgt_du(tcg_env, src1, src2);
     src1 = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -93,7 +93,7 @@ static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);

-    gen_helper_asrtle_d(tcg_env, src1, src2);
+    gen_helper_asrtle_du(tcg_env, src1, src2);
     src1 = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -107,7 +107,7 @@ static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);

-    gen_helper_asrtgt_d(tcg_env, src1, src2);
+    gen_helper_asrtgt_du(tcg_env, src1, src2);
     src1 = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);

@@ -120,7 +120,7 @@ static bool gen_store_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);

-    gen_helper_asrtle_d(tcg_env, src1, src2);
+    gen_helper_asrtle_du(tcg_env, src1, src2);
     src1 = make_address_i(ctx, src1, 0);
     tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);

diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c
index 44772d03a4..25ed328753 100644
--- a/target/loongarch/tcg/op_helper.c
+++ b/target/loongarch/tcg/op_helper.c
@@ -43,6 +43,26 @@ void HELPER(asrtgt_d)(CPULoongArchState *env, target_ulong rj, target_ulong rk)
     }
 }

+void HELPER(asrtle_du)(CPULoongArchState *env, target_ulong rj, target_ulong rk)
+{
+    CPUSysState *sys = env_sys(env);
+
+    if (rj > rk) {
+        sys->CSR_BADV = rj;
+        do_raise_exception(env, EXCCODE_BCE, GETPC());
+    }
+}
+
+void HELPER(asrtgt_du)(CPULoongArchState *env, target_ulong rj, target_ulong rk)
+{
+    CPUSysState *sys = env_sys(env);
+
+    if (rj <= rk) {
+        sys->CSR_BADV = rj;
+        do_raise_exception(env, EXCCODE_BCE, GETPC());
+    }
+}
+
 target_ulong HELPER(crc32)(target_ulong val, target_ulong m, uint64_t sz)
 {
     uint8_t buf[8];