diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-07 13:40:29 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-07 13:40:29 +0000 |
commit | 45d827d2d70927b3759a3ca640d8c950f8c74726 (patch) | |
tree | a319681283dace6cb0cf0df53228cd13ec14f850 | |
parent | fa0d32c4e4486ed7d4caf60bcf14306d0c7406ea (diff) |
target-ppc: convert SPR accesses to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5910 c046a42c-6fe2-441c-8c8c-71466251a162
-rwxr-xr-x | configure | 8 | ||||
-rw-r--r-- | target-ppc/cpu.h | 41 | ||||
-rw-r--r-- | target-ppc/exec.h | 13 | ||||
-rw-r--r-- | target-ppc/helper.c | 46 | ||||
-rw-r--r-- | target-ppc/helper.h | 41 | ||||
-rw-r--r-- | target-ppc/op.c | 320 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 227 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 38 | ||||
-rw-r--r-- | target-ppc/translate.c | 22 | ||||
-rw-r--r-- | target-ppc/translate_init.c | 309 |
10 files changed, 425 insertions, 640 deletions
@@ -1605,39 +1605,31 @@ case "$target_cpu" in ;; ppc) echo "TARGET_ARCH=ppc" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"ppc\"" >> $config_h echo "#define TARGET_PPC 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppcemb) echo "TARGET_ARCH=ppcemb" >> $config_mak echo "TARGET_ABI_DIR=ppc" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h echo "#define TARGET_PPC 1" >> $config_h echo "#define TARGET_PPCEMB 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppc64) echo "TARGET_ARCH=ppc64" >> $config_mak echo "TARGET_ABI_DIR=ppc" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"ppc64\"" >> $config_h echo "#define TARGET_PPC 1" >> $config_h echo "#define TARGET_PPC64 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppc64abi32) echo "TARGET_ARCH=ppc64" >> $config_mak echo "TARGET_ABI_DIR=ppc" >> $config_mak echo "TARGET_ARCH2=ppc64abi32" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"ppc64\"" >> $config_h echo "#define TARGET_PPC 1" >> $config_h echo "#define TARGET_PPC64 1" >> $config_h echo "#define TARGET_ABI32 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; sh4|sh4eb) echo "TARGET_ARCH=sh4" >> $config_mak diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index a9bd0098cd..6abd104b24 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -295,13 +295,13 @@ typedef union ppc_tlb_t ppc_tlb_t; /* SPR access micro-ops generations callbacks */ struct ppc_spr_t { - void (*uea_read)(void *opaque, int spr_num); - void (*uea_write)(void *opaque, int spr_num); + void (*uea_read)(void *opaque, int gpr_num, int spr_num); + void (*uea_write)(void *opaque, int spr_num, int gpr_num); #if !defined(CONFIG_USER_ONLY) - void (*oea_read)(void *opaque, int spr_num); - void (*oea_write)(void *opaque, int spr_num); - void (*hea_read)(void *opaque, int spr_num); - void (*hea_write)(void *opaque, int spr_num); + void (*oea_read)(void *opaque, int gpr_num, int spr_num); + void (*oea_write)(void *opaque, int spr_num, int gpr_num); + void (*hea_read)(void *opaque, int gpr_num, int spr_num); + void (*hea_write)(void *opaque, int spr_num, int gpr_num); #endif const char *name; }; @@ -529,10 +529,6 @@ struct CPUPPCState { /* First are the most commonly used resources * during translated code execution */ -#if TARGET_LONG_BITS > HOST_LONG_BITS - target_ulong t0; -#endif - /* general purpose registers */ target_ulong gpr[32]; #if !defined(TARGET_PPC64) @@ -689,28 +685,19 @@ void ppc_hw_interrupt (CPUPPCState *env); void dump_stack (CPUPPCState *env); #if !defined(CONFIG_USER_ONLY) -target_ulong do_load_ibatu (CPUPPCState *env, int nr); -target_ulong do_load_ibatl (CPUPPCState *env, int nr); -void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value); -void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value); -target_ulong do_load_dbatu (CPUPPCState *env, int nr); -target_ulong do_load_dbatl (CPUPPCState *env, int nr); -void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value); -void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value); -void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value); -void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value); -target_ulong do_load_sdr1 (CPUPPCState *env); -void do_store_sdr1 (CPUPPCState *env, target_ulong value); +void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value); +void ppc_store_sdr1 (CPUPPCState *env, target_ulong value); #if defined(TARGET_PPC64) -target_ulong ppc_load_asr (CPUPPCState *env); void ppc_store_asr (CPUPPCState *env, target_ulong value); target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr); void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs); #endif /* defined(TARGET_PPC64) */ -#if 0 // Unused -target_ulong do_load_sr (CPUPPCState *env, int srnum); -#endif -void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); +void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value); #endif /* !defined(CONFIG_USER_ONLY) */ void ppc_store_msr (CPUPPCState *env, target_ulong value); diff --git a/target-ppc/exec.h b/target-ppc/exec.h index cc7c924ac5..d8b447e674 100644 --- a/target-ppc/exec.h +++ b/target-ppc/exec.h @@ -32,20 +32,7 @@ #define USE_PRECISE_EMULATION 0 register struct CPUPPCState *env asm(AREG0); -#if TARGET_LONG_BITS > HOST_LONG_BITS -/* no registers can be used */ -#define T0 (env->t0) #define TDX "%016" PRIx64 -#else -register target_ulong T0 asm(AREG1); -#define TDX "%016lx" -#endif - -#if defined (DEBUG_OP) -# define RETURN() __asm__ __volatile__("nop" : : : "memory"); -#else -# define RETURN() __asm__ __volatile__("" : : : "memory"); -#endif #if !defined(CONFIG_USER_ONLY) #include "softmmu_exec.h" diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 2678dd61e2..6bffa0638f 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -1800,17 +1800,7 @@ static always_inline void dump_store_bat (CPUPPCState *env, char ID, #endif } -target_ulong do_load_ibatu (CPUPPCState *env, int nr) -{ - return env->IBAT[0][nr]; -} - -target_ulong do_load_ibatl (CPUPPCState *env, int nr) -{ - return env->IBAT[1][nr]; -} - -void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_ibatu (CPUPPCState *env, int nr, target_ulong value) { target_ulong mask; @@ -1836,23 +1826,13 @@ void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value) } } -void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_ibatl (CPUPPCState *env, int nr, target_ulong value) { dump_store_bat(env, 'I', 1, nr, value); env->IBAT[1][nr] = value; } -target_ulong do_load_dbatu (CPUPPCState *env, int nr) -{ - return env->DBAT[0][nr]; -} - -target_ulong do_load_dbatl (CPUPPCState *env, int nr) -{ - return env->DBAT[1][nr]; -} - -void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_dbatu (CPUPPCState *env, int nr, target_ulong value) { target_ulong mask; @@ -1878,13 +1858,13 @@ void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value) } } -void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_dbatl (CPUPPCState *env, int nr, target_ulong value) { dump_store_bat(env, 'D', 1, nr, value); env->DBAT[1][nr] = value; } -void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value) { target_ulong mask; int do_inval; @@ -1921,7 +1901,7 @@ void do_store_ibatu_601 (CPUPPCState *env, int nr, target_ulong value) } } -void do_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value) +void ppc_store_ibatl_601 (CPUPPCState *env, int nr, target_ulong value) { target_ulong mask; int do_inval; @@ -2075,11 +2055,6 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) /*****************************************************************************/ /* Special registers manipulation */ #if defined(TARGET_PPC64) -target_ulong ppc_load_asr (CPUPPCState *env) -{ - return env->asr; -} - void ppc_store_asr (CPUPPCState *env, target_ulong value) { if (env->asr != value) { @@ -2089,12 +2064,7 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value) } #endif -target_ulong do_load_sdr1 (CPUPPCState *env) -{ - return env->sdr1; -} - -void do_store_sdr1 (CPUPPCState *env, target_ulong value) +void ppc_store_sdr1 (CPUPPCState *env, target_ulong value) { #if defined (DEBUG_MMU) if (loglevel != 0) { @@ -2110,7 +2080,7 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) } } -void do_store_sr (CPUPPCState *env, int srnum, target_ulong value) +void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value) { #if defined (DEBUG_MMU) if (loglevel != 0) { diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 5b2607853a..b5985a67ed 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -184,7 +184,7 @@ DEF_HELPER_0(slbia, void) DEF_HELPER_1(slbie, void, tl) #endif DEF_HELPER_1(load_sr, tl, tl); -DEF_HELPER_2(store_sr, void, tl, tl); +DEF_HELPER_2(store_sr, void, tl, tl) DEF_HELPER_1(602_mfrom, tl, tl) #endif @@ -200,6 +200,43 @@ DEF_HELPER_2(divs, tl, tl, tl) DEF_HELPER_2(divso, tl, tl, tl) DEF_HELPER_1(load_dcr, tl, tl); -DEF_HELPER_2(store_dcr, void, tl, tl); +DEF_HELPER_2(store_dcr, void, tl, tl) + +DEF_HELPER_1(load_dump_spr, void, i32) +DEF_HELPER_1(store_dump_spr, void, i32) +DEF_HELPER_0(load_tbl, tl) +DEF_HELPER_0(load_tbu, tl) +DEF_HELPER_0(load_atbl, tl) +DEF_HELPER_0(load_atbu, tl) +DEF_HELPER_0(load_601_rtcl, tl) +DEF_HELPER_0(load_601_rtcu, tl) +#if !defined(CONFIG_USER_ONLY) +#if defined(TARGET_PPC64) +DEF_HELPER_1(store_asr, void, tl) +#endif +DEF_HELPER_1(store_sdr1, void, tl) +DEF_HELPER_1(store_tbl, void, tl) +DEF_HELPER_1(store_tbu, void, tl) +DEF_HELPER_1(store_atbl, void, tl) +DEF_HELPER_1(store_atbu, void, tl) +DEF_HELPER_1(store_601_rtcl, void, tl) +DEF_HELPER_1(store_601_rtcu, void, tl) +DEF_HELPER_0(load_decr, tl) +DEF_HELPER_1(store_decr, void, tl) +DEF_HELPER_1(store_hid0_601, void, tl) +DEF_HELPER_2(store_403_pbr, void, i32, tl) +DEF_HELPER_0(load_40x_pit, tl) +DEF_HELPER_1(store_40x_pit, void, tl) +DEF_HELPER_1(store_40x_dbcr0, void, tl) +DEF_HELPER_1(store_40x_sler, void, tl) +DEF_HELPER_1(store_booke_tcr, void, tl) +DEF_HELPER_1(store_booke_tsr, void, tl) +DEF_HELPER_2(store_ibatl, void, i32, tl) +DEF_HELPER_2(store_ibatu, void, i32, tl) +DEF_HELPER_2(store_dbatl, void, i32, tl) +DEF_HELPER_2(store_dbatu, void, i32, tl) +DEF_HELPER_2(store_601_batl, void, i32, tl) +DEF_HELPER_2(store_601_batu, void, i32, tl) +#endif #include "def-helper.h" diff --git a/target-ppc/op.c b/target-ppc/op.c deleted file mode 100644 index 868db83779..0000000000 --- a/target-ppc/op.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * PowerPC emulation micro-operations for qemu. - * - * Copyright (c) 2003-2007 Jocelyn Mayer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//#define DEBUG_OP - -#include "config.h" -#include "exec.h" -#include "host-utils.h" -#include "helper_regs.h" -#include "op_helper.h" - -#if !defined(CONFIG_USER_ONLY) -void OPPROTO op_load_sdr1 (void) -{ - T0 = env->sdr1; - RETURN(); -} - -void OPPROTO op_store_sdr1 (void) -{ - do_store_sdr1(env, T0); - RETURN(); -} - -#if defined (TARGET_PPC64) -void OPPROTO op_load_asr (void) -{ - T0 = env->asr; - RETURN(); -} - -void OPPROTO op_store_asr (void) -{ - ppc_store_asr(env, T0); - RETURN(); -} -#endif -#endif - -/* SPR */ -void OPPROTO op_load_spr (void) -{ - T0 = env->spr[PARAM1]; - RETURN(); -} - -void OPPROTO op_store_spr (void) -{ - env->spr[PARAM1] = T0; - RETURN(); -} - -void OPPROTO op_load_dump_spr (void) -{ - T0 = ppc_load_dump_spr(PARAM1); - RETURN(); -} - -void OPPROTO op_store_dump_spr (void) -{ - ppc_store_dump_spr(PARAM1, T0); - RETURN(); -} - -void OPPROTO op_mask_spr (void) -{ - env->spr[PARAM1] &= ~T0; - RETURN(); -} - -void OPPROTO op_load_tbl (void) -{ - T0 = cpu_ppc_load_tbl(env); - RETURN(); -} - -void OPPROTO op_load_tbu (void) -{ - T0 = cpu_ppc_load_tbu(env); - RETURN(); -} - -void OPPROTO op_load_atbl (void) -{ - T0 = cpu_ppc_load_atbl(env); - RETURN(); -} - -void OPPROTO op_load_atbu (void) -{ - T0 = cpu_ppc_load_atbu(env); - RETURN(); -} - -#if !defined(CONFIG_USER_ONLY) -void OPPROTO op_store_tbl (void) -{ - cpu_ppc_store_tbl(env, T0); - RETURN(); -} - -void OPPROTO op_store_tbu (void) -{ - cpu_ppc_store_tbu(env, T0); - RETURN(); -} - -void OPPROTO op_store_atbl (void) -{ - cpu_ppc_store_atbl(env, T0); - RETURN(); -} - -void OPPROTO op_store_atbu (void) -{ - cpu_ppc_store_atbu(env, T0); - RETURN(); -} - -void OPPROTO op_load_decr (void) -{ - T0 = cpu_ppc_load_decr(env); - RETURN(); -} - -void OPPROTO op_store_decr (void) -{ - cpu_ppc_store_decr(env, T0); - RETURN(); -} - -void OPPROTO op_load_ibat (void) -{ - T0 = env->IBAT[PARAM1][PARAM2]; - RETURN(); -} - -void OPPROTO op_store_ibatu (void) -{ - do_store_ibatu(env, PARAM1, T0); - RETURN(); -} - -void OPPROTO op_store_ibatl (void) -{ -#if 1 - env->IBAT[1][PARAM1] = T0; -#else - do_store_ibatl(env, PARAM1, T0); -#endif - RETURN(); -} - -void OPPROTO op_load_dbat (void) -{ - T0 = env->DBAT[PARAM1][PARAM2]; - RETURN(); -} - -void OPPROTO op_store_dbatu (void) -{ - do_store_dbatu(env, PARAM1, T0); - RETURN(); -} - -void OPPROTO op_store_dbatl (void) -{ -#if 1 - env->DBAT[1][PARAM1] = T0; -#else - do_store_dbatl(env, PARAM1, T0); -#endif - RETURN(); -} -#endif /* !defined(CONFIG_USER_ONLY) */ - -/* Return from interrupt */ -#if !defined(CONFIG_USER_ONLY) -/* Exception vectors */ -void OPPROTO op_store_excp_prefix (void) -{ - T0 &= env->ivpr_mask; - env->excp_prefix = T0; - RETURN(); -} - -void OPPROTO op_store_excp_vector (void) -{ - T0 &= env->ivor_mask; - env->excp_vectors[PARAM1] = T0; - RETURN(); -} -#endif - -/* 601 specific */ -void OPPROTO op_load_601_rtcl (void) -{ - T0 = cpu_ppc601_load_rtcl(env); - RETURN(); -} - -void OPPROTO op_load_601_rtcu (void) -{ - T0 = cpu_ppc601_load_rtcu(env); - RETURN(); -} - -#if !defined(CONFIG_USER_ONLY) -void OPPROTO op_store_601_rtcl (void) -{ - cpu_ppc601_store_rtcl(env, T0); - RETURN(); -} - -void OPPROTO op_store_601_rtcu (void) -{ - cpu_ppc601_store_rtcu(env, T0); - RETURN(); -} - -void OPPROTO op_store_hid0_601 (void) -{ - do_store_hid0_601(); - RETURN(); -} - -void OPPROTO op_load_601_bat (void) -{ - T0 = env->IBAT[PARAM1][PARAM2]; - RETURN(); -} - -void OPPROTO op_store_601_batl (void) -{ - do_store_ibatl_601(env, PARAM1, T0); - RETURN(); -} - -void OPPROTO op_store_601_batu (void) -{ - do_store_ibatu_601(env, PARAM1, T0); - RETURN(); -} -#endif /* !defined(CONFIG_USER_ONLY) */ - -/* SPR micro-ops */ -/* 440 specific */ -#if !defined(CONFIG_USER_ONLY) -void OPPROTO op_store_pir (void) -{ - env->spr[SPR_PIR] = T0 & 0x0000000FUL; - RETURN(); -} - -void OPPROTO op_load_403_pb (void) -{ - do_load_403_pb(PARAM1); - RETURN(); -} - -void OPPROTO op_store_403_pb (void) -{ - do_store_403_pb(PARAM1); - RETURN(); -} - -void OPPROTO op_load_40x_pit (void) -{ - T0 = load_40x_pit(env); - RETURN(); -} - -void OPPROTO op_store_40x_pit (void) -{ - store_40x_pit(env, T0); - RETURN(); -} - -void OPPROTO op_store_40x_dbcr0 (void) -{ - store_40x_dbcr0(env, T0); - RETURN(); -} - -void OPPROTO op_store_40x_sler (void) -{ - store_40x_sler(env, T0); - RETURN(); -} - -void OPPROTO op_store_booke_tcr (void) -{ - store_booke_tcr(env, T0); - RETURN(); -} - -void OPPROTO op_store_booke_tsr (void) -{ - store_booke_tsr(env, T0); - RETURN(); -} -#endif /* !defined(CONFIG_USER_ONLY) */ - diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index cc760d1327..fd635a36d0 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -22,7 +22,6 @@ #include "helper.h" #include "helper_regs.h" -#include "op_helper.h" //#define DEBUG_OP //#define DEBUG_EXCEPTIONS @@ -65,25 +64,196 @@ void helper_store_cr (target_ulong val, uint32_t mask) } } -target_ulong ppc_load_dump_spr (int sprn) +/*****************************************************************************/ +/* SPR accesses */ +void helper_load_dump_spr (uint32_t sprn) { if (loglevel != 0) { fprintf(logfile, "Read SPR %d %03x => " ADDRX "\n", sprn, sprn, env->spr[sprn]); } - - return env->spr[sprn]; } -void ppc_store_dump_spr (int sprn, target_ulong val) +void helper_store_dump_spr (uint32_t sprn) { if (loglevel != 0) { - fprintf(logfile, "Write SPR %d %03x => " ADDRX " <= " ADDRX "\n", - sprn, sprn, env->spr[sprn], val); + fprintf(logfile, "Write SPR %d %03x <= " ADDRX "\n", + sprn, sprn, env->spr[sprn]); + } +} + +target_ulong helper_load_tbl (void) +{ + return cpu_ppc_load_tbl(env); +} + +target_ulong helper_load_tbu (void) +{ + return cpu_ppc_load_tbu(env); +} + +target_ulong helper_load_atbl (void) +{ + return cpu_ppc_load_atbl(env); +} + +target_ulong helper_load_atbu (void) +{ + return cpu_ppc_load_atbu(env); +} + +target_ulong helper_load_601_rtcl (void) +{ + return cpu_ppc601_load_rtcl(env); +} + +target_ulong helper_load_601_rtcu (void) +{ + return cpu_ppc601_load_rtcu(env); +} + +#if !defined(CONFIG_USER_ONLY) +#if defined (TARGET_PPC64) +void helper_store_asr (target_ulong val) +{ + ppc_store_asr(env, val); +} +#endif + +void helper_store_sdr1 (target_ulong val) +{ + ppc_store_sdr1(env, val); +} + +void helper_store_tbl (target_ulong val) +{ + cpu_ppc_store_tbl(env, val); +} + +void helper_store_tbu (target_ulong val) +{ + cpu_ppc_store_tbu(env, val); +} + +void helper_store_atbl (target_ulong val) +{ + cpu_ppc_store_atbl(env, val); +} + +void helper_store_atbu (target_ulong val) +{ + cpu_ppc_store_atbu(env, val); +} + +void helper_store_601_rtcl (target_ulong val) +{ + cpu_ppc601_store_rtcl(env, val); +} + +void helper_store_601_rtcu (target_ulong val) +{ + cpu_ppc601_store_rtcu(env, val); +} + +target_ulong helper_load_decr (void) +{ + return cpu_ppc_load_decr(env); +} + +void helper_store_decr (target_ulong val) +{ + cpu_ppc_store_decr(env, val); +} + +void helper_store_hid0_601 (target_ulong val) +{ + target_ulong hid0; + + hid0 = env->spr[SPR_HID0]; + if ((val ^ hid0) & 0x00000008) { + /* Change current endianness */ + env->hflags &= ~(1 << MSR_LE); + env->hflags_nmsr &= ~(1 << MSR_LE); + env->hflags_nmsr |= (1 << MSR_LE) & (((val >> 3) & 1) << MSR_LE); + env->hflags |= env->hflags_nmsr; + if (loglevel != 0) { + fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n", + __func__, val & 0x8 ? 'l' : 'b', env->hflags); + } } - env->spr[sprn] = val; + env->spr[SPR_HID0] = (uint32_t)val; +} + +void helper_store_403_pbr (uint32_t num, target_ulong value) +{ + if (likely(env->pb[num] != value)) { + env->pb[num] = value; + /* Should be optimized */ + tlb_flush(env, 1); + } +} + +target_ulong helper_load_40x_pit (void) +{ + return load_40x_pit(env); +} + +void helper_store_40x_pit (target_ulong val) +{ + store_40x_pit(env, val); +} + +void helper_store_40x_dbcr0 (target_ulong val) +{ + store_40x_dbcr0(env, val); +} + +void helper_store_40x_sler (target_ulong val) +{ + store_40x_sler(env, val); +} + +void helper_store_booke_tcr (target_ulong val) +{ + store_booke_tcr(env, val); +} + +void helper_store_booke_tsr (target_ulong val) +{ + store_booke_tsr(env, val); +} + +void helper_store_ibatu (uint32_t nr, target_ulong val) +{ + ppc_store_ibatu(env, nr, val); +} + +void helper_store_ibatl (uint32_t nr, target_ulong val) +{ + ppc_store_ibatl(env, nr, val); +} + +void helper_store_dbatu (uint32_t nr, target_ulong val) +{ + ppc_store_dbatu(env, nr, val); } +void helper_store_dbatl (uint32_t nr, target_ulong val) +{ + ppc_store_dbatl(env, nr, val); +} + +void helper_store_601_batl (uint32_t nr, target_ulong val) +{ + ppc_store_ibatl_601(env, nr, val); +} + +void helper_store_601_batu (uint32_t nr, target_ulong val) +{ + ppc_store_ibatu_601(env, nr, val); +} +#endif + /*****************************************************************************/ /* Memory load and stores */ @@ -1678,25 +1848,6 @@ void helper_rfsvc (void) { do_rfi(env->lr, env->ctr, 0x0000FFFF, 0); } - -void do_store_hid0_601 (void) -{ - uint32_t hid0; - - hid0 = env->spr[SPR_HID0]; - if ((T0 ^ hid0) & 0x00000008) { - /* Change current endianness */ - env->hflags &= ~(1 << MSR_LE); - env->hflags_nmsr &= ~(1 << MSR_LE); - env->hflags_nmsr |= (1 << MSR_LE) & (((T0 >> 3) & 1) << MSR_LE); - env->hflags |= env->hflags_nmsr; - if (loglevel != 0) { - fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n", - __func__, T0 & 0x8 ? 'l' : 'b', env->hflags); - } - } - env->spr[SPR_HID0] = T0; -} #endif /*****************************************************************************/ @@ -1709,7 +1860,7 @@ target_ulong helper_602_mfrom (target_ulong arg) if (likely(arg < 602)) { #if defined(USE_MFROM_ROM_TABLE) #include "mfrom_table.c" - return mfrom_ROM_table[T0]; + return mfrom_ROM_table[arg]; #else double d; /* Extremly decomposed: @@ -1747,7 +1898,7 @@ target_ulong helper_load_dcr (target_ulong dcrn) POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); } else if (unlikely(ppc_dcr_read(env->dcr_env, dcrn, &val) != 0)) { if (loglevel != 0) { - fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0); + fprintf(logfile, "DCR read error %d %03x\n", (int)dcrn, (int)dcrn); } raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG); @@ -1765,7 +1916,7 @@ void helper_store_dcr (target_ulong dcrn, target_ulong val) POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); } else if (unlikely(ppc_dcr_write(env->dcr_env, dcrn, val) != 0)) { if (loglevel != 0) { - fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0); + fprintf(logfile, "DCR write error %d %03x\n", (int)dcrn, (int)dcrn); } raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG); @@ -1796,20 +1947,6 @@ void helper_rfmci (void) do_rfi(env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1, ~((target_ulong)0x3FFF0000), 0); } - -void do_load_403_pb (int num) -{ - T0 = env->pb[num]; -} - -void do_store_403_pb (int num) -{ - if (likely(env->pb[num] != T0)) { - env->pb[num] = T0; - /* Should be optimized */ - tlb_flush(env, 1); - } -} #endif /* 440 specific */ @@ -2539,7 +2676,7 @@ target_ulong helper_load_sr (target_ulong sr_num) void helper_store_sr (target_ulong sr_num, target_ulong val) { - do_store_sr(env, sr_num, val); + ppc_store_sr(env, sr_num, val); } /* SLB management */ diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h deleted file mode 100644 index 0fc379a8e1..0000000000 --- a/target-ppc/op_helper.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * PowerPC emulation helpers header for qemu. - * - * Copyright (c) 2003-2007 Jocelyn Mayer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Registers load and stores */ -#if defined(TARGET_PPC64) -void do_store_pri (int prio); -#endif -target_ulong ppc_load_dump_spr (int sprn); -void ppc_store_dump_spr (int sprn, target_ulong val); - -/* Misc */ -/* POWER / PowerPC 601 specific helpers */ -#if !defined(CONFIG_USER_ONLY) -void do_store_hid0_601 (void); -#endif - -/* PowerPC 403 specific helpers */ -#if !defined(CONFIG_USER_ONLY) -void do_load_403_pb (int num); -void do_store_403_pb (int num); -#endif diff --git a/target-ppc/translate.c b/target-ppc/translate.c index b34de137c7..31d7387204 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -38,7 +38,7 @@ #define GDBSTUB_SINGLE_STEP 0x4 /* Include definitions for instructions classes and implementations flags */ -//#define DO_SINGLE_STEP +#define DO_SINGLE_STEP //#define PPC_DEBUG_DISAS //#define DO_PPC_STATISTICS //#define OPTIMIZE_FPRF_UPDATE @@ -71,9 +71,6 @@ static TCGv cpu_reserve; static TCGv_i32 cpu_fpscr; static TCGv_i32 cpu_access_type; -/* dyngen register indexes */ -static TCGv cpu_T[1]; - #include "gen-icount.h" void ppc_translate_init(void) @@ -86,11 +83,6 @@ void ppc_translate_init(void) return; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); -#if TARGET_LONG_BITS > HOST_LONG_BITS - cpu_T[0] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t0), "T0"); -#else - cpu_T[0] = tcg_global_reg_new(TCG_AREG1, "T0"); -#endif p = cpu_reg_names; @@ -3886,7 +3878,7 @@ static void spr_noaccess (void *opaque, int sprn) /* mfspr */ static always_inline void gen_op_mfspr (DisasContext *ctx) { - void (*read_cb)(void *opaque, int sprn); + void (*read_cb)(void *opaque, int gprn, int sprn); uint32_t sprn = SPR(ctx->opcode); #if !defined(CONFIG_USER_ONLY) @@ -3899,8 +3891,7 @@ static always_inline void gen_op_mfspr (DisasContext *ctx) read_cb = ctx->spr_cb[sprn].uea_read; if (likely(read_cb != NULL)) { if (likely(read_cb != SPR_NOACCESS)) { - (*read_cb)(ctx, sprn); - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); + (*read_cb)(ctx, rD(ctx->opcode), sprn); } else { /* Privilege exception */ /* This is a hack to avoid warnings when running Linux: @@ -3972,7 +3963,6 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) GEN_EXCP_PRIVREG(ctx); return; } - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); if (ctx->opcode & 0x00010000) { /* Special form that does not need any synchronisation */ TCGv t0 = tcg_temp_new(); @@ -4004,7 +3994,6 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) GEN_EXCP_PRIVREG(ctx); return; } - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); if (ctx->opcode & 0x00010000) { /* Special form that does not need any synchronisation */ TCGv t0 = tcg_temp_new(); @@ -4041,7 +4030,7 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) /* mtspr */ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) { - void (*write_cb)(void *opaque, int sprn); + void (*write_cb)(void *opaque, int sprn, int gprn); uint32_t sprn = SPR(ctx->opcode); #if !defined(CONFIG_USER_ONLY) @@ -4054,8 +4043,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) write_cb = ctx->spr_cb[sprn].uea_write; if (likely(write_cb != NULL)) { if (likely(write_cb != SPR_NOACCESS)) { - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); - (*write_cb)(ctx, sprn); + (*write_cb)(ctx, sprn, rS(ctx->opcode)); } else { /* Privilege exception */ if (loglevel != 0) { diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 4208f3de8b..33e945c65d 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -66,67 +66,76 @@ PPC_IRQ_INIT_FN(970); /* Generic callbacks: * do nothing but store/retrieve spr value */ -#ifdef PPC_DUMP_SPR_ACCESSES -static void spr_read_generic (void *opaque, int sprn) -{ - gen_op_load_dump_spr(sprn); -} - -static void spr_write_generic (void *opaque, int sprn) +static void spr_read_generic (void *opaque, int gprn, int sprn) { - gen_op_store_dump_spr(sprn); -} -#else -static void spr_read_generic (void *opaque, int sprn) -{ - gen_op_load_spr(sprn); + gen_load_spr(cpu_gpr[gprn], sprn); +#ifdef PPC_DUMP_SPR_ACCESSES + { + TCGv t0 = tcg_const_i32(sprn); + gen_helper_load_dump_spr(t0); + tcg_temp_free_i32(t0); + } +#endif } -static void spr_write_generic (void *opaque, int sprn) +static void spr_write_generic (void *opaque, int sprn, int gprn) { - gen_op_store_spr(sprn); -} + gen_store_spr(sprn, cpu_gpr[gprn]); +#ifdef PPC_DUMP_SPR_ACCESSES + { + TCGv t0 = tcg_const_i32(sprn); + gen_helper_store_dump_spr(t0); + tcg_temp_free_i32(t0); + } #endif +} #if !defined(CONFIG_USER_ONLY) -static void spr_write_clear (void *opaque, int sprn) +static void spr_write_clear (void *opaque, int sprn, int gprn) { - gen_op_mask_spr(sprn); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + gen_load_spr(t0, sprn); + tcg_gen_neg_tl(t1, cpu_gpr[gprn]); + tcg_gen_and_tl(t0, t0, t1); + gen_store_spr(sprn, t0); + tcg_temp_free(t0); + tcg_temp_free(t1); } #endif /* SPR common to all PowerPC */ /* XER */ -static void spr_read_xer (void *opaque, int sprn) +static void spr_read_xer (void *opaque, int gprn, int sprn) { - tcg_gen_mov_tl(cpu_T[0], cpu_xer); + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_xer); } -static void spr_write_xer (void *opaque, int sprn) +static void spr_write_xer (void *opaque, int sprn, int gprn) { - tcg_gen_mov_tl(cpu_xer, cpu_T[0]); + tcg_gen_mov_tl(cpu_xer, cpu_gpr[gprn]); } /* LR */ -static void spr_read_lr (void *opaque, int sprn) +static void spr_read_lr (void *opaque, int gprn, int sprn) { - tcg_gen_mov_tl(cpu_T[0], cpu_lr); + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr); } -static void spr_write_lr (void *opaque, int sprn) +static void spr_write_lr (void *opaque, int sprn, int gprn) { - tcg_gen_mov_tl(cpu_lr, cpu_T[0]); + tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]); } /* CTR */ -static void spr_read_ctr (void *opaque, int sprn) +static void spr_read_ctr (void *opaque, int gprn, int sprn) { - tcg_gen_mov_tl(cpu_T[0], cpu_ctr); + tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr); } -static void spr_write_ctr (void *opaque, int sprn) +static void spr_write_ctr (void *opaque, int sprn, int gprn) { - tcg_gen_mov_tl(cpu_ctr, cpu_T[0]); + tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]); } /* User read access to SPR */ @@ -135,192 +144,208 @@ static void spr_write_ctr (void *opaque, int sprn) /* UPMCx */ /* USIA */ /* UDECR */ -static void spr_read_ureg (void *opaque, int sprn) +static void spr_read_ureg (void *opaque, int gprn, int sprn) { - gen_op_load_spr(sprn + 0x10); + gen_load_spr(cpu_gpr[gprn], sprn + 0x10); } /* SPR common to all non-embedded PowerPC */ /* DECR */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_decr (void *opaque, int sprn) +static void spr_read_decr (void *opaque, int gprn, int sprn) { - gen_op_load_decr(); + gen_helper_load_decr(cpu_gpr[gprn]); } -static void spr_write_decr (void *opaque, int sprn) +static void spr_write_decr (void *opaque, int sprn, int gprn) { - gen_op_store_decr(); + gen_helper_store_decr(cpu_gpr[gprn]); } #endif /* SPR common to all non-embedded PowerPC, except 601 */ /* Time base */ -static void spr_read_tbl (void *opaque, int sprn) +static void spr_read_tbl (void *opaque, int gprn, int sprn) { - gen_op_load_tbl(); + gen_helper_load_tbl(cpu_gpr[gprn]); } -static void spr_read_tbu (void *opaque, int sprn) +static void spr_read_tbu (void *opaque, int gprn, int sprn) { - gen_op_load_tbu(); + gen_helper_load_tbu(cpu_gpr[gprn]); } __attribute__ (( unused )) -static void spr_read_atbl (void *opaque, int sprn) +static void spr_read_atbl (void *opaque, int gprn, int sprn) { - gen_op_load_atbl(); + gen_helper_load_atbl(cpu_gpr[gprn]); } __attribute__ (( unused )) -static void spr_read_atbu (void *opaque, int sprn) +static void spr_read_atbu (void *opaque, int gprn, int sprn) { - gen_op_load_atbu(); + gen_helper_load_atbu(cpu_gpr[gprn]); } #if !defined(CONFIG_USER_ONLY) -static void spr_write_tbl (void *opaque, int sprn) +static void spr_write_tbl (void *opaque, int sprn, int gprn) { - gen_op_store_tbl(); + gen_helper_store_tbl(cpu_gpr[gprn]); } -static void spr_write_tbu (void *opaque, int sprn) +static void spr_write_tbu (void *opaque, int sprn, int gprn) { - gen_op_store_tbu(); + gen_helper_store_tbu(cpu_gpr[gprn]); } __attribute__ (( unused )) -static void spr_write_atbl (void *opaque, int sprn) +static void spr_write_atbl (void *opaque, int sprn, int gprn) { - gen_op_store_atbl(); + gen_helper_store_atbl(cpu_gpr[gprn]); } __attribute__ (( unused )) -static void spr_write_atbu (void *opaque, int sprn) +static void spr_write_atbu (void *opaque, int sprn, int gprn) { - gen_op_store_atbu(); + gen_helper_store_atbu(cpu_gpr[gprn]); } #endif #if !defined(CONFIG_USER_ONLY) /* IBAT0U...IBAT0U */ /* IBAT0L...IBAT7L */ -static void spr_read_ibat (void *opaque, int sprn) +static void spr_read_ibat (void *opaque, int gprn, int sprn) { - gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT0U) / 2); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } -static void spr_read_ibat_h (void *opaque, int sprn) +static void spr_read_ibat_h (void *opaque, int gprn, int sprn) { - gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT4U) / 2); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT4U) / 2])); } -static void spr_write_ibatu (void *opaque, int sprn) +static void spr_write_ibatu (void *opaque, int sprn, int gprn) { - gen_op_store_ibatu((sprn - SPR_IBAT0U) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); + gen_helper_store_ibatu(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_ibatu_h (void *opaque, int sprn) +static void spr_write_ibatu_h (void *opaque, int sprn, int gprn) { - gen_op_store_ibatu((sprn - SPR_IBAT4U) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT4U) / 2); + gen_helper_store_ibatu(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_ibatl (void *opaque, int sprn) +static void spr_write_ibatl (void *opaque, int sprn, int gprn) { - gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2); + gen_helper_store_ibatl(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_ibatl_h (void *opaque, int sprn) +static void spr_write_ibatl_h (void *opaque, int sprn, int gprn) { - gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT4L) / 2); + gen_helper_store_ibatl(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } /* DBAT0U...DBAT7U */ /* DBAT0L...DBAT7L */ -static void spr_read_dbat (void *opaque, int sprn) +static void spr_read_dbat (void *opaque, int gprn, int sprn) { - gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT0U) / 2); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2])); } -static void spr_read_dbat_h (void *opaque, int sprn) +static void spr_read_dbat_h (void *opaque, int gprn, int sprn) { - gen_op_load_dbat(sprn & 1, ((sprn - SPR_DBAT4U) / 2) + 4); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4])); } -static void spr_write_dbatu (void *opaque, int sprn) +static void spr_write_dbatu (void *opaque, int sprn, int gprn) { - gen_op_store_dbatu((sprn - SPR_DBAT0U) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2); + gen_helper_store_dbatu(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_dbatu_h (void *opaque, int sprn) +static void spr_write_dbatu_h (void *opaque, int sprn, int gprn) { - gen_op_store_dbatu(((sprn - SPR_DBAT4U) / 2) + 4); + TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4); + gen_helper_store_dbatu(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_dbatl (void *opaque, int sprn) +static void spr_write_dbatl (void *opaque, int sprn, int gprn) { - gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2); + gen_helper_store_dbatl(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_dbatl_h (void *opaque, int sprn) +static void spr_write_dbatl_h (void *opaque, int sprn, int gprn) { - gen_op_store_dbatl(((sprn - SPR_DBAT4L) / 2) + 4); + TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4); + gen_helper_store_dbatl(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } /* SDR1 */ -static void spr_read_sdr1 (void *opaque, int sprn) +static void spr_read_sdr1 (void *opaque, int gprn, int sprn) { - gen_op_load_sdr1(); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, sdr1)); } -static void spr_write_sdr1 (void *opaque, int sprn) +static void spr_write_sdr1 (void *opaque, int sprn, int gprn) { - gen_op_store_sdr1(); + gen_helper_store_sdr1(cpu_gpr[gprn]); } /* 64 bits PowerPC specific SPRs */ /* ASR */ #if defined(TARGET_PPC64) -static void spr_read_asr (void *opaque, int sprn) +static void spr_read_asr (void *opaque, int gprn, int sprn) { - gen_op_load_asr(); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, asr)); } -static void spr_write_asr (void *opaque, int sprn) +static void spr_write_asr (void *opaque, int sprn, int gprn) { - gen_op_store_asr(); + gen_helper_store_asr(cpu_gpr[gprn]); } #endif #endif /* PowerPC 601 specific registers */ /* RTC */ -static void spr_read_601_rtcl (void *opaque, int sprn) +static void spr_read_601_rtcl (void *opaque, int gprn, int sprn) { - gen_op_load_601_rtcl(); + gen_helper_load_601_rtcl(cpu_gpr[gprn]); } -static void spr_read_601_rtcu (void *opaque, int sprn) +static void spr_read_601_rtcu (void *opaque, int gprn, int sprn) { - gen_op_load_601_rtcu(); + gen_helper_load_601_rtcu(cpu_gpr[gprn]); } #if !defined(CONFIG_USER_ONLY) -static void spr_write_601_rtcu (void *opaque, int sprn) +static void spr_write_601_rtcu (void *opaque, int sprn, int gprn) { - gen_op_store_601_rtcu(); + gen_helper_store_601_rtcu(cpu_gpr[gprn]); } -static void spr_write_601_rtcl (void *opaque, int sprn) +static void spr_write_601_rtcl (void *opaque, int sprn, int gprn) { - gen_op_store_601_rtcl(); + gen_helper_store_601_rtcl(cpu_gpr[gprn]); } -static void spr_write_hid0_601 (void *opaque, int sprn) +static void spr_write_hid0_601 (void *opaque, int sprn, int gprn) { DisasContext *ctx = opaque; - gen_op_store_hid0_601(); + gen_helper_store_hid0_601(cpu_gpr[gprn]); /* Must stop the translation as endianness may have changed */ GEN_STOP(ctx); } @@ -328,96 +353,116 @@ static void spr_write_hid0_601 (void *opaque, int sprn) /* Unified bats */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_601_ubat (void *opaque, int sprn) +static void spr_read_601_ubat (void *opaque, int gprn, int sprn) { - gen_op_load_601_bat(sprn & 1, (sprn - SPR_IBAT0U) / 2); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } -static void spr_write_601_ubatu (void *opaque, int sprn) +static void spr_write_601_ubatu (void *opaque, int sprn, int gprn) { - gen_op_store_601_batu((sprn - SPR_IBAT0U) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); + gen_helper_store_601_batl(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_601_ubatl (void *opaque, int sprn) +static void spr_write_601_ubatl (void *opaque, int sprn, int gprn) { - gen_op_store_601_batl((sprn - SPR_IBAT0L) / 2); + TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); + gen_helper_store_601_batu(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } #endif /* PowerPC 40x specific registers */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_40x_pit (void *opaque, int sprn) +static void spr_read_40x_pit (void *opaque, int gprn, int sprn) { - gen_op_load_40x_pit(); + gen_helper_load_40x_pit(cpu_gpr[gprn]); } -static void spr_write_40x_pit (void *opaque, int sprn) +static void spr_write_40x_pit (void *opaque, int sprn, int gprn) { - gen_op_store_40x_pit(); + gen_helper_store_40x_pit(cpu_gpr[gprn]); } -static void spr_write_40x_dbcr0 (void *opaque, int sprn) +static void spr_write_40x_dbcr0 (void *opaque, int sprn, int gprn) { DisasContext *ctx = opaque; - gen_op_store_40x_dbcr0(); + gen_helper_store_40x_dbcr0(cpu_gpr[gprn]); /* We must stop translation as we may have rebooted */ GEN_STOP(ctx); } -static void spr_write_40x_sler (void *opaque, int sprn) +static void spr_write_40x_sler (void *opaque, int sprn, int gprn) { - gen_op_store_40x_sler(); + gen_helper_store_40x_sler(cpu_gpr[gprn]); } -static void spr_write_booke_tcr (void *opaque, int sprn) +static void spr_write_booke_tcr (void *opaque, int sprn, int gprn) { - gen_op_store_booke_tcr(); + gen_helper_store_booke_tcr(cpu_gpr[gprn]); } -static void spr_write_booke_tsr (void *opaque, int sprn) +static void spr_write_booke_tsr (void *opaque, int sprn, int gprn) { - gen_op_store_booke_tsr(); + gen_helper_store_booke_tsr(cpu_gpr[gprn]); } #endif /* PowerPC 403 specific registers */ /* PBL1 / PBU1 / PBL2 / PBU2 */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_403_pbr (void *opaque, int sprn) +static void spr_read_403_pbr (void *opaque, int gprn, int sprn) { - gen_op_load_403_pb(sprn - SPR_403_PBL1); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, pb[sprn - SPR_403_PBL1])); } -static void spr_write_403_pbr (void *opaque, int sprn) +static void spr_write_403_pbr (void *opaque, int sprn, int gprn) { - gen_op_store_403_pb(sprn - SPR_403_PBL1); + TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1); + gen_helper_store_403_pbr(t0, cpu_gpr[gprn]); + tcg_temp_free_i32(t0); } -static void spr_write_pir (void *opaque, int sprn) +static void spr_write_pir (void *opaque, int sprn, int gprn) { - gen_op_store_pir(); + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF); + gen_store_spr(SPR_PIR, t0); + tcg_temp_free(t0); } #endif #if !defined(CONFIG_USER_ONLY) /* Callback used to write the exception vector base */ -static void spr_write_excp_prefix (void *opaque, int sprn) +static void spr_write_excp_prefix (void *opaque, int sprn, int gprn) { - gen_op_store_excp_prefix(); - gen_op_store_spr(sprn); + TCGv t0 = tcg_temp_new(); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivpr_mask)); + tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_prefix)); + gen_store_spr(sprn, t0); } -static void spr_write_excp_vector (void *opaque, int sprn) +static void spr_write_excp_vector (void *opaque, int sprn, int gprn) { DisasContext *ctx = opaque; if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) { - gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR0); - gen_op_store_spr(sprn); + TCGv t0 = tcg_temp_new(); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivor_mask)); + tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_vectors[sprn - SPR_BOOKE_IVOR0])); + gen_store_spr(sprn, t0); + tcg_temp_free(t0); } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) { - gen_op_store_excp_vector(sprn - SPR_BOOKE_IVOR32 + 32); - gen_op_store_spr(sprn); + TCGv t0 = tcg_temp_new(); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivor_mask)); + tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_vectors[sprn - SPR_BOOKE_IVOR32 + 32])); + gen_store_spr(sprn, t0); + tcg_temp_free(t0); } else { printf("Trying to write an unknown exception vector %d %03x\n", sprn, sprn); @@ -434,16 +479,16 @@ do { \ } while (0) static inline void _spr_register (CPUPPCState *env, int num, const char *name, - void (*uea_read)(void *opaque, int sprn), - void (*uea_write)(void *opaque, int sprn), + void (*uea_read)(void *opaque, int gprn, int sprn), + void (*uea_write)(void *opaque, int sprn, int gprn), target_ulong initial_value) #else static inline void spr_register (CPUPPCState *env, int num, const char *name, - void (*uea_read)(void *opaque, int sprn), - void (*uea_write)(void *opaque, int sprn), - void (*oea_read)(void *opaque, int sprn), - void (*oea_write)(void *opaque, int sprn), + void (*uea_read)(void *opaque, int gprn, int sprn), + void (*uea_write)(void *opaque, int sprn, int gprn), + void (*oea_read)(void *opaque, int gprn, int sprn), + void (*oea_write)(void *opaque, int sprn, int gprn), target_ulong initial_value) #endif { |