qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5236] target-alpha: convert some arith3 instructions to TC


From: Aurelien Jarno
Subject: [Qemu-devel] [5236] target-alpha: convert some arith3 instructions to TCG
Date: Tue, 16 Sep 2008 22:44:10 +0000

Revision: 5236
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5236
Author:   aurel32
Date:     2008-09-16 22:44:10 +0000 (Tue, 16 Sep 2008)

Log Message:
-----------
target-alpha: convert some arith3 instructions to TCG

Replace gen_arith3 generic macro and dyngen ops by instruction specific
optimized TCG code.

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

Modified Paths:
--------------
    trunk/target-alpha/op.c
    trunk/target-alpha/translate.c

Modified: trunk/target-alpha/op.c
===================================================================
--- trunk/target-alpha/op.c     2008-09-16 22:44:02 UTC (rev 5235)
+++ trunk/target-alpha/op.c     2008-09-16 22:44:10 UTC (rev 5236)
@@ -198,72 +198,36 @@
 }
 
 /* Arithmetic */
-void OPPROTO op_addq (void)
-{
-    T0 += T1;
-    RETURN();
-}
-
 void OPPROTO op_addqv (void)
 {
     helper_addqv();
     RETURN();
 }
 
-void OPPROTO op_addl (void)
-{
-    T0 = (int64_t)((int32_t)(T0 + T1));
-    RETURN();
-}
-
 void OPPROTO op_addlv (void)
 {
     helper_addlv();
     RETURN();
 }
 
-void OPPROTO op_subq (void)
-{
-    T0 -= T1;
-    RETURN();
-}
-
 void OPPROTO op_subqv (void)
 {
     helper_subqv();
     RETURN();
 }
 
-void OPPROTO op_subl (void)
-{
-    T0 = (int64_t)((int32_t)(T0 - T1));
-    RETURN();
-}
-
 void OPPROTO op_sublv (void)
 {
     helper_sublv();
     RETURN();
 }
 
-void OPPROTO op_mull (void)
-{
-    T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
-    RETURN();
-}
-
 void OPPROTO op_mullv (void)
 {
     helper_mullv();
     RETURN();
 }
 
-void OPPROTO op_mulq (void)
-{
-    T0 = (int64_t)T0 * (int64_t)T1;
-    RETURN();
-}
-
 void OPPROTO op_mulqv (void)
 {
     helper_mulqv();
@@ -280,60 +244,6 @@
 }
 
 /* Logical */
-void OPPROTO op_and (void)
-{
-    T0 &= T1;
-    RETURN();
-}
-
-void OPPROTO op_bic (void)
-{
-    T0 &= ~T1;
-    RETURN();
-}
-
-void OPPROTO op_bis (void)
-{
-    T0 |= T1;
-    RETURN();
-}
-
-void OPPROTO op_eqv (void)
-{
-    T0 ^= ~T1;
-    RETURN();
-}
-
-void OPPROTO op_ornot (void)
-{
-    T0 |= ~T1;
-    RETURN();
-}
-
-void OPPROTO op_xor (void)
-{
-    T0 ^= T1;
-    RETURN();
-}
-
-void OPPROTO op_sll (void)
-{
-    T0 <<= T1;
-    RETURN();
-}
-
-void OPPROTO op_srl (void)
-{
-    T0 >>= T1;
-    RETURN();
-}
-
-void OPPROTO op_sra (void)
-{
-    T0 = (int64_t)T0 >> T1;
-    RETURN();
-}
-
 void OPPROTO op_mskbl (void)
 {
     helper_mskbl();

Modified: trunk/target-alpha/translate.c
===================================================================
--- trunk/target-alpha/translate.c      2008-09-16 22:44:02 UTC (rev 5235)
+++ trunk/target-alpha/translate.c      2008-09-16 22:44:10 UTC (rev 5236)
@@ -440,54 +440,6 @@
     gen_store_fir(ctx, rc, 0);
 }
 
