qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5506] target-ppc: convert logical instructions to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5506] target-ppc: convert logical instructions to TCG
Date: Tue, 21 Oct 2008 11:31:28 +0000

Revision: 5506
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5506
Author:   aurel32
Date:     2008-10-21 11:31:27 +0000 (Tue, 21 Oct 2008)

Log Message:
-----------
target-ppc: convert logical instructions to TCG

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

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

Modified: trunk/target-ppc/helper.h
===================================================================
--- trunk/target-ppc/helper.h   2008-10-21 11:31:14 UTC (rev 5505)
+++ trunk/target-ppc/helper.h   2008-10-21 11:31:27 UTC (rev 5506)
@@ -7,3 +7,13 @@
 
 DEF_HELPER(uint32_t, helper_load_cr, (void))
 DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
+
+DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t))
+DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val))
+DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong))
+#if defined(TARGET_PPC64)
+DEF_HELPER(target_ulong, helper_cntlzd, (target_ulong t))
+DEF_HELPER(target_ulong, helper_popcntb_64, (target_ulong val))
+DEF_HELPER(target_ulong, helper_srad, (target_ulong, target_ulong))
+#endif
+

Modified: trunk/target-ppc/op.c
===================================================================
--- trunk/target-ppc/op.c       2008-10-21 11:31:14 UTC (rev 5505)
+++ trunk/target-ppc/op.c       2008-10-21 11:31:27 UTC (rev 5506)
@@ -37,15 +37,6 @@
     do_raise_exception(EXCP_DEBUG);
 }
 
-/* Load/store special registers */
-#if defined(TARGET_PPC64)
-void OPPROTO op_store_pri (void)
-{
-    do_store_pri(PARAM1);
-    RETURN();
-}
-#endif
-
 #if !defined(CONFIG_USER_ONLY)
 /* Segment registers load and store */
 void OPPROTO op_load_sr (void)
@@ -921,101 +912,7 @@
 }
 #endif
 
