qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5830] target-ppc: convert load/store with reservation inst


From: Aurelien Jarno
Subject: [Qemu-devel] [5830] target-ppc: convert load/store with reservation instructions to TCG
Date: Sun, 30 Nov 2008 16:24:39 +0000

Revision: 5830
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5830
Author:   aurel32
Date:     2008-11-30 16:24:39 +0000 (Sun, 30 Nov 2008)

Log Message:
-----------
target-ppc: convert load/store with reservation instructions to TCG

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

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

Modified: trunk/target-ppc/op_mem.h
===================================================================
--- trunk/target-ppc/op_mem.h   2008-11-30 16:24:30 UTC (rev 5829)
+++ trunk/target-ppc/op_mem.h   2008-11-30 16:24:39 UTC (rev 5830)
@@ -20,232 +20,6 @@
 
 #include "op_mem_access.h"
 
-/* Load and set reservation */
-void OPPROTO glue(op_lwarx, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
-        env->reserve = (uint32_t)T0;
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
-        env->reserve = (uint64_t)T0;
-    }
-    RETURN();
-}
-
-void OPPROTO glue(op_ldarx, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu64, MEMSUFFIX)((uint32_t)T0);
-        env->reserve = (uint32_t)T0;
-    }
-    RETURN();
-}
-
-void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu64, MEMSUFFIX)((uint64_t)T0);
-        env->reserve = (uint64_t)T0;
-    }
-    RETURN();
-}
-#endif
-
-void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
-        env->reserve = (uint32_t)T0;
-    }
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
-        env->reserve = (uint64_t)T0;
-    }
-    RETURN();
-}
-
-void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu64r, MEMSUFFIX)((uint32_t)T0);
-        env->reserve = (uint32_t)T0;
-    }
-    RETURN();
-}
-
-void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        T1 = glue(ldu64r, MEMSUFFIX)((uint64_t)T0);
-        env->reserve = (uint64_t)T0;
-    }
-    RETURN();
-}
-#endif
-
-/* Store with reservation */
-void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint32_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st32, MEMSUFFIX)((uint32_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint64_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st32, MEMSUFFIX)((uint64_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-void OPPROTO glue(op_stdcx, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint32_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st64, MEMSUFFIX)((uint32_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint64_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st64, MEMSUFFIX)((uint64_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-#endif
-
-void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint32_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st32r, MEMSUFFIX)((uint32_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint64_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st32r, MEMSUFFIX)((uint64_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint32_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st64r, MEMSUFFIX)((uint32_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-
-void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void)
-{
-    if (unlikely(T0 & 0x03)) {
-        raise_exception(env, POWERPC_EXCP_ALIGN);
-    } else {
-        if (unlikely(env->reserve != (uint64_t)T0)) {
-            env->crf[0] = xer_so;
-        } else {
-            glue(st64r, MEMSUFFIX)((uint64_t)T0, T1);
-            env->crf[0] = xer_so | 0x02;
-        }
-    }
-    env->reserve = (target_ulong)-1ULL;
-    RETURN();
-}
-#endif
-
 /* External access */
 void OPPROTO glue(op_eciwx, MEMSUFFIX) (void)
 {

Modified: trunk/target-ppc/translate.c
===================================================================
--- trunk/target-ppc/translate.c        2008-11-30 16:24:30 UTC (rev 5829)
+++ trunk/target-ppc/translate.c        2008-11-30 16:24:39 UTC (rev 5830)
@@ -66,6 +66,7 @@
 static TCGv cpu_ctr;
 static TCGv cpu_lr;
 static TCGv cpu_xer;
+static TCGv cpu_reserve;
 static TCGv_i32 cpu_fpscr;
 static TCGv_i32 cpu_access_type;
 
@@ -161,6 +162,9 @@
     cpu_xer = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUState, xer), "xer");
 
+    cpu_reserve = tcg_global_mem_new(TCG_AREG0,
+                                     offsetof(CPUState, reserve), "reserve");
+
     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
                                        offsetof(CPUState, fpscr), "fpscr");
 
@@ -2468,6 +2472,24 @@
         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
 }
 
+static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int 
mask)
+{
+    int l1 = gen_new_label();
+    TCGv t0 = tcg_temp_new();
+    TCGv_i32 t1, t2;
+    /* NIP cannot be restored if the memory exception comes from an helper */
+    gen_update_nip(ctx, ctx->nip - 4);
+    tcg_gen_andi_tl(t0, EA, mask);
+    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
+    t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
+    t2 = tcg_const_i32(0);
+    gen_helper_raise_exception_err(t1, t2);
+    tcg_temp_free_i32(t1);
+    tcg_temp_free_i32(t2);
+    gen_set_label(l1);
+    tcg_temp_free(t0);
+}
+
 #if defined(TARGET_PPC64)
 #define _GEN_MEM_FUNCS(name, mode)                                            \
     &gen_op_##name##_##mode,                                                  \
@@ -3220,67 +3242,79 @@
     GEN_STOP(ctx);
 }
 
-#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
-#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
-static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
-    GEN_MEM_FUNCS(lwarx),
-};
-static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
-    GEN_MEM_FUNCS(stwcx),
-};
-
 /* lwarx */
 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
 {
-    /* NIP cannot be restored if the memory exception comes from an helper */
-    gen_update_nip(ctx, ctx->nip - 4);
+    TCGv t0 = tcg_temp_local_new();
     gen_set_access_type(ACCESS_RES);
-    gen_addr_reg_index(cpu_T[0], ctx);
-    op_lwarx();
-    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
+    gen_addr_reg_index(t0, ctx);
+    gen_check_align(ctx, t0, 0x03);
+#if defined(TARGET_PPC64)
+    if (!ctx->sf_mode)
+        tcg_gen_ext32u_tl(t0, t0);
+#endif
+    gen_qemu_ld32u(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+    tcg_gen_mov_tl(cpu_reserve, t0);
+    tcg_temp_free(t0);
 }
 
 /* stwcx. */
 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
 {
-    /* NIP cannot be restored if the memory exception comes from an helper */
-    gen_update_nip(ctx, ctx->nip - 4);
+    int l1 = gen_new_label();
+    TCGv t0 = tcg_temp_local_new();
     gen_set_access_type(ACCESS_RES);
-    gen_addr_reg_index(cpu_T[0], ctx);
-    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
-    op_stwcx();
+    gen_addr_reg_index(t0, ctx);
+    gen_check_align(ctx, t0, 0x03);
+#if defined(TARGET_PPC64)
+    if (!ctx->sf_mode)
+        tcg_gen_ext32u_tl(t0, t0);
+#endif
+    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
+    tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
+    tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+    tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
+    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+    gen_qemu_st32(cpu_gpr[rS(ctx->opcode)], t0, ctx->mem_idx);
+    gen_set_label(l1);
+    tcg_gen_movi_tl(cpu_reserve, -1);
+    tcg_temp_free(t0);
 }
 
 #if defined(TARGET_PPC64)
-#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
-#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
-static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
-    GEN_MEM_FUNCS(ldarx),
-};
-static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
-    GEN_MEM_FUNCS(stdcx),
-};
-
 /* ldarx */
 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
 {
-    /* NIP cannot be restored if the memory exception comes from an helper */
-    gen_update_nip(ctx, ctx->nip - 4);
+    TCGv t0 = tcg_temp_local_new();
     gen_set_access_type(ACCESS_RES);
-    gen_addr_reg_index(cpu_T[0], ctx);
-    op_ldarx();
-    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[1]);
+    gen_addr_reg_index(t0, ctx);
+    gen_check_align(ctx, t0, 0x07);
+    if (!ctx->sf_mode)
+        tcg_gen_ext32u_tl(t0, t0);
+    gen_qemu_ld64(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx);
+    tcg_gen_mov_tl(cpu_reserve, t0);
+    tcg_temp_free(t0);
 }
 
 /* stdcx. */
 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
 {
-    /* NIP cannot be restored if the memory exception comes from an helper */
-    gen_update_nip(ctx, ctx->nip - 4);
+    int l1 = gen_new_label();
+    TCGv t0 = tcg_temp_local_new();
     gen_set_access_type(ACCESS_RES);
-    gen_addr_reg_index(cpu_T[0], ctx);
-    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]);
-    op_stdcx();
+    gen_addr_reg_index(t0, ctx);
+    gen_check_align(ctx, t0, 0x07);
+    if (!ctx->sf_mode)
+        tcg_gen_ext32u_tl(t0, t0);
+    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
+    tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
+    tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+    tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
+    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+    gen_qemu_st64(cpu_gpr[rS(ctx->opcode)], t0, ctx->mem_idx);
+    gen_set_label(l1);
+    tcg_gen_movi_tl(cpu_reserve, -1);
+    tcg_temp_free(t0);
 }
 #endif /* defined(TARGET_PPC64) */
 






reply via email to

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