-static always_inline void gen_s4addl (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
-    gen_op_addl();
-}
-
-static always_inline void gen_s4subl (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
-    gen_op_subl();
-}
-
-static always_inline void gen_s8addl (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
-    gen_op_addl();
-}
-
-static always_inline void gen_s8subl (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
-    gen_op_subl();
-}
-
-static always_inline void gen_s4addq (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
-    tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
-}
-
-static always_inline void gen_s4subq (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
-    tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
-}
-
-static always_inline void gen_s8addq (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
-    tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
-}
-
-static always_inline void gen_s8subq (void)
-{
-    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 3);
-    tcg_gen_sub_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
-}
-
 static always_inline int translate_one (DisasContext *ctx, uint32_t insn)
 {
     uint32_t palcode;
@@ -616,19 +568,103 @@
         switch (fn7) {
         case 0x00:
             /* ADDL */
-            gen_arith3(ctx, &gen_op_addl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit) {
+                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else if (rb != 31) {
+                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], (int32_t)lit);
+                    else if (rb != 31)
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x02:
             /* S4ADDL */
-            gen_arith3(ctx, &gen_s4addl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
+                        if (islit)
+                            tcg_gen_addi_i64(tmp, tmp, lit);
+                        else
+                            tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
+                        tcg_temp_free(tmp);
+                    } else {
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    }
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x09:
             /* SUBL */
-            gen_arith3(ctx, &gen_op_subl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit) {
+                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else if (rb != 31) {
+                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31) {
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x0B:
             /* S4SUBL */
-            gen_arith3(ctx, &gen_s4subl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
+                        if (islit)
+                            tcg_gen_subi_i64(tmp, tmp, lit);
+                        else
+                            tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
+                        tcg_temp_free(tmp);
+                    } else {
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    }
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31) {
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x0F:
             /* CMPBGE */
@@ -636,11 +672,58 @@
             break;
         case 0x12:
             /* S8ADDL */
-            gen_arith3(ctx, &gen_s8addl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
+                        if (islit)
+                            tcg_gen_addi_i64(tmp, tmp, lit);
+                        else
+                            tcg_gen_add_i64(tmp, tmp, cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
+                        tcg_temp_free(tmp);
+                    } else {
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    }
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x1B:
             /* S8SUBL */
-            gen_arith3(ctx, &gen_s8subl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
+                        if (islit)
+                            tcg_gen_subi_i64(tmp, tmp, lit);
+                        else
+                            tcg_gen_sub_i64(tmp, tmp, cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], tmp);
+                        tcg_temp_free(tmp);
+                    } else {
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    }
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31) {
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                        tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    } else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x1D:
             /* CMPULT */
@@ -648,19 +731,91 @@
             break;
         case 0x20:
             /* ADDQ */
-            gen_arith3(ctx, &gen_op_addq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_addi_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                    else if (rb != 31)
+                        tcg_gen_add_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                    else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x22:
             /* S4ADDQ */
-            gen_arith3(ctx, &gen_s4addq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
+                        if (islit)
+                            tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
+                        else
+                            tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x29:
             /* SUBQ */
-            gen_arith3(ctx, &gen_op_subq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_subi_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                    else if (rb != 31)
+                        tcg_gen_sub_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                    else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31)
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x2B:
             /* S4SUBQ */
-            gen_arith3(ctx, &gen_s4subq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 2);
+                        if (islit)
+                            tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
+                        else
+                            tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 2);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31)
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x2D:
             /* CMPEQ */
@@ -668,11 +823,51 @@
             break;
         case 0x32:
             /* S8ADDQ */
-            gen_arith3(ctx, &gen_s8addq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
+                        if (islit)
+                            tcg_gen_addi_i64(cpu_ir[rc], tmp, lit);
+                        else
+                            tcg_gen_add_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x3B:
             /* S8SUBQ */
-            gen_arith3(ctx, &gen_s8subq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit || rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_shli_i64(tmp, cpu_ir[ra], 3);
+                        if (islit)
+                            tcg_gen_subi_i64(cpu_ir[rc], tmp, lit);
+                        else
+                            tcg_gen_sub_i64(cpu_ir[rc], tmp, cpu_ir[rb]);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], 3);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], -lit);
+                    else if (rb != 31)
+                        tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x3D:
             /* CMPULE */
@@ -710,11 +905,31 @@
         switch (fn7) {
         case 0x00:
             /* AND */
-            gen_arith3(ctx, &gen_op_and, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra == 31 || (rb == 31 && !islit))
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+                else if (islit)
+                    tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                else
+                    tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+            }
             break;
         case 0x08:
             /* BIC */
-            gen_arith3(ctx, &gen_op_bic, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
+                    else if (rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
+                        tcg_gen_and_i64(cpu_ir[rc], cpu_ir[ra], tmp);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+            }
             break;
         case 0x14:
             /* CMOVLBS */
@@ -726,21 +941,22 @@
             break;
         case 0x20:
             /* BIS */
-            if (ra == rb || ra == 31 || rb == 31) {
-                if (ra == 31 && rc == 31) {
-                    /* NOP */
-                    gen_op_nop();
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                    else if (rb != 31)
+                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                    else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
                 } else {
-                    /* MOV */
-                    if (rc != 31) {
-                        if (rb != 31)
-                            tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
-                        else
-                            tcg_gen_movi_i64(cpu_ir[rc], 0);
-                    }
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
                 }
-            } else {
-                gen_arith3(ctx, &gen_op_bis, ra, rb, rc, islit, lit);
             }
             break;
         case 0x24:
@@ -753,11 +969,45 @@
             break;
         case 0x28:
             /* ORNOT */
-            gen_arith3(ctx, &gen_op_ornot, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (rb == 31 && !islit)
+                    tcg_gen_movi_i64(cpu_ir[rc], ~0);
+                else if (ra != 31) {
+                    if (islit)
+                        tcg_gen_ori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
+                    else {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
+                        tcg_gen_or_i64(cpu_ir[rc], cpu_ir[ra], tmp);
+                        tcg_temp_free(tmp);
+                    }
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
+                    else
+                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
+                }
+            }
             break;
         case 0x40:
             /* XOR */
-            gen_arith3(ctx, &gen_op_xor, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                    else if (rb != 31)
+                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                    else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], lit);
+                    else if (rb != 31)
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], 0);
+                }
+            }
             break;
         case 0x44:
             /* CMOVLT */