-void OPPROTO op_popcntb (void)
-{
-    do_popcntb();
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_popcntb_64 (void)
-{
-    do_popcntb_64();
-    RETURN();
-}
-#endif
-
 /***                            Integer logical                            ***/
-/* and */
-void OPPROTO op_and (void)
-{
-    T0 &= T1;
-    RETURN();
-}
-
-/* andc */
-void OPPROTO op_andc (void)
-{
-    T0 &= ~T1;
-    RETURN();
-}
-
-/* count leading zero */
-void OPPROTO op_cntlzw (void)
-{
-    do_cntlzw();
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_cntlzd (void)
-{
-    do_cntlzd();
-    RETURN();
-}
-#endif
-
-/* eqv */
-void OPPROTO op_eqv (void)
-{
-    T0 = ~(T0 ^ T1);
-    RETURN();
-}
-
-/* extend sign byte */
-void OPPROTO op_extsb (void)
-{
-#if defined (TARGET_PPC64)
-    T0 = (int64_t)((int8_t)T0);
-#else
-    T0 = (int32_t)((int8_t)T0);
-#endif
-    RETURN();
-}
-
-/* extend sign half word */
-void OPPROTO op_extsh (void)
-{
-#if defined (TARGET_PPC64)
-    T0 = (int64_t)((int16_t)T0);
-#else
-    T0 = (int32_t)((int16_t)T0);
-#endif
-    RETURN();
-}
-
-#if defined (TARGET_PPC64)
-void OPPROTO op_extsw (void)
-{
-    T0 = (int64_t)((int32_t)T0);
-    RETURN();
-}
-#endif
-
-/* nand */
-void OPPROTO op_nand (void)
-{
-    T0 = ~(T0 & T1);
-    RETURN();
-}
-
-/* nor */
-void OPPROTO op_nor (void)
-{
-    T0 = ~(T0 | T1);
-    RETURN();
-}
-
 /* or */
 void OPPROTO op_or (void)
 {
@@ -1023,34 +920,6 @@
     RETURN();
 }
 
-/* orc */
-void OPPROTO op_orc (void)
-{
-    T0 |= ~T1;
-    RETURN();
-}
-
-/* ori */
-void OPPROTO op_ori (void)
-{
-    T0 |= (uint32_t)PARAM1;
-    RETURN();
-}
-
-/* xor */
-void OPPROTO op_xor (void)
-{
-    T0 ^= T1;
-    RETURN();
-}
-
-/* xori */
-void OPPROTO op_xori (void)
-{
-    T0 ^= (uint32_t)PARAM1;
-    RETURN();
-}
-
 /***                             Integer rotate                            ***/
 void OPPROTO op_rotl32_T0_T1 (void)
 {
@@ -1079,122 +948,13 @@
 #endif
 
 /***                             Integer shift                             ***/
-/* shift left word */
-void OPPROTO op_slw (void)
-{
-    if (T1 & 0x20) {
-        T0 = 0;
-    } else {
-        T0 = (uint32_t)(T0 << T1);
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_sld (void)
-{
-    if (T1 & 0x40) {
-        T0 = 0;
-    } else {
-        T0 = T0 << T1;
-    }
-    RETURN();
-}
-#endif
-
-/* shift right algebraic word */
-void OPPROTO op_sraw (void)
-{
-    do_sraw();
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_srad (void)
-{
-    do_srad();
-    RETURN();
-}
-#endif
-
-/* shift right algebraic word immediate */
-void OPPROTO op_srawi (void)
-{
-    uint32_t mask = (uint32_t)PARAM2;
-
-    T0 = (int32_t)T0 >> PARAM1;
-    if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
-        env->xer |= (1 << XER_CA);
-    } else {
-        env->xer &= ~(1 << XER_CA);
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_sradi (void)
-{
-    uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
-
-    T0 = (int64_t)T0 >> PARAM1;
-    if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
-        env->xer |= (1 << XER_CA);
-    } else {
-        env->xer &= ~(1 << XER_CA);
-    }
-    RETURN();
-}
-#endif
-
 /* shift right word */
-void OPPROTO op_srw (void)
-{
-    if (T1 & 0x20) {
-        T0 = 0;
-    } else {
-        T0 = (uint32_t)T0 >> T1;
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_srd (void)
-{
-    if (T1 & 0x40) {
-        T0 = 0;
-    } else {
-        T0 = (uint64_t)T0 >> T1;
-    }
-    RETURN();
-}
-#endif
-
-void OPPROTO op_sl_T0_T1 (void)
-{
-    T0 = T0 << T1;
-    RETURN();
-}
-
 void OPPROTO op_sli_T0 (void)
 {
     T0 = T0 << PARAM1;
     RETURN();
 }
 
-void OPPROTO op_srl_T0_T1 (void)
-{
-    T0 = (uint32_t)T0 >> T1;
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_srl_T0_T1_64 (void)
-{
-    T0 = (uint32_t)T0 >> T1;
-    RETURN();
-}
-#endif
-
 void OPPROTO op_srli_T0 (void)
 {
     T0 = (uint32_t)T0 >> PARAM1;
@@ -1215,14 +975,6 @@
     RETURN();
 }
 
-#if defined(TARGET_PPC64)
-void OPPROTO op_srli_T1_64 (void)
-{
-    T1 = (uint64_t)T1 >> PARAM1;
-    RETURN();
-}
-#endif
-
 /***                       Floating-Point arithmetic                       ***/
 /* fadd - fadd. */
 void OPPROTO op_fadd (void)

Modified: trunk/target-ppc/op_helper.c
===================================================================
--- trunk/target-ppc/op_helper.c        2008-10-21 11:31:14 UTC (rev 5505)
+++ trunk/target-ppc/op_helper.c        2008-10-21 11:31:27 UTC (rev 5506)
@@ -368,96 +368,98 @@
 }
 #endif
 
-void do_cntlzw (void)
+target_ulong helper_cntlzw (target_ulong t)
 {
-    T0 = clz32(T0);
+    return clz32(t);
 }
 
 #if defined(TARGET_PPC64)
-void do_cntlzd (void)
+target_ulong helper_cntlzd (target_ulong t)
 {
-    T0 = clz64(T0);
+    return clz64(t);
 }
 #endif
 
 /* shift right arithmetic helper */
-void do_sraw (void)
+target_ulong helper_sraw (target_ulong value, target_ulong shift)
 {
     int32_t ret;
 
-    if (likely(!(T1 & 0x20UL))) {
-        if (likely((uint32_t)T1 != 0)) {
-            ret = (int32_t)T0 >> (T1 & 0x1fUL);
-            if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
+    if (likely(!(shift & 0x20))) {
+        if (likely((uint32_t)shift != 0)) {
+            shift &= 0x1f;
+            ret = (int32_t)value >> shift;
+            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
                 env->xer &= ~(1 << XER_CA);
             } else {
                 env->xer |= (1 << XER_CA);
             }
         } else {
-            ret = T0;
+            ret = (int32_t)value;
             env->xer &= ~(1 << XER_CA);
         }
     } else {
-        ret = UINT32_MAX * ((uint32_t)T0 >> 31);
-        if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
+        ret = (int32_t)value >> 31;
+        if (ret) {
+            env->xer |= (1 << XER_CA);
+        } else {
             env->xer &= ~(1 << XER_CA);
-        } else {
-            env->xer |= (1 << XER_CA);
         }
     }
-    T0 = ret;
+    return (target_long)ret;
 }
 
 #if defined(TARGET_PPC64)
-void do_srad (void)
+target_ulong helper_srad (target_ulong value, target_ulong shift)
 {
     int64_t ret;
 
-    if (likely(!(T1 & 0x40UL))) {
-        if (likely((uint64_t)T1 != 0)) {
-            ret = (int64_t)T0 >> (T1 & 0x3FUL);
-            if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
+    if (likely(!(shift & 0x40))) {
+        if (likely((uint64_t)shift != 0)) {
+            shift &= 0x3f;
+            ret = (int64_t)value >> shift;
+            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
                 env->xer &= ~(1 << XER_CA);
             } else {
                 env->xer |= (1 << XER_CA);
             }
         } else {
-            ret = T0;
+            ret = (int64_t)value;
             env->xer &= ~(1 << XER_CA);
         }
     } else {
-        ret = UINT64_MAX * ((uint64_t)T0 >> 63);
-        if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
+        ret = (int64_t)value >> 63;
+        if (ret) {
+            env->xer |= (1 << XER_CA);
+        } else {
             env->xer &= ~(1 << XER_CA);
-        } else {
-            env->xer |= (1 << XER_CA);
         }
     }
-    T0 = ret;
+    return ret;
 }
 #endif
 
-void do_popcntb (void)
+target_ulong helper_popcntb (target_ulong val)
 {
     uint32_t ret;
     int i;
 
     ret = 0;
     for (i = 0; i < 32; i += 8)
-        ret |= ctpop8((T0 >> i) & 0xFF) << i;
-    T0 = ret;
+        ret |= ctpop8((val >> i) & 0xFF) << i;
+    return ret;
 }
 
 #if defined(TARGET_PPC64)
-void do_popcntb_64 (void)
+target_ulong helper_popcntb_64 (target_ulong val)
 {
     uint64_t ret;
     int i;
 
     ret = 0;
     for (i = 0; i < 64; i += 8)
-        ret |= ctpop8((T0 >> i) & 0xFF) << i;
-    T0 = ret;
+        ret |= ctpop8((val >> i) & 0xFF) << i;
+    return ret;
 }
 #endif
 

Modified: trunk/target-ppc/translate.c
===================================================================
--- trunk/target-ppc/translate.c        2008-10-21 11:31:14 UTC (rev 5505)
+++ trunk/target-ppc/translate.c        2008-10-21 11:31:27 UTC (rev 5506)
@@ -1277,63 +1277,56 @@
 #endif
 
 /***                            Integer logical                            ***/
-#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
-GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
+#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
+GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)                          \
 {                                                                             \
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
-    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);                       \
-    gen_op_##name();                                                          \
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
+    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
+       cpu_gpr[rB(ctx->opcode)]);                                             \
     if (unlikely(Rc(ctx->opcode) != 0))                                       \
-        gen_set_Rc0(ctx, cpu_T[0]);                                           \
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
 }
-#define GEN_LOGICAL2(name, opc, type)                                         \
-__GEN_LOGICAL2(name, 0x1C, opc, type)
 
-#define GEN_LOGICAL1(name, opc, type)                                         \
+#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
 {                                                                             \
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);                       \
-    gen_op_##name();                                                          \
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);                       \
+    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
     if (unlikely(Rc(ctx->opcode) != 0))                                       \
-        gen_set_Rc0(ctx, cpu_T[0]);                                           \
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
 }
 
 /* and & and. */
-GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
+GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
 /* andc & andc. */
-GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
+GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
 /* andi. */
 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 {
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode));
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
-    gen_set_Rc0(ctx, cpu_T[0]);
+    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
UIMM(ctx->opcode));
+    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 /* andis. */
 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 {
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode) << 16);
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
-    gen_set_Rc0(ctx, cpu_T[0]);
+    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
UIMM(ctx->opcode) << 16);
+    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
-
 /* cntlzw */
-GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
+GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
+{
+    tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], 
cpu_gpr[rS(ctx->opcode)]);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rS(ctx->opcode)]);
+}
 /* eqv & eqv. */
-GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
+GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
 /* extsb & extsb. */
-GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
+GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
 /* extsh & extsh. */
-GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
+GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
 /* nand & nand. */
-GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
+GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
 /* nor & nor. */
-GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
-
+GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
 /* or & or. */
 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
 {
@@ -1344,55 +1337,54 @@
     rb = rB(ctx->opcode);
     /* Optimisation for mr. ri case */
     if (rs != ra || rs != rb) {
-        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
-        if (rs != rb) {
-            tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
-            gen_op_or();
-        }
-        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
+        if (rs != rb)
+            tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
+        else
+            tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
         if (unlikely(Rc(ctx->opcode) != 0))
-            gen_set_Rc0(ctx, cpu_T[0]);
+            gen_set_Rc0(ctx, cpu_gpr[ra]);
     } else if (unlikely(Rc(ctx->opcode) != 0)) {
-        tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
-        gen_set_Rc0(ctx, cpu_T[0]);
+        gen_set_Rc0(ctx, cpu_gpr[rs]);
 #if defined(TARGET_PPC64)
     } else {
+        int prio = 0;
+
         switch (rs) {
         case 1:
             /* Set process priority to low */
-            gen_op_store_pri(2);
+            prio = 2;
             break;
         case 6:
             /* Set process priority to medium-low */
-            gen_op_store_pri(3);
+            prio = 3;
             break;
         case 2:
             /* Set process priority to normal */
-            gen_op_store_pri(4);
+            prio = 4;
             break;
 #if !defined(CONFIG_USER_ONLY)
         case 31:
             if (ctx->supervisor > 0) {
                 /* Set process priority to very low */
-                gen_op_store_pri(1);
+                prio = 1;
             }
             break;
         case 5:
             if (ctx->supervisor > 0) {
                 /* Set process priority to medium-hight */
-                gen_op_store_pri(5);
+                prio = 5;
             }
             break;
         case 3:
             if (ctx->supervisor > 0) {
                 /* Set process priority to high */
-                gen_op_store_pri(6);
+                prio = 6;
             }
             break;
         case 7:
             if (ctx->supervisor > 1) {
                 /* Set process priority to very high */
-                gen_op_store_pri(7);
+                prio = 7;
             }
             break;
 #endif
@@ -1400,26 +1392,29 @@
             /* nop */
             break;
         }
+        if (prio) {
+            TCGv temp = tcg_temp_new(TCG_TYPE_TL);
+            tcg_gen_ld_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
+            tcg_gen_andi_tl(temp, temp, ~0x001C000000000000ULL);
+            tcg_gen_ori_tl(temp, temp, ((uint64_t)prio) << 50);
+            tcg_gen_st_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
+            tcg_temp_free(temp);
+        }
 #endif
     }
 }
