qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5500] target-ppc: Convert XER accesses to TCG


From: Aurelien Jarno
Subject: [Qemu-devel] [5500] target-ppc: Convert XER accesses to TCG
Date: Tue, 21 Oct 2008 11:28:47 +0000

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

Log Message:
-----------
target-ppc: Convert XER accesses to TCG

Define XER bits as a single register and access them individually to
avoid defining 5 32-bit registers (TCG doesn't permit to map 8-bit
registers).

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

Modified Paths:
--------------
    trunk/gdbstub.c
    trunk/monitor.c
    trunk/target-ppc/cpu.h
    trunk/target-ppc/helper.c
    trunk/target-ppc/helper_regs.h
    trunk/target-ppc/op.c
    trunk/target-ppc/op_helper.c
    trunk/target-ppc/translate.c
    trunk/target-ppc/translate_init.c

Modified: trunk/gdbstub.c
===================================================================
--- trunk/gdbstub.c     2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/gdbstub.c     2008-10-21 11:28:46 UTC (rev 5500)
@@ -445,7 +445,7 @@
             }
         case 67: GET_REGL(env->lr);
         case 68: GET_REGL(env->ctr);
-        case 69: GET_REG32(ppc_load_xer(env));
+        case 69: GET_REGL(env->xer);
         case 70: GET_REG32(0); /* fpscr */
         }
     }
@@ -485,8 +485,8 @@
             env->ctr = ldtul_p(mem_buf);
             return sizeof(target_ulong);
         case 69:
-            ppc_store_xer(env, ldl_p(mem_buf));
-            return 4;
+            env->xer = ldtul_p(mem_buf);
+            return sizeof(target_ulong);
         case 70:
             /* fpscr */
             return 4;

Modified: trunk/monitor.c
===================================================================
--- trunk/monitor.c     2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/monitor.c     2008-10-21 11:28:46 UTC (rev 5500)
@@ -1582,7 +1582,7 @@
     CPUState *env = mon_get_cpu();
     if (!env)
         return 0;
-    return ppc_load_xer(env);
+    return env->xer;
 }
 
 static target_long monitor_get_decr (const struct MonitorDef *md, int val)

Modified: trunk/target-ppc/cpu.h
===================================================================
--- trunk/target-ppc/cpu.h      2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/cpu.h      2008-10-21 11:28:46 UTC (rev 5500)
@@ -553,8 +553,7 @@
     /* condition register */
     uint32_t crf[8];
     /* XER */
-    /* XXX: We use only 5 fields, but we want to keep the structure aligned */
-    uint8_t xer[8];
+    target_ulong xer;
     /* Reservation address */
     target_ulong reserve;
 
@@ -831,16 +830,16 @@
 
 /*****************************************************************************/
 /* Registers definitions */
-#define XER_SO 31
-#define XER_OV 30
-#define XER_CA 29
-#define XER_CMP 8
-#define XER_BC  0
-#define xer_so  env->xer[4]
-#define xer_ov  env->xer[6]
-#define xer_ca  env->xer[2]
-#define xer_cmp env->xer[1]
-#define xer_bc  env->xer[0]
+#define XER_SO  31
+#define XER_OV  30
+#define XER_CA  29
+#define XER_CMP  8
+#define XER_BC   0
+#define xer_so  ((env->xer >> XER_SO)  &    1)
+#define xer_ov  ((env->xer >> XER_OV)  &    1)
+#define xer_ca  ((env->xer >> XER_CA)  &    1)
+#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
+#define xer_bc  ((env->xer >> XER_BC)  & 0x7F)
 
 /* SPR definitions */
 #define SPR_MQ                (0x000)

Modified: trunk/target-ppc/helper.c
===================================================================
--- trunk/target-ppc/helper.c   2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/helper.c   2008-10-21 11:28:46 UTC (rev 5500)
@@ -2124,16 +2124,6 @@
 }
 #endif /* !defined (CONFIG_USER_ONLY) */
 
