[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 16/19] target-mips: optimize ddiv/ddivu/div/divu
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH v2 16/19] target-mips: optimize ddiv/ddivu/div/divu with movcond |
Date: |
Tue, 30 Oct 2012 01:12:09 +0100 |
The result of a division by 0, or a division of INT_MIN by -1 in the
signed case, is unpredictable. Just replace 0 by 1 in that case so that
it doesn't trigger a floating point exception on the host.
Signed-off-by: Aurelien Jarno <address@hidden>
---
target-mips/translate.c | 85 +++++++++++++++++++++--------------------------
1 file changed, 37 insertions(+), 48 deletions(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 5d5c44e..bfc7cc7 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2155,60 +2155,48 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
const char *opn = "mul/div";
TCGv t0, t1;
- switch (opc) {
- case OPC_DIV:
- case OPC_DIVU:
-#if defined(TARGET_MIPS64)
- case OPC_DDIV:
- case OPC_DDIVU:
-#endif
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
- break;
- default:
- t0 = tcg_temp_new();
- t1 = tcg_temp_new();
- break;
- }
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
+
switch (opc) {
case OPC_DIV:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
tcg_gen_ext32s_tl(t0, t0);
tcg_gen_ext32s_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
-
- tcg_gen_mov_tl(cpu_LO[0], t0);
- tcg_gen_movi_tl(cpu_HI[0], 0);
- tcg_gen_br(l1);
- gen_set_label(l2);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
+ tcg_gen_and_tl(t2, t2, t3);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
+ tcg_gen_or_tl(t2, t2, t3);
+ tcg_gen_movi_tl(t3, 0);
+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
tcg_gen_div_tl(cpu_LO[0], t0, t1);
tcg_gen_rem_tl(cpu_HI[0], t0, t1);
tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
- gen_set_label(l1);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
}
opn = "div";
break;
case OPC_DIVU:
{
- int l1 = gen_new_label();
-
+ TCGv t2 = tcg_const_tl(0);
+ TCGv t3 = tcg_const_tl(1);
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
tcg_gen_divu_tl(cpu_LO[0], t0, t1);
tcg_gen_remu_tl(cpu_HI[0], t0, t1);
tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
- gen_set_label(l1);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
}
opn = "divu";
break;
@@ -2253,30 +2241,31 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
#if defined(TARGET_MIPS64)
case OPC_DDIV:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
- tcg_gen_mov_tl(cpu_LO[0], t0);
- tcg_gen_movi_tl(cpu_HI[0], 0);
- tcg_gen_br(l1);
- gen_set_label(l2);
- tcg_gen_div_i64(cpu_LO[0], t0, t1);
- tcg_gen_rem_i64(cpu_HI[0], t0, t1);
- gen_set_label(l1);
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
+ tcg_gen_and_tl(t2, t2, t3);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
+ tcg_gen_or_tl(t2, t2, t3);
+ tcg_gen_movi_tl(t3, 0);
+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
+ tcg_gen_div_tl(cpu_LO[0], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[0], t0, t1);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
}
opn = "ddiv";
break;
case OPC_DDIVU:
{
- int l1 = gen_new_label();
-
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
+ TCGv t2 = tcg_const_tl(0);
+ TCGv t3 = tcg_const_tl(1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
tcg_gen_divu_i64(cpu_LO[0], t0, t1);
tcg_gen_remu_i64(cpu_HI[0], t0, t1);
- gen_set_label(l1);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
}
opn = "ddivu";
break;
--
1.7.10.4
- [Qemu-devel] [PATCH v2 19/19] target-mips: don't flush extra TLB on permissions upgrade, (continued)
- [Qemu-devel] [PATCH v2 19/19] target-mips: don't flush extra TLB on permissions upgrade, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 07/19] target-mips: cleanup float to int conversion helpers, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 03/19] softfloat: implement fused multiply-add NaN propagation for MIPS, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 14/19] target-mips: don't use local temps for store conditional, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 13/19] target-mips: implement unaligned loads using TCG, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 15/19] target-mips: implement movn/movz using movcond, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 06/19] target-mips: fix FPU exceptions, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 18/19] target-mips: fix TLBR wrt SEGMask, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 16/19] target-mips: optimize ddiv/ddivu/div/divu with movcond,
Aurelien Jarno <=
- [Qemu-devel] [PATCH v2 17/19] target-mips: use deposit instead of hardcoded version, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 10/19] target-mips: cleanup load/store operations, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 12/19] target-mips: simplify load/store microMIPS helpers, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 04/19] target-mips: use the softfloat floatXX_muladd functions, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 05/19] target-mips: keep softfloat exception set to 0 between instructions, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 08/19] target-mips: use softfloat constants when possible, Aurelien Jarno, 2012/10/29
- [Qemu-devel] [PATCH v2 09/19] target-mips: restore CPU state after an FPU exception, Aurelien Jarno, 2012/10/29
- Re: [Qemu-devel] [PATCH v2 00/19] target-mips: misc fixes and optimizations, Richard Henderson, 2012/10/31