-
 /* orc & orc. */
-GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
+GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
 /* xor & xor. */
 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
 {
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
     /* Optimisation for "set to zero" case */
-    if (rS(ctx->opcode) != rB(ctx->opcode)) {
-        tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
-        gen_op_xor();
-    } else {
-        tcg_gen_movi_tl(cpu_T[0], 0);
-    }
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+    if (rS(ctx->opcode) != rB(ctx->opcode))
+       tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
cpu_gpr[rB(ctx->opcode)]);
+    else
+        tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
     if (unlikely(Rc(ctx->opcode) != 0))
-        gen_set_Rc0(ctx, cpu_T[0]);
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 /* ori */
 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1431,10 +1426,7 @@
         /* XXX: should handle special NOPs for POWER series */
         return;
     }
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    if (likely(uimm != 0))
-        gen_op_ori(uimm);
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
 }
 /* oris */
 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1445,10 +1437,7 @@
         /* NOP */
         return;
     }
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    if (likely(uimm != 0))
-        gen_op_ori(uimm << 16);
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 
16);
 }
 /* xori */
 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
@@ -1459,12 +1448,8 @@
         /* NOP */
         return;
     }
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    if (likely(uimm != 0))
-        gen_op_xori(uimm);
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
 }
-
 /* xoris */
 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 {
@@ -1474,30 +1459,29 @@
         /* NOP */
         return;
     }
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    if (likely(uimm != 0))
-        gen_op_xori(uimm << 16);
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm 
<< 16);
 }
