summaryrefslogtreecommitdiff
path: root/target-ppc/op_helper.c
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 /target-ppc/op_helper.c
parent931ff2725866606d0c695576a9ec3b7808d82b24 (diff)
downloadqemu-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.c63
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)