diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-30 16:23:56 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-30 16:23:56 +0000 |
commit | ff4a62cd8100f373ce0195d5e888c191a1a07516 (patch) | |
tree | de38d0dee486aa52e65a19af34a1b59f7eacc1fa /target-ppc/op_helper.c | |
parent | 931ff2725866606d0c695576a9ec3b7808d82b24 (diff) | |
download | qemu-ff4a62cd8100f373ce0195d5e888c191a1a07516.zip |
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
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 63 |
1 files changed, 63 insertions, 0 deletions
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) |