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];