aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2012-05-30 04:23:40 +0000
committerAlexander Graf <agraf@suse.de>2012-06-24 01:04:43 +0200
commit2f5a189caefe2ecbd32faf528a0fbf8c915dfa08 (patch)
tree87960abefc1a5653b12dc178a12ab49191e45480 /target-ppc
parent8555f71dcbbe562429bbb25e0028f71e5741b752 (diff)
ppc: Move load and store helpers, switch to AREG0 free mode
Add an explicit CPUPPCState parameter instead of relying on AREG0 and rename op_helper.c (which only contains load and store helpers) to mem_helper.c. Remove AREG0 swapping in tlb_fill(). Switch to AREG0 free mode. Use cpu_ld{l,uw}_code in translation and interrupt handling, cpu_{ld,st}{l,uw}_data in loads and stores. Signed-off-by: Blue Swirl <blauwirbel@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Andreas Färber <afaerber@suse.de> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/Makefile.objs7
-rw-r--r--target-ppc/excp_helper.c3
-rw-r--r--target-ppc/helper.h30
-rw-r--r--target-ppc/mem_helper.c (renamed from target-ppc/op_helper.c)109
-rw-r--r--target-ppc/translate.c30
5 files changed, 90 insertions, 89 deletions
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index 8d4d16baf3..6c11ef84b7 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -1,12 +1,11 @@
-obj-y += translate.o op_helper.o helper.o
+obj-y += translate.o helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
-obj-y += op_helper.o helper.o
+obj-y += helper.o
obj-y += excp_helper.o
obj-y += fpu_helper.o
obj-y += int_helper.o
obj-y += mmu_helper.o
obj-y += timebase_helper.o
obj-y += misc_helper.o
-
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+obj-y += mem_helper.o
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 7fa7a59b4f..c7762b99c5 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -179,7 +179,8 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
}
/* XXX: this is false */
/* Get rS/rD and rA from faulting opcode */
- env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
+ env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
+ & 0x03FF0000) >> 16;
goto store_current;
case POWERPC_EXCP_PROGRAM: /* Program exception */
switch (env->error_code & ~0xF) {
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index b7a157e35e..ddab97b379 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -20,15 +20,15 @@ DEF_HELPER_1(hrfid, void, env)
#endif
#endif
-DEF_HELPER_2(lmw, void, tl, i32)
-DEF_HELPER_2(stmw, void, tl, i32)
-DEF_HELPER_3(lsw, void, tl, i32, i32)
-DEF_HELPER_4(lswx, void, tl, i32, i32, i32)
-DEF_HELPER_3(stsw, void, tl, i32, i32)
-DEF_HELPER_1(dcbz, void, tl)
-DEF_HELPER_1(dcbz_970, void, tl)
-DEF_HELPER_1(icbi, void, tl)
-DEF_HELPER_4(lscbx, tl, tl, i32, i32, i32)
+DEF_HELPER_3(lmw, void, env, tl, i32)
+DEF_HELPER_3(stmw, void, env, tl, i32)
+DEF_HELPER_4(lsw, void, env, tl, i32, i32)
+DEF_HELPER_5(lswx, void, env, tl, i32, i32, i32)
+DEF_HELPER_4(stsw, void, env, tl, i32, i32)
+DEF_HELPER_2(dcbz, void, env, tl)
+DEF_HELPER_2(dcbz_970, void, env, tl)
+DEF_HELPER_2(icbi, void, env, tl)
+DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
#if defined(TARGET_PPC64)
DEF_HELPER_FLAGS_2(mulhd, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64)
@@ -226,12 +226,12 @@ DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr)
DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr)
DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr)
DEF_HELPER_2(mtvscr, void, env, avr);
-DEF_HELPER_2(lvebx, void, avr, tl)
-DEF_HELPER_2(lvehx, void, avr, tl)
-DEF_HELPER_2(lvewx, void, avr, tl)
-DEF_HELPER_2(stvebx, void, avr, tl)
-DEF_HELPER_2(stvehx, void, avr, tl)
-DEF_HELPER_2(stvewx, void, avr, tl)
+DEF_HELPER_3(lvebx, void, env, avr, tl)
+DEF_HELPER_3(lvehx, void, env, avr, tl)
+DEF_HELPER_3(lvewx, void, env, avr, tl)
+DEF_HELPER_3(stvebx, void, env, avr, tl)
+DEF_HELPER_3(stvehx, void, env, avr, tl)
+DEF_HELPER_3(stvewx, void, env, avr, tl)
DEF_HELPER_4(vsumsws, void, env, avr, avr, avr)
DEF_HELPER_4(vsum2sws, void, env, avr, avr, avr)
DEF_HELPER_4(vsum4sbs, void, env, avr, avr, avr)
diff --git a/target-ppc/op_helper.c b/target-ppc/mem_helper.c
index cd1a53322c..ebcd7b24a8 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/mem_helper.c
@@ -1,5 +1,5 @@
/*
- * PowerPC emulation helpers for QEMU.
+ * PowerPC memory access emulation helpers for QEMU.
*
* Copyright (c) 2003-2007 Jocelyn Mayer
*
@@ -16,9 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
#include "cpu.h"
-#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
@@ -33,7 +31,8 @@
/*****************************************************************************/
/* Memory load and stores */
-static inline target_ulong addr_add(target_ulong addr, target_long arg)
+static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr,
+ target_long arg)
{
#if defined(TARGET_PPC64)
if (!msr_sf) {
@@ -45,44 +44,44 @@ static inline target_ulong addr_add(target_ulong addr, target_long arg)
}
}
-void helper_lmw(target_ulong addr, uint32_t reg)
+void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
{
for (; reg < 32; reg++) {
if (msr_le) {
- env->gpr[reg] = bswap32(ldl(addr));
+ env->gpr[reg] = bswap32(cpu_ldl_data(env, addr));
} else {
- env->gpr[reg] = ldl(addr);
+ env->gpr[reg] = cpu_ldl_data(env, addr);
}
- addr = addr_add(addr, 4);
+ addr = addr_add(env, addr, 4);
}
}
-void helper_stmw(target_ulong addr, uint32_t reg)
+void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
{
for (; reg < 32; reg++) {
if (msr_le) {
- stl(addr, bswap32((uint32_t)env->gpr[reg]));
+ cpu_stl_data(env, addr, bswap32((uint32_t)env->gpr[reg]));
} else {
- stl(addr, (uint32_t)env->gpr[reg]);
+ cpu_stl_data(env, addr, (uint32_t)env->gpr[reg]);
}
- addr = addr_add(addr, 4);
+ addr = addr_add(env, addr, 4);
}
}
-void helper_lsw(target_ulong addr, uint32_t nb, uint32_t reg)
+void helper_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, uint32_t reg)
{
int sh;
for (; nb > 3; nb -= 4) {
- env->gpr[reg] = ldl(addr);
+ env->gpr[reg] = cpu_ldl_data(env, addr);
reg = (reg + 1) % 32;
- addr = addr_add(addr, 4);
+ addr = addr_add(env, addr, 4);
}
if (unlikely(nb > 0)) {
env->gpr[reg] = 0;
for (sh = 24; nb > 0; nb--, sh -= 8) {
- env->gpr[reg] |= ldub(addr) << sh;
- addr = addr_add(addr, 1);
+ env->gpr[reg] |= cpu_ldub_data(env, addr) << sh;
+ addr = addr_add(env, addr, 1);
}
}
}
@@ -91,7 +90,8 @@ void helper_lsw(target_ulong addr, uint32_t nb, uint32_t reg)
* In an other hand, IBM says this is valid, but rA won't be loaded.
* For now, I'll follow the spec...
*/
-void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb)
+void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
+ uint32_t ra, uint32_t rb)
{
if (likely(xer_bc != 0)) {
if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
@@ -100,56 +100,57 @@ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb)
POWERPC_EXCP_INVAL |
POWERPC_EXCP_INVAL_LSWX);
} else {
- helper_lsw(addr, xer_bc, reg);
+ helper_lsw(env, addr, xer_bc, reg);
}
}
}
-void helper_stsw(target_ulong addr, uint32_t nb, uint32_t reg)
+void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
+ uint32_t reg)
{
int sh;
for (; nb > 3; nb -= 4) {
- stl(addr, env->gpr[reg]);
+ cpu_stl_data(env, addr, env->gpr[reg]);
reg = (reg + 1) % 32;
- addr = addr_add(addr, 4);
+ addr = addr_add(env, addr, 4);
}
if (unlikely(nb > 0)) {
for (sh = 24; nb > 0; nb--, sh -= 8) {
- stb(addr, (env->gpr[reg] >> sh) & 0xFF);
- addr = addr_add(addr, 1);
+ cpu_stb_data(env, addr, (env->gpr[reg] >> sh) & 0xFF);
+ addr = addr_add(env, addr, 1);
}
}
}
-static void do_dcbz(target_ulong addr, int dcache_line_size)
+static void do_dcbz(CPUPPCState *env, target_ulong addr, int dcache_line_size)
{
int i;
addr &= ~(dcache_line_size - 1);
for (i = 0; i < dcache_line_size; i += 4) {
- stl(addr + i, 0);
+ cpu_stl_data(env, addr + i, 0);
}
if (env->reserve_addr == addr) {
env->reserve_addr = (target_ulong)-1ULL;
}
}
-void helper_dcbz(target_ulong addr)
+void helper_dcbz(CPUPPCState *env, target_ulong addr)
{
- do_dcbz(addr, env->dcache_line_size);
+ do_dcbz(env, addr, env->dcache_line_size);
}
-void helper_dcbz_970(target_ulong addr)
+void helper_dcbz_970(CPUPPCState *env, target_ulong addr)
{
if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
- do_dcbz(addr, 32);
+ do_dcbz(env, addr, 32);
} else {
- do_dcbz(addr, env->dcache_line_size);
+ do_dcbz(env, addr, env->dcache_line_size);
}
}
-void helper_icbi(target_ulong addr)
+void helper_icbi(CPUPPCState *env, target_ulong addr)
{
addr &= ~(env->dcache_line_size - 1);
/* Invalidate one cache line :
@@ -157,19 +158,19 @@ void helper_icbi(target_ulong addr)
* (not a fetch) by the MMU. To be sure it will be so,
* do the load "by hand".
*/
- ldl(addr);
+ cpu_ldl_data(env, addr);
}
/* XXX: to be tested */
-target_ulong helper_lscbx(target_ulong addr, uint32_t reg, uint32_t ra,
- uint32_t rb)
+target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
+ uint32_t ra, uint32_t rb)
{
int i, c, d;
d = 24;
for (i = 0; i < xer_bc; i++) {
- c = ldub(addr);
- addr = addr_add(addr, 1);
+ c = cpu_ldub_data(env, addr);
+ addr = addr_add(env, addr, 1);
/* ra (if not 0) and rb are never modified */
if (likely(reg != rb && (ra == 0 || reg != ra))) {
env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d);
@@ -199,7 +200,8 @@ target_ulong helper_lscbx(target_ulong addr, uint32_t reg, uint32_t ra,
#endif
#define LVE(name, access, swap, element) \
- void helper_##name(ppc_avr_t *r, target_ulong addr) \
+ void helper_##name(CPUPPCState *env, ppc_avr_t *r, \
+ target_ulong addr) \
{ \
size_t n_elems = ARRAY_SIZE(r->element); \
int adjust = HI_IDX*(n_elems - 1); \
@@ -208,21 +210,22 @@ target_ulong helper_lscbx(target_ulong addr, uint32_t reg, uint32_t ra,
\
if (msr_le) { \
r->element[LO_IDX ? index : (adjust - index)] = \
- swap(access(addr)); \
+ swap(access(env, addr)); \
} else { \
r->element[LO_IDX ? index : (adjust - index)] = \
- access(addr); \
+ access(env, addr); \
} \
}
#define I(x) (x)
-LVE(lvebx, ldub, I, u8)
-LVE(lvehx, lduw, bswap16, u16)
-LVE(lvewx, ldl, bswap32, u32)
+LVE(lvebx, cpu_ldub_data, I, u8)
+LVE(lvehx, cpu_lduw_data, bswap16, u16)
+LVE(lvewx, cpu_ldl_data, bswap32, u32)
#undef I
#undef LVE
#define STVE(name, access, swap, element) \
- void helper_##name(ppc_avr_t *r, target_ulong addr) \
+ void helper_##name(CPUPPCState *env, ppc_avr_t *r, \
+ target_ulong addr) \
{ \
size_t n_elems = ARRAY_SIZE(r->element); \
int adjust = HI_IDX * (n_elems - 1); \
@@ -230,15 +233,17 @@ LVE(lvewx, ldl, bswap32, u32)
int index = (addr & 0xf) >> sh; \
\
if (msr_le) { \
- access(addr, swap(r->element[LO_IDX ? index : (adjust - index)])); \
+ access(env, addr, swap(r->element[LO_IDX ? index : \
+ (adjust - index)])); \
} else { \
- access(addr, r->element[LO_IDX ? index : (adjust - index)]); \
+ access(env, addr, r->element[LO_IDX ? index : \
+ (adjust - index)]); \
} \
}
#define I(x) (x)
-STVE(stvebx, stb, I, u8)
-STVE(stvehx, stw, bswap16, u16)
-STVE(stvewx, stl, bswap32, u32)
+STVE(stvebx, cpu_stb_data, I, u8)
+STVE(stvehx, cpu_stw_data, bswap16, u16)
+STVE(stvewx, cpu_stl_data, bswap32, u32)
#undef I
#undef LVE
@@ -267,15 +272,12 @@ STVE(stvewx, stl, bswap32, u32)
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
-void tlb_fill(CPUPPCState *env1, target_ulong addr, int is_write, int mmu_idx,
+void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
TranslationBlock *tb;
- CPUPPCState *saved_env;
int ret;
- saved_env = env;
- env = env1;
ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (unlikely(ret != 0)) {
if (likely(retaddr)) {
@@ -289,6 +291,5 @@ void tlb_fill(CPUPPCState *env1, target_ulong addr, int is_write, int mmu_idx,
}
helper_raise_exception_err(env, env->exception_index, env->error_code);
}
- env = saved_env;
}
#endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bcc993313d..9103fd5776 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2989,7 +2989,7 @@ static void gen_lmw(DisasContext *ctx)
t0 = tcg_temp_new();
t1 = tcg_const_i32(rD(ctx->opcode));
gen_addr_imm_index(ctx, t0, 0);
- gen_helper_lmw(t0, t1);
+ gen_helper_lmw(cpu_env, t0, t1);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
}
@@ -3005,7 +3005,7 @@ static void gen_stmw(DisasContext *ctx)
t0 = tcg_temp_new();
t1 = tcg_const_i32(rS(ctx->opcode));
gen_addr_imm_index(ctx, t0, 0);
- gen_helper_stmw(t0, t1);
+ gen_helper_stmw(cpu_env, t0, t1);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
}
@@ -3043,7 +3043,7 @@ static void gen_lswi(DisasContext *ctx)
gen_addr_register(ctx, t0);
t1 = tcg_const_i32(nb);
t2 = tcg_const_i32(start);
- gen_helper_lsw(t0, t1, t2);
+ gen_helper_lsw(cpu_env, t0, t1, t2);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
@@ -3062,7 +3062,7 @@ static void gen_lswx(DisasContext *ctx)
t1 = tcg_const_i32(rD(ctx->opcode));
t2 = tcg_const_i32(rA(ctx->opcode));
t3 = tcg_const_i32(rB(ctx->opcode));
- gen_helper_lswx(t0, t1, t2, t3);
+ gen_helper_lswx(cpu_env, t0, t1, t2, t3);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
@@ -3084,7 +3084,7 @@ static void gen_stswi(DisasContext *ctx)
nb = 32;
t1 = tcg_const_i32(nb);
t2 = tcg_const_i32(rS(ctx->opcode));
- gen_helper_stsw(t0, t1, t2);
+ gen_helper_stsw(cpu_env, t0, t1, t2);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
@@ -3104,7 +3104,7 @@ static void gen_stswx(DisasContext *ctx)
tcg_gen_trunc_tl_i32(t1, cpu_xer);
tcg_gen_andi_i32(t1, t1, 0x7F);
t2 = tcg_const_i32(rS(ctx->opcode));
- gen_helper_stsw(t0, t1, t2);
+ gen_helper_stsw(cpu_env, t0, t1, t2);
tcg_temp_free(t0);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
@@ -4116,7 +4116,7 @@ static void gen_dcbz(DisasContext *ctx)
gen_update_nip(ctx, ctx->nip - 4);
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
- gen_helper_dcbz(t0);
+ gen_helper_dcbz(cpu_env, t0);
tcg_temp_free(t0);
}
@@ -4129,9 +4129,9 @@ static void gen_dcbz_970(DisasContext *ctx)
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
if (ctx->opcode & 0x00200000)
- gen_helper_dcbz(t0);
+ gen_helper_dcbz(cpu_env, t0);
else
- gen_helper_dcbz_970(t0);
+ gen_helper_dcbz_970(cpu_env, t0);
tcg_temp_free(t0);
}
@@ -4171,7 +4171,7 @@ static void gen_icbi(DisasContext *ctx)
gen_update_nip(ctx, ctx->nip - 4);
t0 = tcg_temp_new();
gen_addr_reg_index(ctx, t0);
- gen_helper_icbi(t0);
+ gen_helper_icbi(cpu_env, t0);
tcg_temp_free(t0);
}
@@ -4663,7 +4663,7 @@ static void gen_lscbx(DisasContext *ctx)
gen_addr_reg_index(ctx, t0);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- gen_helper_lscbx(t0, t0, t1, t2, t3);
+ gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t3);
@@ -6387,7 +6387,7 @@ static void gen_lve##name(DisasContext *ctx) \
EA = tcg_temp_new(); \
gen_addr_reg_index(ctx, EA); \
rs = gen_avr_ptr(rS(ctx->opcode)); \
- gen_helper_lve##name (rs, EA); \
+ gen_helper_lve##name(cpu_env, rs, EA); \
tcg_temp_free(EA); \
tcg_temp_free_ptr(rs); \
}
@@ -6405,7 +6405,7 @@ static void gen_stve##name(DisasContext *ctx) \
EA = tcg_temp_new(); \
gen_addr_reg_index(ctx, EA); \
rs = gen_avr_ptr(rS(ctx->opcode)); \
- gen_helper_stve##name (rs, EA); \
+ gen_helper_stve##name(cpu_env, rs, EA); \
tcg_temp_free(EA); \
tcg_temp_free_ptr(rs); \
}
@@ -9683,9 +9683,9 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
if (unlikely(ctx.le_mode)) {
- ctx.opcode = bswap32(ldl_code(ctx.nip));
+ ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
} else {
- ctx.opcode = ldl_code(ctx.nip);
+ ctx.opcode = cpu_ldl_code(env, ctx.nip);
}
LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),