qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [6940] target-mips: optimize gen_muldiv()


From: Aurelien Jarno
Subject: [Qemu-devel] [6940] target-mips: optimize gen_muldiv()
Date: Sun, 29 Mar 2009 01:19:32 +0000

Revision: 6940
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6940
Author:   aurel32
Date:     2009-03-29 01:19:31 +0000 (Sun, 29 Mar 2009)
Log Message:
-----------
target-mips: optimize gen_muldiv()

Signed-off-by: Aurelien Jarno <address@hidden>

Modified Paths:
--------------
    trunk/target-mips/translate.c

Modified: trunk/target-mips/translate.c
===================================================================
--- trunk/target-mips/translate.c       2009-03-29 01:19:22 UTC (rev 6939)
+++ trunk/target-mips/translate.c       2009-03-29 01:19:31 UTC (rev 6940)
@@ -1803,39 +1803,46 @@
                         int rs, int rt)
 {
     const char *opn = "mul/div";
-    TCGv t0 = tcg_temp_local_new();
-    TCGv t1 = tcg_temp_local_new();
+    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;
+    }
+
     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();
 
+            tcg_gen_ext32s_tl(t0, t0);
+            tcg_gen_ext32s_tl(t1, t1);
             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
-            {
-                int l2 = gen_new_label();
-                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
-                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
-                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
+            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
+            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
 
-                tcg_gen_trunc_tl_i32(r_tmp1, t0);
-                tcg_gen_trunc_tl_i32(r_tmp2, t1);
-                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
-                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
-                tcg_gen_ext32s_tl(cpu_LO[0], t0);
-                tcg_gen_movi_tl(cpu_HI[0], 0);
-                tcg_gen_br(l1);
-                gen_set_label(l2);
-                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
-                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
-                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
-                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
-                tcg_temp_free_i32(r_tmp1);
-                tcg_temp_free_i32(r_tmp2);
-                tcg_temp_free_i32(r_tmp3);
-            }
+            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_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);
         }
         opn = "div";
@@ -1844,40 +1851,28 @@
         {
             int l1 = gen_new_label();
 
-            tcg_gen_ext32s_tl(t1, t1);
             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
-            {
-                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
-                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
-                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
-
-                tcg_gen_trunc_tl_i32(r_tmp1, t0);
-                tcg_gen_trunc_tl_i32(r_tmp2, t1);
-                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
-                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
-                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
-                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
-                tcg_temp_free_i32(r_tmp1);
-                tcg_temp_free_i32(r_tmp2);
-                tcg_temp_free_i32(r_tmp3);
-            }
+            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);
         }
         opn = "divu";
         break;
     case OPC_MULT:
         {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
-            tcg_gen_ext_tl_i64(r_tmp1, t0);
-            tcg_gen_ext_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_ext_tl_i64(t2, t0);
+            tcg_gen_ext_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_HI[0], t1);
         }
@@ -1885,19 +1880,19 @@
         break;
     case OPC_MULTU:
         {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
-            tcg_gen_extu_tl_i64(r_tmp1, t0);
-            tcg_gen_extu_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_extu_tl_i64(t2, t0);
+            tcg_gen_extu_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_HI[0], t1);
         }
@@ -1907,20 +1902,17 @@
     case OPC_DDIV:
         {
             int l1 = gen_new_label();
+            int l2 = gen_new_label();
 
             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
-            {
-                int l2 = gen_new_label();
-
-                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);
-            }
+            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);
         }
         opn = "ddiv";
@@ -1947,19 +1939,19 @@
 #endif
     case OPC_MADD:
         {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
-            tcg_gen_ext_tl_i64(r_tmp1, t0);
-            tcg_gen_ext_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
-            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_ext_tl_i64(t2, t0);
+            tcg_gen_ext_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_add_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_LO[1], t1);
         }
@@ -1967,21 +1959,21 @@
         break;
     case OPC_MADDU:
        {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
-            tcg_gen_extu_tl_i64(r_tmp1, t0);
-            tcg_gen_extu_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
-            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_extu_tl_i64(t2, t0);
+            tcg_gen_extu_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_add_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_HI[0], t1);
         }
@@ -1989,19 +1981,19 @@
         break;
     case OPC_MSUB:
         {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
-            tcg_gen_ext_tl_i64(r_tmp1, t0);
-            tcg_gen_ext_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
-            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_ext_tl_i64(t2, t0);
+            tcg_gen_ext_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_sub_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_HI[0], t1);
         }
@@ -2009,21 +2001,21 @@
         break;
     case OPC_MSUBU:
         {
-            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
-            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+            TCGv_i64 t2 = tcg_temp_new_i64();
+            TCGv_i64 t3 = tcg_temp_new_i64();
 
             tcg_gen_ext32u_tl(t0, t0);
             tcg_gen_ext32u_tl(t1, t1);
-            tcg_gen_extu_tl_i64(r_tmp1, t0);
-            tcg_gen_extu_tl_i64(r_tmp2, t1);
-            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
-            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
-            tcg_temp_free_i64(r_tmp2);
-            tcg_gen_trunc_i64_tl(t0, r_tmp1);
-            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
-            tcg_gen_trunc_i64_tl(t1, r_tmp1);
-            tcg_temp_free_i64(r_tmp1);
+            tcg_gen_extu_tl_i64(t2, t0);
+            tcg_gen_extu_tl_i64(t3, t1);
+            tcg_gen_mul_i64(t2, t2, t3);
+            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+            tcg_gen_sub_i64(t2, t2, t3);
+            tcg_temp_free_i64(t3);
+            tcg_gen_trunc_i64_tl(t0, t2);
+            tcg_gen_shri_i64(t2, t2, 32);
+            tcg_gen_trunc_i64_tl(t1, t2);
+            tcg_temp_free_i64(t2);
             tcg_gen_ext32s_tl(cpu_LO[0], t0);
             tcg_gen_ext32s_tl(cpu_HI[0], t1);
         }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]