aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-30 16:23:56 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-30 16:23:56 +0000
commitff4a62cd8100f373ce0195d5e888c191a1a07516 (patch)
treede38d0dee486aa52e65a19af34a1b59f7eacc1fa
parent931ff2725866606d0c695576a9ec3b7808d82b24 (diff)
target-ppc: convert load/store multiple instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5825 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-ppc/helper.h3
-rw-r--r--target-ppc/op_helper.c63
-rw-r--r--target-ppc/op_helper.h8
-rw-r--r--target-ppc/op_helper_mem.h65
-rw-r--r--target-ppc/op_mem.h57
-rw-r--r--target-ppc/translate.c24
6 files changed, 78 insertions, 142 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index d1aaf56d02..a3e5ea0e80 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -7,6 +7,9 @@ DEF_HELPER_3(tw, void, tl, tl, i32)
DEF_HELPER_3(td, void, tl, tl, i32)
#endif
+DEF_HELPER_2(lmw, void, tl, i32)
+DEF_HELPER_2(stmw, void, tl, i32)
+
DEF_HELPER_2(fcmpo, i32, i64, i64)
DEF_HELPER_2(fcmpu, i32, i64, i64)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 2a5e18e409..4796e60859 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -109,6 +109,69 @@ void ppc_store_dump_spr (int sprn, target_ulong val)
}
/*****************************************************************************/
+/* Memory load and stores */
+
+static always_inline target_ulong get_addr(target_ulong addr)
+{
+#if defined(TARGET_PPC64)
+ if (msr_sf)
+ return addr;
+ else
+#endif
+ return (uint32_t)addr;
+}
+
+void helper_lmw (target_ulong addr, uint32_t reg)
+{
+#ifdef CONFIG_USER_ONLY
+#define ldfun ldl_raw
+#else
+ int (*ldfun)(target_ulong);
+
+ switch (env->mmu_idx) {
+ default:
+ case 0: ldfun = ldl_user;
+ break;
+ case 1: ldfun = ldl_kernel;
+ break;
+ case 2: ldfun = ldl_hypv;
+ break;
+ }
+#endif
+ for (; reg < 32; reg++, addr += 4) {
+ if (msr_le)
+ env->gpr[reg] = bswap32(ldfun(get_addr(addr)));
+ else
+ env->gpr[reg] = ldfun(get_addr(addr));
+ }
+}
+
+void helper_stmw (target_ulong addr, uint32_t reg)
+{
+#ifdef CONFIG_USER_ONLY
+#define stfun stl_raw
+#else
+ void (*stfun)(target_ulong, int);
+
+ switch (env->mmu_idx) {
+ default:
+ case 0: stfun = stl_user;
+ break;
+ case 1: stfun = stl_kernel;
+ break;
+ case 2: stfun = stl_hypv;
+ break;
+ }
+#endif
+ for (; reg < 32; reg++, addr += 4) {
+ if (msr_le)
+ stfun(get_addr(addr), bswap32((uint32_t)env->gpr[reg]));
+ else
+ stfun(get_addr(addr), (uint32_t)env->gpr[reg]);
+ }
+}
+
+/*****************************************************************************/
/* Fixed point operations helpers */
#if defined(TARGET_PPC64)
diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h
index 44f02d640c..675292f56b 100644
--- a/target-ppc/op_helper.h
+++ b/target-ppc/op_helper.h
@@ -23,10 +23,6 @@
/* Memory load/store helpers */
void glue(do_lsw, MEMSUFFIX) (int dst);
void glue(do_stsw, MEMSUFFIX) (int src);
-void glue(do_lmw, MEMSUFFIX) (int dst);
-void glue(do_lmw_le, MEMSUFFIX) (int dst);
-void glue(do_stmw, MEMSUFFIX) (int src);
-void glue(do_stmw_le, MEMSUFFIX) (int src);
void glue(do_icbi, MEMSUFFIX) (void);
void glue(do_dcbz, MEMSUFFIX) (void);
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
@@ -38,10 +34,6 @@ void glue(do_POWER2_stfq_le, MEMSUFFIX) (void);
#if defined(TARGET_PPC64)
void glue(do_lsw_64, MEMSUFFIX) (int dst);
void glue(do_stsw_64, MEMSUFFIX) (int src);
-void glue(do_lmw_64, MEMSUFFIX) (int dst);
-void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
-void glue(do_stmw_64, MEMSUFFIX) (int src);
-void glue(do_stmw_le_64, MEMSUFFIX) (int src);
void glue(do_icbi_64, MEMSUFFIX) (void);
void glue(do_dcbz_64, MEMSUFFIX) (void);
#endif
diff --git a/target-ppc/op_helper_mem.h b/target-ppc/op_helper_mem.h
index b896a29b92..cb61e96ec3 100644
--- a/target-ppc/op_helper_mem.h
+++ b/target-ppc/op_helper_mem.h
@@ -20,71 +20,6 @@
#include "op_mem_access.h"
-/* Multiple word / string load and store */
-void glue(do_lmw, MEMSUFFIX) (int dst)
-{
- for (; dst < 32; dst++, T0 += 4) {
- env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
- }
-}
-
-#if defined(TARGET_PPC64)
-void glue(do_lmw_64, MEMSUFFIX) (int dst)
-{
- for (; dst < 32; dst++, T0 += 4) {
- env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
- }
-}
-#endif
-
-void glue(do_stmw, MEMSUFFIX) (int src)
-{
- for (; src < 32; src++, T0 += 4) {
- glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
- }
-}
-
-#if defined(TARGET_PPC64)
-void glue(do_stmw_64, MEMSUFFIX) (int src)
-{
- for (; src < 32; src++, T0 += 4) {
- glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
- }
-}
-#endif
-
-void glue(do_lmw_le, MEMSUFFIX) (int dst)
-{
- for (; dst < 32; dst++, T0 += 4) {
- env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
- }
-}
-
-#if defined(TARGET_PPC64)
-void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
-{
- for (; dst < 32; dst++, T0 += 4) {
- env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
- }
-}
-#endif
-
-void glue(do_stmw_le, MEMSUFFIX) (int src)
-{
- for (; src < 32; src++, T0 += 4) {
- glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
- }
-}
-
-#if defined(TARGET_PPC64)
-void glue(do_stmw_le_64, MEMSUFFIX) (int src)
-{
- for (; src < 32; src++, T0 += 4) {
- glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
- }
-}
-#endif
-
void glue(do_lsw, MEMSUFFIX) (int dst)
{
uint32_t tmp;
diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h
index 2e3b620146..40120db8ba 100644
--- a/target-ppc/op_mem.h
+++ b/target-ppc/op_mem.h
@@ -20,63 +20,6 @@
#include "op_mem_access.h"
-/*** Integer load and store multiple ***/
-void OPPROTO glue(op_lmw, MEMSUFFIX) (void)
-{
- glue(do_lmw, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_lmw_64, MEMSUFFIX) (void)
-{
- glue(do_lmw_64, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-#endif
-
-void OPPROTO glue(op_lmw_le, MEMSUFFIX) (void)
-{
- glue(do_lmw_le, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_lmw_le_64, MEMSUFFIX) (void)
-{
- glue(do_lmw_le_64, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-#endif
-
-void OPPROTO glue(op_stmw, MEMSUFFIX) (void)
-{
- glue(do_stmw, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_stmw_64, MEMSUFFIX) (void)
-{
- glue(do_stmw_64, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-#endif
-
-void OPPROTO glue(op_stmw_le, MEMSUFFIX) (void)
-{
- glue(do_stmw_le, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO glue(op_stmw_le_64, MEMSUFFIX) (void)
-{
- glue(do_stmw_le_64, MEMSUFFIX)(PARAM1);
- RETURN();
-}
-#endif
-
/*** Integer load and store strings ***/
void OPPROTO glue(op_lswi, MEMSUFFIX) (void)
{
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c831ea7819..fe4a745350 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3092,30 +3092,30 @@ void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
/*** Integer load and store multiple ***/
-#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
-static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
- GEN_MEM_FUNCS(lmw),
-};
-static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
- GEN_MEM_FUNCS(stmw),
-};
-
/* lmw */
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
+ TCGv t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(cpu_T[0], ctx, 0);
- op_ldstm(lmw, rD(ctx->opcode));
+ gen_addr_imm_index(t0, ctx, 0);
+ gen_helper_lmw(t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free_i32(t1);
}
/* stmw */
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
{
+ TCGv t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_const_i32(rS(ctx->opcode));
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_addr_imm_index(cpu_T[0], ctx, 0);
- op_ldstm(stmw, rS(ctx->opcode));
+ gen_addr_imm_index(t0, ctx, 0);
+ gen_helper_stmw(t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free_i32(t1);
}
/*** Integer load and store strings ***/