qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5678] target-mips: convert bitfield ops to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5678] target-mips: convert bitfield ops to TCG
Date: Tue, 11 Nov 2008 11:46:59 +0000

Revision: 5678
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5678
Author:   aurel32
Date:     2008-11-11 11:46:58 +0000 (Tue, 11 Nov 2008)

Log Message:
-----------
target-mips: convert bitfield ops to TCG

Bitfield operations can be written with very few TCG instructions
(between 2 and 5), so it is worth converting them to TCG.

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

Modified Paths:
--------------
    trunk/target-mips/helper.h
    trunk/target-mips/op_helper.c
    trunk/target-mips/translate.c

Modified: trunk/target-mips/helper.h
===================================================================
--- trunk/target-mips/helper.h  2008-11-11 11:39:33 UTC (rev 5677)
+++ trunk/target-mips/helper.h  2008-11-11 11:46:58 UTC (rev 5678)
@@ -270,13 +270,9 @@
 DEF_HELPER(void, do_pmon, (int function))
 DEF_HELPER(void, do_wait, (void))
 
-/* Bitfield operations. */
-DEF_HELPER(target_ulong, do_ext, (target_ulong t1, uint32_t pos, uint32_t 
size))
-DEF_HELPER(target_ulong, do_ins, (target_ulong t0, target_ulong t1, uint32_t 
pos, uint32_t size))
+/* Bit shuffle operations. */
 DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1))
 #ifdef TARGET_MIPS64
-DEF_HELPER(target_ulong, do_dext, (target_ulong t1, uint32_t pos, uint32_t 
size))
-DEF_HELPER(target_ulong, do_dins, (target_ulong t0, target_ulong t1, uint32_t 
pos, uint32_t size))
 DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1))
 DEF_HELPER(target_ulong, do_dshd, (target_ulong t1))
 #endif

Modified: trunk/target-mips/op_helper.c
===================================================================
--- trunk/target-mips/op_helper.c       2008-11-11 11:39:33 UTC (rev 5677)
+++ trunk/target-mips/op_helper.c       2008-11-11 11:46:58 UTC (rev 5678)
@@ -1781,37 +1781,13 @@
     return 0;
 }
 
-/* Bitfield operations. */
-target_ulong do_ext(target_ulong t1, uint32_t pos, uint32_t size)
-{
-    return (int32_t)((t1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
-}
-
-target_ulong do_ins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t 
size)
-{
-    target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
-
-    return (int32_t)((t0 & ~mask) | ((t1 << pos) & mask));
-}
-
+/* Bit shuffle operations. */
 target_ulong do_wsbh(target_ulong t1)
 {
     return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF));
 }
 
 #if defined(TARGET_MIPS64)
-target_ulong do_dext(target_ulong t1, uint32_t pos, uint32_t size)
-{
-    return (t1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
-}
-
-target_ulong do_dins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t 
size)
-{
-    target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
-
-    return (t0 & ~mask) | ((t1 << pos) & mask);
-}
-
 target_ulong do_dsbh(target_ulong t1)
 {
     return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 
0x00FF00FF00FF00FFULL);

Modified: trunk/target-mips/translate.c
===================================================================
--- trunk/target-mips/translate.c       2008-11-11 11:39:33 UTC (rev 5677)
+++ trunk/target-mips/translate.c       2008-11-11 11:46:58 UTC (rev 5678)
@@ -2682,57 +2682,80 @@
 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
                         int rs, int lsb, int msb)
 {
-    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
-    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
+    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+    TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
+    target_ulong mask;
 
     gen_load_gpr(t1, rs);
     switch (opc) {
     case OPC_EXT:
         if (lsb + msb > 31)
             goto fail;
-        tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
+        tcg_gen_shri_tl(t0, t1, lsb);
+        if (msb != 31) {
+            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
+        } else {
+            tcg_gen_ext32s_tl(t0, t0);
+        }
         break;
 #if defined(TARGET_MIPS64)
     case OPC_DEXTM:
-        if (lsb + msb > 63)
-            goto fail;
-        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
+        tcg_gen_shri_tl(t0, t1, lsb);
+        if (msb != 31) {
+            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
+        }
         break;
     case OPC_DEXTU:
-        if (lsb + msb > 63)
-            goto fail;
-        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
+        tcg_gen_shri_tl(t0, t1, lsb + 32);
+        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
         break;
     case OPC_DEXT:
-        if (lsb + msb > 63)
-            goto fail;
-        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
+        tcg_gen_shri_tl(t0, t1, lsb);
+        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
         break;
 #endif
     case OPC_INS:
         if (lsb > msb)
             goto fail;
+        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << 
lsb;
         gen_load_gpr(t0, rt);
-        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
+        tcg_gen_andi_tl(t0, t0, ~mask);
+        tcg_gen_shli_tl(t1, t1, lsb);
+        tcg_gen_andi_tl(t1, t1, mask);
+        tcg_gen_or_tl(t0, t0, t1);
+        tcg_gen_ext32s_tl(t0, t0);
         break;
 #if defined(TARGET_MIPS64)
     case OPC_DINSM:
         if (lsb > msb)
             goto fail;
+        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 
1) : ~0ULL) << lsb;
         gen_load_gpr(t0, rt);
-        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
+        tcg_gen_andi_tl(t0, t0, ~mask);
+        tcg_gen_shli_tl(t1, t1, lsb);
+        tcg_gen_andi_tl(t1, t1, mask);
+        tcg_gen_or_tl(t0, t0, t1);
         break;
     case OPC_DINSU:
         if (lsb > msb)
             goto fail;
+        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
         gen_load_gpr(t0, rt);
-        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
+        tcg_gen_andi_tl(t0, t0, ~mask);
+        tcg_gen_shli_tl(t1, t1, lsb + 32);
+        tcg_gen_andi_tl(t1, t1, mask);
+        tcg_gen_or_tl(t0, t0, t1);
         break;
     case OPC_DINS:
         if (lsb > msb)
             goto fail;
         gen_load_gpr(t0, rt);
-        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
+        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
+        gen_load_gpr(t0, rt);
+        tcg_gen_andi_tl(t0, t0, ~mask);
+        tcg_gen_shli_tl(t1, t1, lsb);
+        tcg_gen_andi_tl(t1, t1, mask);
+        tcg_gen_or_tl(t0, t0, t1);
         break;
 #endif
     default:






reply via email to

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