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 <[email protected]> --- target/loongarch/tcg/helper.h | 2 ++ .../tcg/insn_trans/trans_fmemory.c.inc | 8 ++++---- .../tcg/insn_trans/trans_memory.c.inc | 8 ++++---- target/loongarch/tcg/op_helper.c | 20 +++++++++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) 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 b863ba1dc2..b050436a77 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_x(ctx, src1, src2); 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_x(ctx, src1, src2); 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_x(ctx, src1, src2); 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_x(ctx, src1, src2); 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]; -- 2.54.0