-target_ulong ppc_load_xer (CPUPPCState *env)
-{
-    return hreg_load_xer(env);
-}
-
-void ppc_store_xer (CPUPPCState *env, target_ulong value)
-{
-    hreg_store_xer(env, value);
-}
-
 /* GDBstub can read and write MSR... */
 void ppc_store_msr (CPUPPCState *env, target_ulong value)
 {

Modified: trunk/target-ppc/helper_regs.h
===================================================================
--- trunk/target-ppc/helper_regs.h      2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/helper_regs.h      2008-10-21 11:28:46 UTC (rev 5500)
@@ -21,24 +21,6 @@
 #if !defined(__HELPER_REGS_H__)
 #define __HELPER_REGS_H__
 
-static always_inline target_ulong hreg_load_xer (CPUPPCState *env)
-{
-    return (xer_so << XER_SO) |
-        (xer_ov << XER_OV) |
-        (xer_ca << XER_CA) |
-        (xer_bc << XER_BC) |
-        (xer_cmp << XER_CMP);
-}
-
-static always_inline void hreg_store_xer (CPUPPCState *env, target_ulong value)
-{
-    xer_so = (value >> XER_SO) & 0x01;
-    xer_ov = (value >> XER_OV) & 0x01;
-    xer_ca = (value >> XER_CA) & 0x01;
-    xer_cmp = (value >> XER_CMP) & 0xFF;
-    xer_bc = (value >> XER_BC) & 0x7F;
-}
-
 /* Swap temporary saved registers with GPRs */
 static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
 {

Modified: trunk/target-ppc/op.c
===================================================================
--- trunk/target-ppc/op.c       2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/op.c       2008-10-21 11:28:46 UTC (rev 5500)
@@ -58,49 +58,6 @@
     RETURN();
 }
 
-void OPPROTO op_load_xer_cr (void)
-{
-    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
-    RETURN();
-}
-
-void OPPROTO op_clear_xer_ov (void)
-{
-    xer_so = 0;
-    xer_ov = 0;
-    RETURN();
-}
-
-void OPPROTO op_clear_xer_ca (void)
-{
-    xer_ca = 0;
-    RETURN();
-}
-
-void OPPROTO op_load_xer_bc (void)
-{
-    T1 = xer_bc;
-    RETURN();
-}
-
-void OPPROTO op_store_xer_bc (void)
-{
-    xer_bc = T0;
-    RETURN();
-}
-
-void OPPROTO op_load_xer (void)
-{
-    T0 = hreg_load_xer(env);
-    RETURN();
-}
-
-void OPPROTO op_store_xer (void)
-{
-    hreg_store_xer(env, T0);
-    RETURN();
-}
-
 #if defined(TARGET_PPC64)
 void OPPROTO op_store_pri (void)
 {
@@ -574,18 +531,26 @@
 /* add */
 void OPPROTO op_check_addo (void)
 {
-    xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
+    int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
               ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
-    xer_so |= xer_ov;
+    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)
 {
-    xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
+    int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
               ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
-    xer_so |= xer_ov;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     RETURN();
 }
 #endif
@@ -594,9 +559,9 @@
 void OPPROTO op_check_addc (void)
 {
     if (likely((uint32_t)T0 >= (uint32_t)T2)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
     RETURN();
 }
@@ -605,9 +570,9 @@
 void OPPROTO op_check_addc_64 (void)
 {
     if (likely((uint64_t)T0 >= (uint64_t)T2)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
     RETURN();
 }
@@ -633,7 +598,7 @@
 {
     T0 += xer_ca + (-1);
     if (likely((uint32_t)T1 != 0))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     RETURN();
 }
 
@@ -642,7 +607,7 @@
 {
     T0 += xer_ca + (-1);
     if (likely((uint64_t)T1 != 0))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     RETURN();
 }
 #endif
@@ -855,9 +820,9 @@
 void OPPROTO op_check_subfc (void)
 {
     if (likely((uint32_t)T0 > (uint32_t)T1)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
     RETURN();
 }
@@ -866,9 +831,9 @@
 void OPPROTO op_check_subfc_64 (void)
 {
     if (likely((uint64_t)T0 > (uint64_t)T1)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
     RETURN();
 }
@@ -894,9 +859,9 @@
 {
     T0 = (int32_t)PARAM1 + ~T0 + 1;
     if ((uint32_t)T0 <= (uint32_t)PARAM1) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -906,9 +871,9 @@
 {
     T0 = (int64_t)PARAM1 + ~T0 + 1;
     if ((uint64_t)T0 <= (uint64_t)PARAM1) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -919,7 +884,7 @@
 {
     T0 = ~T0 + xer_ca - 1;
     if (likely((uint32_t)T0 != UINT32_MAX))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     RETURN();
 }
 
@@ -928,7 +893,7 @@
 {
     T0 = ~T0 + xer_ca - 1;
     if (likely((uint64_t)T0 != UINT64_MAX))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     RETURN();
 }
 #endif
@@ -953,9 +918,9 @@
     T1 = ~T0;
     T0 = T1 + xer_ca;
     if ((uint32_t)T0 < (uint32_t)T1) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -966,9 +931,9 @@
     T1 = ~T0;
     T0 = T1 + xer_ca;
     if ((uint64_t)T0 < (uint64_t)T1) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -1317,9 +1282,9 @@
 
     T0 = (int32_t)T0 >> PARAM1;
     if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -1331,9 +1296,9 @@
 
     T0 = (int64_t)T0 >> PARAM1;
     if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     } else {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     }
     RETURN();
 }
@@ -1975,7 +1940,7 @@
     /* nabs never overflows */
     if (T0 > 0)
         T0 = -T0;
-    xer_ov = 0;
+    env->xer &= ~(1 << XER_OV);
     RETURN();
 }
 
@@ -2189,10 +2154,9 @@
 void OPPROTO op_405_check_ovu (void)
 {
     if (likely(T0 >= T2)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     }
     RETURN();
 }

Modified: trunk/target-ppc/op_helper.c
===================================================================
--- trunk/target-ppc/op_helper.c        2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/op_helper.c        2008-10-21 11:28:46 UTC (rev 5500)
@@ -119,9 +119,9 @@
     T0 += T1 + xer_ca;
     if (likely(!((uint32_t)T0 < (uint32_t)T2 ||
                  (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 
@@ -132,32 +132,42 @@
     T0 += T1 + xer_ca;
     if (likely(!((uint64_t)T0 < (uint64_t)T2 ||
                  (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 #endif
 
 void do_addmeo (void)
 {
+    int ov;
     T1 = T0;
     T0 += xer_ca + (-1);
-    xer_ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;
-    xer_so |= xer_ov;
+    ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint32_t)T1 != 0))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
 }
 
 #if defined(TARGET_PPC64)
 void do_addmeo_64 (void)
 {
+    int ov;
     T1 = T0;
     T0 += xer_ca + (-1);
-    xer_ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;
-    xer_so |= xer_ov;
+    ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint64_t)T1 != 0))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
 }
 #endif
 
@@ -165,13 +175,12 @@
 {
     if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||
                  (int32_t)T1 == 0))) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = (int32_t)T0 / (int32_t)T1;
     } else {
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
         T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
     }
-    xer_so |= xer_ov;
 }
 
 #if defined(TARGET_PPC64)
@@ -179,24 +188,22 @@
 {
     if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||
                  (int64_t)T1 == 0))) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = (int64_t)T0 / (int64_t)T1;
     } else {
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
         T0 = UINT64_MAX * ((uint64_t)T0 >> 63);
     }
