diff options
-rw-r--r-- | target-ppc/helper.h | 3 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 63 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 8 | ||||
-rw-r--r-- | target-ppc/op_helper_mem.h | 65 | ||||
-rw-r--r-- | target-ppc/op_mem.h | 57 | ||||
-rw-r--r-- | target-ppc/translate.c | 24 |
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 ***/ |