So we set the divisor to 1 and the dividend to 0.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/insn_trans/trans_arith.c.inc | 34 +++++++++++++++----
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/target/loongarch/insn_trans/trans_arith.c.inc
b/target/loongarch/insn_trans/trans_arith.c.inc
index 8e45eadbc8..c97afb16f9 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -147,12 +147,28 @@ static void prep_divisor_du(TCGv ret, TCGv src2)
tcg_gen_movcond_tl(TCG_COND_EQ, ret, src2, zero, one, src2);
}
+static void prep_div(TCGv divisor, TCGv dividend, TCGv src1, TCGv src2)
+{
+ TCGv zero = tcg_constant_tl(0);
+ TCGv one = tcg_constant_tl(1);
+
+ /*
+ * If x / 0, set the diviend to 0 set the divisor to 1
+ * this is the same with LoongArch host.
+ */
+ tcg_gen_movcond_tl(TCG_COND_EQ, dividend, src2, zero, zero, src1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, divisor, src2, zero, one, src2);
+}
+
static void gen_div_d(TCGv dest, TCGv src1, TCGv src2)
{
TCGv t0 = tcg_temp_new();
- prep_divisor_d(t0, src1, src2);
- tcg_gen_div_tl(dest, src1, t0);
+ TCGv t1 = tcg_temp_new();
+
+ prep_div(t0, t1, src1, src2);
+ tcg_gen_div_tl(dest, t1, t0);
tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)
@@ -166,9 +182,11 @@ static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2)
static void gen_div_du(TCGv dest, TCGv src1, TCGv src2)
{
TCGv t0 = tcg_temp_new();
- prep_divisor_du(t0, src2);
- tcg_gen_divu_tl(dest, src1, t0);
+ TCGv t1 = tcg_temp_new();
+ prep_div(t0, t1, src1, src2);
+ tcg_gen_divu_tl(dest, t1, t0);
tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)
@@ -182,10 +200,12 @@ static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2)
static void gen_div_w(TCGv dest, TCGv src1, TCGv src2)
{
TCGv t0 = tcg_temp_new();
- /* We need not check for integer overflow for div_w. */
- prep_divisor_du(t0, src2);
- tcg_gen_div_tl(dest, src1, t0);
+ TCGv t1 = tcg_temp_new();
+
+ prep_div(t0, t1, src1, src2);
+ tcg_gen_div_tl(dest, t1, t0);
tcg_temp_free(t0);
+ tcg_temp_free(t1);
}
static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2)