qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH v2 05/11] target-mips: convert bit shuffle ops to TC


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH v2 05/11] target-mips: convert bit shuffle ops to TCG
Date: Sat, 8 Nov 2008 20:19:09 +0100
User-agent: Mutt/1.5.18 (2008-05-17)

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

This code also move all bit shuffle generation code to a separate
function in order to have a cleaner exception code path, that is it
doesn't store back the TCG register to the target register after the
exception, as the TCG register doesn't exist anymore.

Signed-off-by: Aurelien Jarno <address@hidden>
---
 target-mips/helper.h    |    7 ---
 target-mips/op_helper.c |   19 --------
 target-mips/translate.c |  106 +++++++++++++++++++++++++----------------------
 3 files changed, 56 insertions(+), 76 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 5926921..f67c82a 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -269,10 +269,3 @@ DEF_HELPER(target_ulong, do_rdhwr_cc, (void))
 DEF_HELPER(target_ulong, do_rdhwr_ccres, (void))
 DEF_HELPER(void, do_pmon, (int function))
 DEF_HELPER(void, do_wait, (void))
-
-/* Bit shuffle operations. */
-DEF_HELPER(target_ulong, do_wsbh, (target_ulong t1))
-#ifdef TARGET_MIPS64
-DEF_HELPER(target_ulong, do_dsbh, (target_ulong t1))
-DEF_HELPER(target_ulong, do_dshd, (target_ulong t1))
-#endif
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index b642593..3fe62fb 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1781,25 +1781,6 @@ target_ulong do_rdhwr_ccres(void)
     return 0;
 }
 
-/* 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_dsbh(target_ulong t1)
-{
-    return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 
0x00FF00FF00FF00FFULL);
-}
-
-target_ulong do_dshd(target_ulong t1)
-{
-    t1 = ((t1 << 16) & ~0x0000FFFF0000FFFFULL) | ((t1 >> 16) & 
0x0000FFFF0000FFFFULL);
-    return (t1 << 32) | (t1 >> 32);
-}
-#endif
-
 void do_pmon (int function)
 {
     function /= 2;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index d74d2cb..e89d59e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2771,6 +2771,60 @@ fail:
     tcg_temp_free(t1);
 }
 
+static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
+{
+    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+    TCGv t1 = tcg_temp_new(TCG_TYPE_TL);
+
+    gen_load_gpr(t1, rt);
+    switch (op2) {
+    case OPC_WSBH:
+        tcg_gen_shri_tl(t0, t1, 8);
+        tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
+        tcg_gen_shli_tl(t1, t1, 8);
+        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
+        tcg_gen_or_tl(t0, t0, t1);
+        tcg_gen_ext32s_tl(t0, t0);
+        break;
+    case OPC_SEB:
+        tcg_gen_ext8s_tl(t0, t1);
+        break;
+    case OPC_SEH:
+        tcg_gen_ext16s_tl(t0, t1);
+        break;
+#if defined(TARGET_MIPS64)
+    case OPC_DSBH:
+        gen_load_gpr(t1, rt);
+        tcg_gen_shri_tl(t0, t1, 8);
+        tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
+        tcg_gen_shli_tl(t1, t1, 8);
+        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
+        tcg_gen_or_tl(t0, t0, t1);
+        break;
+    case OPC_DSHD:
+        gen_load_gpr(t1, rt);
+        tcg_gen_shri_tl(t0, t1, 16);
+        tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
+        tcg_gen_shli_tl(t1, t1, 16);
+        tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
+        tcg_gen_or_tl(t1, t0, t1);
+        tcg_gen_shri_tl(t0, t1, 32);
+        tcg_gen_shli_tl(t1, t1, 32);
+        tcg_gen_or_tl(t0, t0, t1);
+        break;
+#endif
+    default:
+        MIPS_INVAL("bsfhl");
+        generate_exception(ctx, EXCP_RI);
+        tcg_temp_free(t0);
+        tcg_temp_free(t1);
+        return;
+    }
+    gen_store_gpr(t0, rd);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
 #ifndef CONFIG_USER_ONLY
 /* CP0 (MMU and control) */
 static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
@@ -7953,34 +8007,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
         case OPC_BSHFL:
             check_insn(env, ctx, ISA_MIPS32R2);
             op2 = MASK_BSHFL(ctx->opcode);
-            {
-                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
-                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
-
-                switch (op2) {
-                case OPC_WSBH:
-                    gen_load_gpr(t1, rt);
-                    tcg_gen_helper_1_1(do_wsbh, t0, t1);
-                    gen_store_gpr(t0, rd);
-                    break;
-                case OPC_SEB:
-                    gen_load_gpr(t1, rt);
-                    tcg_gen_ext8s_tl(t0, t1);
-                    gen_store_gpr(t0, rd);
-                    break;
-                case OPC_SEH:
-                    gen_load_gpr(t1, rt);
-                    tcg_gen_ext16s_tl(t0, t1);
-                    gen_store_gpr(t0, rd);
-                    break;
-                default:            /* Invalid */
-                    MIPS_INVAL("bshfl");
-                    generate_exception(ctx, EXCP_RI);
-                    break;
-                }
-                tcg_temp_free(t0);
-                tcg_temp_free(t1);
-            }
+            gen_bshfl(ctx, op2, rt, rd);
             break;
         case OPC_RDHWR:
             check_insn(env, ctx, ISA_MIPS32R2);
@@ -8056,28 +8083,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             check_insn(env, ctx, ISA_MIPS64R2);
             check_mips_64(ctx);
             op2 = MASK_DBSHFL(ctx->opcode);
-            {
-                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
-                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
-
-                switch (op2) {
-                case OPC_DSBH:
-                    gen_load_gpr(t1, rt);
-                    tcg_gen_helper_1_1(do_dsbh, t0, t1);
-                    break;
-                case OPC_DSHD:
-                    gen_load_gpr(t1, rt);
-                    tcg_gen_helper_1_1(do_dshd, t0, t1);
-                    break;
-                default:            /* Invalid */
-                    MIPS_INVAL("dbshfl");
-                    generate_exception(ctx, EXCP_RI);
-                    break;
-                }
-                gen_store_gpr(t0, rd);
-                tcg_temp_free(t0);
-                tcg_temp_free(t1);
-            }
+            gen_bshfl(ctx, op2, rt, rd);
             break;
 #endif
         default:            /* Invalid */
-- 
1.5.6.5


-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

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