@@ -769,7 +1019,26 @@
             break;
         case 0x48:
             /* EQV */
-            gen_arith3(ctx, &gen_op_eqv, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_xori_i64(cpu_ir[rc], cpu_ir[ra], ~lit);
+                    else if (rb != 31) {
+                        TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_not_i64(tmp, cpu_ir[rb]);
+                        tcg_gen_xor_i64(cpu_ir[rc], cpu_ir[ra], tmp);
+                        tcg_temp_free(tmp);
+                    } else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else {
+                    if (islit)
+                        tcg_gen_movi_i64(cpu_ir[rc], ~lit);
+                    else if (rb != 31)
+                        tcg_gen_not_i64(cpu_ir[rc], cpu_ir[rb]);
+                    else
+                        tcg_gen_movi_i64(cpu_ir[rc], ~0);
+                }
+            }
             break;
         case 0x61:
             /* AMASK */
@@ -852,7 +1121,20 @@
             break;
         case 0x34:
             /* SRL */
-            gen_arith3(ctx, &gen_op_srl, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_shri_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
+                    else if (rb != 31) {
+                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
+                        tcg_gen_shr_i64(cpu_ir[rc], cpu_ir[ra], shift);
+                        tcg_temp_free(shift);
+                    } else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+            }
             break;
         case 0x36:
             /* EXTQL */
@@ -860,7 +1142,20 @@
             break;
         case 0x39:
             /* SLL */
-            gen_arith3(ctx, &gen_op_sll, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_shli_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
+                    else if (rb != 31) {
+                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
+                        tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], shift);
+                        tcg_temp_free(shift);
+                    } else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+            }
             break;
         case 0x3B:
             /* INSQL */
@@ -868,7 +1163,20 @@
             break;
         case 0x3C:
             /* SRA */
-            gen_arith3(ctx, &gen_op_sra, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra != 31) {
+                    if (islit)
+                        tcg_gen_sari_i64(cpu_ir[rc], cpu_ir[ra], lit & 0x3f);
+                    else if (rb != 31) {
+                        TCGv shift = tcg_temp_new(TCG_TYPE_I64);
+                        tcg_gen_andi_i64(shift, cpu_ir[rb], 0x3f);
+                        tcg_gen_sar_i64(cpu_ir[rc], cpu_ir[ra], shift);
+                        tcg_temp_free(shift);
+                    } else
+                        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]);
+                } else
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+            }
             break;
         case 0x52:
             /* MSKWH */
@@ -914,11 +1222,28 @@
         switch (fn7) {
         case 0x00:
             /* MULL */
-            gen_arith3(ctx, &gen_op_mull, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra == 31 || (rb == 31 && !islit))
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+                else {
+                    if (islit)
+                        tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                    else
+                        tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+                    tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                }
+            }
             break;
         case 0x20:
             /* MULQ */
-            gen_arith3(ctx, &gen_op_mulq, ra, rb, rc, islit, lit);
+            if (likely(rc != 31)) {
+                if (ra == 31 || (rb == 31 && !islit))
+                    tcg_gen_movi_i64(cpu_ir[rc], 0);
+                else if (islit)
+                    tcg_gen_muli_i64(cpu_ir[rc], cpu_ir[ra], lit);
+                else
+                    tcg_gen_mul_i64(cpu_ir[rc], cpu_ir[ra], cpu_ir[rb]);
+            }
             break;
         case 0x30:
             /* UMULH */






reply via email to

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