From 2f5a189caefe2ecbd32faf528a0fbf8c915dfa08 Mon Sep 17 00:00:00 2001 From: Blue Swirl Date: Wed, 30 May 2012 04:23:40 +0000 Subject: [PATCH] ppc: Move load and store helpers, switch to AREG0 free mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Alexander Graf Signed-off-by: Andreas Färber Signed-off-by: Alexander Graf --- configure | 2 +- cpu-all.h | 9 ++ target-ppc/Makefile.objs | 7 +- target-ppc/excp_helper.c | 3 +- target-ppc/helper.h | 30 +++---- target-ppc/{op_helper.c => mem_helper.c} | 109 ++++++++++++----------- target-ppc/translate.c | 30 +++---- 7 files changed, 100 insertions(+), 90 deletions(-) rename target-ppc/{op_helper.c => mem_helper.c} (68%) diff --git a/configure b/configure index b68c0ca194..6128ba7522 100755 --- a/configure +++ b/configure @@ -3679,7 +3679,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" case "$target_arch2" in - alpha | sparc* | xtensa*) + alpha | sparc* | xtensa* | ppc*) echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak ;; esac diff --git a/cpu-all.h b/cpu-all.h index 50c8b62583..9dc249a165 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -291,6 +291,15 @@ extern unsigned long reserved_va; #define stfl_kernel(p, v) stfl_raw(p, v) #define stfq_kernel(p, vt) stfq_raw(p, v) +#ifdef CONFIG_TCG_PASS_AREG0 +#define cpu_ldub_data(env, addr) ldub_raw(addr) +#define cpu_lduw_data(env, addr) lduw_raw(addr) +#define cpu_ldl_data(env, addr) ldl_raw(addr) + +#define cpu_stb_data(env, addr, data) stb_raw(addr, data) +#define cpu_stw_data(env, addr, data) stw_raw(addr, data) +#define cpu_stl_data(env, addr, data) stl_raw(addr, data) +#endif #endif /* defined(CONFIG_USER_ONLY) */ /* page related stuff */ 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 similarity index 68% rename from target-ppc/op_helper.c rename to 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 . */ -#include #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),