-
 /* popcntb : PowerPC 2.03 specification */
 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
 {
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
 #if defined(TARGET_PPC64)
     if (ctx->sf_mode)
-        gen_op_popcntb_64();
+        tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], 
cpu_gpr[rS(ctx->opcode)]);
     else
 #endif
-        gen_op_popcntb();
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
+        tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], 
cpu_gpr[rS(ctx->opcode)]);
 }
 
 #if defined(TARGET_PPC64)
 /* extsw & extsw. */
-GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
+GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
 /* cntlzd */
-GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
+GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
+{
+    tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], 
cpu_gpr[rS(ctx->opcode)]);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 #endif
 
 /***                             Integer rotate                            ***/
@@ -1759,54 +1743,141 @@
 
 /***                             Integer shift                             ***/
 /* slw & slw. */
-__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
+GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
+{
+    TCGv temp;
+    int l1, l2;
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+
+    temp = tcg_temp_local_new(TCG_TYPE_TL);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
+    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
+    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+    gen_set_label(l2);
+    tcg_temp_free(temp);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 /* sraw & sraw. */
-__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
+GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
+{
+    tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
+                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 /* srawi & srawi. */
 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
 {
-    int mb, me;
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    if (SH(ctx->opcode) != 0) {
-        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
-        mb = 32 - SH(ctx->opcode);
-        me = 31;
-#if defined(TARGET_PPC64)
-        mb += 32;
-        me += 32;
-#endif
-        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
+    int sh = SH(ctx->opcode);
+    if (sh != 0) {
+        int l1, l2;
+        TCGv temp;
+        l1 = gen_new_label();
+        l2 = gen_new_label();
+        temp = tcg_temp_local_new(TCG_TYPE_TL);
+        tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_brcondi_tl(TCG_COND_GE, temp, 0, l1);
+        tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
+        tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+        tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
+        tcg_gen_br(l2);
+        gen_set_label(l1);
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
+        gen_set_label(l2);
+        tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], temp, sh);
+        tcg_temp_free(temp);
+    } else {
+        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
     }
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
     if (unlikely(Rc(ctx->opcode) != 0))
-        gen_set_Rc0(ctx, cpu_T[0]);
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 /* srw & srw. */
-__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
+GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
+{
+    TCGv temp;
+    int l1, l2;
+    l1 = gen_new_label();
+    l2 = gen_new_label();
 
+    temp = tcg_temp_local_new(TCG_TYPE_TL);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
+    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
+    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+    gen_set_label(l2);
+    tcg_temp_free(temp);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 #if defined(TARGET_PPC64)
 /* sld & sld. */
-__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
+GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
+{
+    TCGv temp;
+    int l1, l2;
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+
+    temp = tcg_temp_local_new(TCG_TYPE_TL);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
+    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
+    gen_set_label(l2);
+    tcg_temp_free(temp);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 /* srad & srad. */
-__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
+GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
+{
+    tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
+                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 /* sradi & sradi. */
 static always_inline void gen_sradi (DisasContext *ctx, int n)
 {
-    uint64_t mask;
-    int sh, mb, me;
-
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
-    sh = SH(ctx->opcode) + (n << 5);
+    int sh = SH(ctx->opcode) + (n << 5);
     if (sh != 0) {
-        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
-        mb = 64 - SH(ctx->opcode);
-        me = 63;
-        mask = MASK(mb, me);
-        gen_op_sradi(sh, mask >> 32, mask);
+        int l1, l2;
+        TCGv temp;
+        l1 = gen_new_label();
+        l2 = gen_new_label();
+        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
+        temp = tcg_temp_new(TCG_TYPE_TL);
+        tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
+        tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+        tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
+        tcg_gen_br(l2);
+        gen_set_label(l1);
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
+        gen_set_label(l2);
+        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 
sh);
+    } else {
+        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
     }
-    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
     if (unlikely(Rc(ctx->opcode) != 0))
-        gen_set_Rc0(ctx, cpu_T[0]);
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
 {
@@ -1817,7 +1888,26 @@
     gen_sradi(ctx, 1);
 }
 /* srd & srd. */
-__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
+GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
+{
+    TCGv temp;
+    int l1, l2;
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+
+    temp = tcg_temp_local_new(TCG_TYPE_TL);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
+    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
+    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
+    gen_set_label(l2);
+    tcg_temp_free(temp);
+    if (unlikely(Rc(ctx->opcode) != 0))
+        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
+}
 #endif
 
 /***                       Floating-Point arithmetic                       ***/






reply via email to

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