-    xer_so |= xer_ov;
 }
 #endif
 
 void do_divwuo (void)
 {
     if (likely((uint32_t)T1 != 0)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = (uint32_t)T0 / (uint32_t)T1;
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
         T0 = 0;
     }
 }
@@ -205,11 +212,10 @@
 void do_divduo (void)
 {
     if (likely((uint64_t)T1 != 0)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = (uint64_t)T0 / (uint64_t)T1;
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
         T0 = 0;
     }
 }
@@ -220,10 +226,9 @@
     int64_t res = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;
 
     if (likely((int32_t)res == res)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     }
     T0 = (int32_t)res;
 }
@@ -238,22 +243,20 @@
     T0 = (int64_t)tl;
     /* If th != 0 && th != -1, then we had an overflow */
     if (likely((uint64_t)(th + 1) <= 1)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     } else {
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     }
-    xer_so |= xer_ov;
 }
 #endif
 
 void do_nego (void)
 {
     if (likely((int32_t)T0 != INT32_MIN)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = -(int32_t)T0;
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     }
 }
 
@@ -261,11 +264,10 @@
 void do_nego_64 (void)
 {
     if (likely((int64_t)T0 != INT64_MIN)) {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
         T0 = -(int64_t)T0;
     } else {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     }
 }
 #endif
