qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5591] target-ppc: convert 405 MAC instructions to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5591] target-ppc: convert 405 MAC instructions to TCG
Date: Sat, 01 Nov 2008 00:54:24 +0000

Revision: 5591
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5591
Author:   aurel32
Date:     2008-11-01 00:54:23 +0000 (Sat, 01 Nov 2008)

Log Message:
-----------
target-ppc: convert 405 MAC instructions to TCG

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

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

Modified: trunk/target-ppc/op.c
===================================================================
--- trunk/target-ppc/op.c       2008-11-01 00:54:12 UTC (rev 5590)
+++ trunk/target-ppc/op.c       2008-11-01 00:54:23 UTC (rev 5591)
@@ -326,34 +326,6 @@
     RETURN();
 }
 
-/***                           Integer arithmetic                          ***/
-/* add */
-void OPPROTO op_check_addo (void)
-{
-    int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
-              ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
-    if (ov) {
-        env->xer |= (1 << XER_OV) | (1 << XER_SO);
-    } else {
-        env->xer &= ~(1 << XER_OV);
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_check_addo_64 (void)
-{
-    int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
-              ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
-    if (ov) {
-        env->xer |= (1 << XER_OV) | (1 << XER_SO);
-    } else {
-        env->xer &= ~(1 << XER_OV);
-    }
-    RETURN();
-}
-#endif
-
 /***                             Integer shift                             ***/
 void OPPROTO op_srli_T1 (void)
 {
@@ -1062,73 +1034,6 @@
 #endif
 
 /* PowerPC 4xx specific micro-ops */
-void OPPROTO op_405_add_T0_T2 (void)
-{
-    T0 = (int32_t)T0 + (int32_t)T2;
-    RETURN();
-}
-
-void OPPROTO op_405_mulchw (void)
-{
-    T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
-    RETURN();
-}
-
-void OPPROTO op_405_mulchwu (void)
-{
-    T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
-    RETURN();
-}
-
-void OPPROTO op_405_mulhhw (void)
-{
-    T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
-    RETURN();
-}
-
-void OPPROTO op_405_mulhhwu (void)
-{
-    T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
-    RETURN();
-}
-
-void OPPROTO op_405_mullhw (void)
-{
-    T0 = ((int16_t)T0) * ((int16_t)T1);
-    RETURN();
-}
-
-void OPPROTO op_405_mullhwu (void)
-{
-    T0 = ((uint16_t)T0) * ((uint16_t)T1);
-    RETURN();
-}
-
-void OPPROTO op_405_check_sat (void)
-{
-    do_405_check_sat();
-    RETURN();
-}
-
-void OPPROTO op_405_check_ovu (void)
-{
-    if (likely(T0 >= T2)) {
-        env->xer &= ~(1 << XER_OV);
-    } else {
-        env->xer |= (1 << XER_OV) | (1 << XER_SO);
-    }
-    RETURN();
-}
-
-void OPPROTO op_405_check_satu (void)
-{
-    if (unlikely(T0 < T2)) {
-        /* Saturate result */
-        T0 = UINT32_MAX;
-    }
-    RETURN();
-}
-
 void OPPROTO op_load_dcr (void)
 {
     do_load_dcr();

Modified: trunk/target-ppc/op_helper.c
===================================================================
--- trunk/target-ppc/op_helper.c        2008-11-01 00:54:12 UTC (rev 5590)
+++ trunk/target-ppc/op_helper.c        2008-11-01 00:54:23 UTC (rev 5591)
@@ -1510,18 +1510,6 @@
 
 /*****************************************************************************/
 /* Embedded PowerPC specific helpers */
-void do_405_check_sat (void)
-{
-    if (!likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) ||
-                !(((uint32_t)T0 ^ (uint32_t)T2) >> 31))) {
-        /* Saturate result */
-        if (T2 >> 31) {
-            T0 = INT32_MIN;
-        } else {
-            T0 = INT32_MAX;
-        }
-    }
-}
 
 /* XXX: to be improved to check access rights when in user-mode */
 void do_load_dcr (void)

Modified: trunk/target-ppc/op_helper.h
===================================================================
--- trunk/target-ppc/op_helper.h        2008-11-01 00:54:12 UTC (rev 5590)
+++ trunk/target-ppc/op_helper.h        2008-11-01 00:54:23 UTC (rev 5591)
@@ -144,7 +144,6 @@
 #endif
 
 /* PowerPC 4xx specific helpers */
-void do_405_check_sat (void);
 void do_load_dcr (void);
 void do_store_dcr (void);
 #if !defined(CONFIG_USER_ONLY)

Modified: trunk/target-ppc/translate.c
===================================================================
--- trunk/target-ppc/translate.c        2008-11-01 00:54:12 UTC (rev 5590)
+++ trunk/target-ppc/translate.c        2008-11-01 00:54:23 UTC (rev 5591)
@@ -5214,8 +5214,11 @@
                                                 int opc2, int opc3,
                                                 int ra, int rb, int rt, int Rc)
 {
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[ra]);
-    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
+    TCGv t0, t1;
+
+    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t1 = tcg_temp_local_new(TCG_TYPE_TL);
+
     switch (opc3 & 0x0D) {
     case 0x05:
         /* macchw    - macchw.    - macchwo   - macchwo.   */
@@ -5223,13 +5226,17 @@
         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
         /* mulchw - mulchw. */
-        gen_op_405_mulchw();
+        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
+        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
+        tcg_gen_ext16s_tl(t1, t1);
         break;
     case 0x04:
         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
         /* mulchwu - mulchwu. */
-        gen_op_405_mulchwu();
+        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
+        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
+        tcg_gen_ext16u_tl(t1, t1);
         break;
     case 0x01:
         /* machhw    - machhw.    - machhwo   - machhwo.   */
@@ -5237,13 +5244,19 @@
         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
         /* mulhhw - mulhhw. */
-        gen_op_405_mulhhw();
+        tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
+        tcg_gen_ext16s_tl(t0, t0);
+        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
+        tcg_gen_ext16s_tl(t1, t1);
         break;
     case 0x00:
         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
         /* mulhhwu - mulhhwu. */
-        gen_op_405_mulhhwu();
+        tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
+        tcg_gen_ext16u_tl(t0, t0);
+        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
+        tcg_gen_ext16u_tl(t1, t1);
         break;
     case 0x0D:
         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
@@ -5251,43 +5264,70 @@
         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
         /* mullhw - mullhw. */
-        gen_op_405_mullhw();
+        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
+        tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
         break;
     case 0x0C:
         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
         /* mullhwu - mullhwu. */
-        gen_op_405_mullhwu();
+        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
+        tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
         break;
     }
-    if (opc2 & 0x02) {
-        /* nmultiply-and-accumulate (0x0E) */
-        tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
-    }
     if (opc2 & 0x04) {
-        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
-        tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rt]);
-        tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
-        gen_op_405_add_T0_T2();
+        /* (n)multiply-and-accumulate (0x0C / 0x0E) */
+        tcg_gen_mul_tl(t1, t0, t1);
+        if (opc2 & 0x02) {
+            /* nmultiply-and-accumulate (0x0E) */
+            tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
+        } else {
+            /* multiply-and-accumulate (0x0C) */
+            tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
+        }
+
+        if (opc3 & 0x12) {
+            /* Check overflow and/or saturate */
+            int l1 = gen_new_label();
+
+            if (opc3 & 0x10) {
+                /* Start with XER OV disabled, the most likely case */
+                tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+            }
+            if (opc3 & 0x01) {
+                /* Signed */
+                tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
+                tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
+                tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
+                tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
+               if (opc3 & 0x02) {
+                    /* Saturate */
+                    tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
+                    tcg_gen_xori_tl(t0, t0, 0x7fffffff);
+                }
+            } else {
+                /* Unsigned */
+                tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
+               if (opc3 & 0x02) {
+                    /* Saturate */
+                    tcg_gen_movi_tl(t0, UINT32_MAX);
+                }
+            }
+            if (opc3 & 0x10) {
+                /* Check overflow */
+                tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << 
XER_SO));
+            }
+            gen_set_label(l1);
+            tcg_gen_mov_tl(cpu_gpr[rt], t0);
+        }
+    } else {
+        tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
     }
-    if (opc3 & 0x10) {
-        /* Check overflow */
-        if (opc3 & 0x01)
-            gen_op_check_addo();
-        else
-            gen_op_405_check_ovu();
-    }
-    if (opc3 & 0x02) {
-        /* Saturate */
-        if (opc3 & 0x01)
-            gen_op_405_check_sat();
-        else
-            gen_op_405_check_satu();
-    }
-    tcg_gen_mov_tl(cpu_gpr[rt], cpu_T[0]);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
     if (unlikely(Rc) != 0) {
         /* Update Rc0 */
-        gen_set_Rc0(ctx, cpu_T[0]);
+        gen_set_Rc0(ctx, cpu_gpr[rt]);
     }
 }
 






reply via email to

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