@@ -275,9 +277,9 @@
     T0 = T1 + ~T0 + xer_ca;
     if (likely((uint32_t)T0 >= (uint32_t)T1 &&
                (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 
@@ -287,61 +289,81 @@
     T0 = T1 + ~T0 + xer_ca;
     if (likely((uint64_t)T0 >= (uint64_t)T1 &&
                (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 #endif
 
 void do_subfmeo (void)
 {
+    int ov;
     T1 = T0;
     T0 = ~T0 + xer_ca - 1;
-    xer_ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;
-    xer_so |= xer_ov;
+    ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint32_t)T1 != UINT32_MAX))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
 }
 
 #if defined(TARGET_PPC64)
 void do_subfmeo_64 (void)
 {
+    int ov;
     T1 = T0;
     T0 = ~T0 + xer_ca - 1;
-    xer_ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;
-    xer_so |= xer_ov;
+    ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint64_t)T1 != UINT64_MAX))
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
 }
 #endif
 
 void do_subfzeo (void)
 {
+    int ov;
     T1 = T0;
     T0 = ~T0 + xer_ca;
-    xer_ov = (((uint32_t)~T1 ^ UINT32_MAX) &
-              ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;
-    xer_so |= xer_ov;
+    ov = (((uint32_t)~T1 ^ UINT32_MAX) &
+          ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint32_t)T0 >= (uint32_t)~T1)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 
 #if defined(TARGET_PPC64)
 void do_subfzeo_64 (void)
 {
+    int ov;
     T1 = T0;
     T0 = ~T0 + xer_ca;
-    xer_ov = (((uint64_t)~T1 ^  UINT64_MAX) &
-              ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;
-    xer_so |= xer_ov;
+    ov = (((uint64_t)~T1 ^  UINT64_MAX) &
+          ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;
+    if (ov) {
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
+    } else {
+        env->xer &= ~(1 << XER_OV);
+    }
     if (likely((uint64_t)T0 >= (uint64_t)~T1)) {
-        xer_ca = 0;
+        env->xer &= ~(1 << XER_CA);
     } else {
-        xer_ca = 1;
+        env->xer |= (1 << XER_CA);
     }
 }
 #endif
@@ -367,20 +389,20 @@
         if (likely((uint32_t)T1 != 0)) {
             ret = (int32_t)T0 >> (T1 & 0x1fUL);
             if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
-                xer_ca = 0;
+                env->xer &= ~(1 << XER_CA);
             } else {
-                xer_ca = 1;
+                env->xer |= (1 << XER_CA);
             }
         } else {
             ret = T0;
-            xer_ca = 0;
+            env->xer &= ~(1 << XER_CA);
         }
     } else {
         ret = UINT32_MAX * ((uint32_t)T0 >> 31);
         if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
-            xer_ca = 0;
+            env->xer &= ~(1 << XER_CA);
         } else {
-            xer_ca = 1;
+            env->xer |= (1 << XER_CA);
         }
     }
     T0 = ret;
@@ -395,20 +417,20 @@
         if (likely((uint64_t)T1 != 0)) {
             ret = (int64_t)T0 >> (T1 & 0x3FUL);
             if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
-                xer_ca = 0;
+                env->xer &= ~(1 << XER_CA);
             } else {
-                xer_ca = 1;
+                env->xer |= (1 << XER_CA);
             }
         } else {
             ret = T0;
-            xer_ca = 0;
+            env->xer &= ~(1 << XER_CA);
         }
     } else {
         ret = UINT64_MAX * ((uint64_t)T0 >> 63);
         if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
-            xer_ca = 0;
+            env->xer &= ~(1 << XER_CA);
         } else {
-            xer_ca = 1;
+            env->xer |= (1 << XER_CA);
         }
     }
     T0 = ret;
@@ -1478,14 +1500,13 @@
 {
     if ((int32_t)T0 == INT32_MIN) {
         T0 = INT32_MAX;
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     } else if ((int32_t)T0 < 0) {
         T0 = -T0;
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     } else {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     }
-    xer_so |= xer_ov;
 }
 
 void do_POWER_clcs (void)
@@ -1538,19 +1559,18 @@
         (int32_t)T1 == 0) {
         T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
         env->spr[SPR_MQ] = 0;
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     } else {
         tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ];
         env->spr[SPR_MQ] = tmp % T1;
         tmp /= (int32_t)T1;
         if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) {
-            xer_ov = 1;
+            env->xer |= (1 << XER_OV) | (1 << XER_SO);
         } else {
-            xer_ov = 0;
+            env->xer &= ~(1 << XER_OV);
         }
         T0 = tmp;
     }
-    xer_so |= xer_ov;
 }
 
 void do_POWER_divs (void)
@@ -1571,13 +1591,12 @@
         (int32_t)T1 == 0) {
         T0 = UINT32_MAX * ((uint32_t)T0 >> 31);
         env->spr[SPR_MQ] = 0;
-        xer_ov = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     } else {
         T0 = (int32_t)T0 / (int32_t)T1;
         env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1;
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     }
-    xer_so |= xer_ov;
 }
 
 void do_POWER_dozo (void)
@@ -1587,14 +1606,13 @@
         T0 = T1 - T0;
         if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
             ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) {
-            xer_ov = 1;
-            xer_so = 1;
+            env->xer |= (1 << XER_OV) | (1 << XER_SO);
         } else {
-            xer_ov = 0;
+            env->xer &= ~(1 << XER_OV);
         }
     } else {
         T0 = 0;
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     }
 }
 
@@ -1621,10 +1639,9 @@
     env->spr[SPR_MQ] = tmp >> 32;
     T0 = tmp;
     if (tmp >> 32 != ((uint64_t)T0 >> 16) * ((uint64_t)T1 >> 16)) {
-        xer_ov = 1;
-        xer_so = 1;
+        env->xer |= (1 << XER_OV) | (1 << XER_SO);
     } else {
-        xer_ov = 0;
+        env->xer &= ~(1 << XER_OV);
     }
 }
 

Modified: trunk/target-ppc/translate.c
===================================================================
--- trunk/target-ppc/translate.c        2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/translate.c        2008-10-21 11:28:46 UTC (rev 5500)
@@ -62,6 +62,7 @@
 static TCGv cpu_nip;
 static TCGv cpu_ctr;
 static TCGv cpu_lr;
+static TCGv cpu_xer;
 
 /* dyngen register indexes */
 static TCGv cpu_T[3];
@@ -175,6 +176,9 @@
     cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                 offsetof(CPUState, lr), "lr");
 
+    cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                 offsetof(CPUState, xer), "xer");
+
     /* register helpers */
 #undef DEF_HELPER
 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
@@ -1057,7 +1061,7 @@
 #endif
             gen_op_check_addc();
     } else {
-        gen_op_clear_xer_ca();
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
     }
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
 }
@@ -1077,7 +1081,7 @@
 #endif
             gen_op_check_addc();
     } else {
-        gen_op_clear_xer_ca();
+        tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
     }
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
     gen_set_Rc0(ctx);
@@ -2852,7 +2856,7 @@
     if (ra == 0) {
         ra = rb;
     }
-    gen_op_load_xer_bc();
+    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
     op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
 }
 
@@ -2876,7 +2880,7 @@
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_addr_reg_index(cpu_T[0], ctx);
-    gen_op_load_xer_bc();
+    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
     op_ldsts(stsw, rS(ctx->opcode));
 }
 
@@ -3509,10 +3513,9 @@
 /* mcrxr */
 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
 {
-    gen_op_load_xer_cr();
-    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);
-    gen_op_clear_xer_ov();
-    gen_op_clear_xer_ca();
+    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
+    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 
XER_CA);
+    tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << 
XER_CA));
 }
 
 /* mfcr */
@@ -4310,10 +4313,12 @@
     }
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
-    gen_op_load_xer_bc();
-    gen_op_load_xer_cmp();
+    tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F);
+    tcg_gen_shri_tl(cpu_T[2], cpu_xer, XER_CMP);
+    tcg_gen_andi_tl(cpu_T[2], cpu_T[2], 0xFF);
     op_POWER_lscbx(rD(ctx->opcode), ra, rb);
-    gen_op_store_xer_bc();
+    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
+    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx);
 }
@@ -5500,7 +5505,8 @@
     tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
     gen_op_440_dlmzb();
     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
-    gen_op_store_xer_bc();
+    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
+    tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
     if (Rc(ctx->opcode)) {
         gen_op_440_dlmzb_update_Rc();
         tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
@@ -6391,7 +6397,7 @@
     int i;
 
     cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
-                env->nip, env->lr, env->ctr, hreg_load_xer(env));
+                env->nip, env->lr, env->ctr, env->xer);
     cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
                 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
 #if !defined(NO_TIMER_DUMP)

Modified: trunk/target-ppc/translate_init.c
===================================================================
--- trunk/target-ppc/translate_init.c   2008-10-17 17:31:57 UTC (rev 5499)
+++ trunk/target-ppc/translate_init.c   2008-10-21 11:28:46 UTC (rev 5500)
@@ -99,12 +99,12 @@
 /* XER */
 static void spr_read_xer (void *opaque, int sprn)
 {
-    gen_op_load_xer();
+    tcg_gen_mov_tl(cpu_T[0], cpu_xer);
 }
 
 static void spr_write_xer (void *opaque, int sprn)
 {
-    gen_op_store_xer();
+    tcg_gen_mov_tl(cpu_xer, cpu_T[0]);
 }
 
 /* LR */






reply via email to

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