diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2011-08-01 12:19:05 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2012-03-18 12:22:02 +0000 |
commit | 0184e266cb7584feefaf4b54abbaa9fa81b62fac (patch) | |
tree | 4685a7b60eaf0e0512667bcc019ed256ec90e6aa /target-sparc | |
parent | fe8d8f0f1c3ed0f5e84edffbbc8fcdf3b7da589b (diff) | |
download | qemu-0184e266cb7584feefaf4b54abbaa9fa81b62fac.zip qemu-0184e266cb7584feefaf4b54abbaa9fa81b62fac.tar.gz qemu-0184e266cb7584feefaf4b54abbaa9fa81b62fac.tar.bz2 |
Sparc: avoid AREG0 wrappers for memory access helpers
Adjust generation of load and store templates so that the functions
take a parameter for CPUState instead of relying on global env.
Remove wrappers. Move remaining memory helpers to ldst_helper.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/cpu.h | 85 | ||||
-rw-r--r-- | target-sparc/ldst_helper.c | 73 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 174 | ||||
-rw-r--r-- | target-sparc/translate.c | 10 |
4 files changed, 77 insertions, 265 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index ee28daa..1025752 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -587,89 +587,6 @@ void cpu_unassigned_access(CPUSPARCState *env1, target_phys_addr_t addr, target_phys_addr_t cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr, int mmu_idx); #endif - -#define WRAP_LD(rettype, fn) \ - rettype cpu_ ## fn (CPUSPARCState *env1, target_ulong addr) - -WRAP_LD(uint32_t, ldub_kernel); -WRAP_LD(uint32_t, lduw_kernel); -WRAP_LD(uint32_t, ldl_kernel); -WRAP_LD(uint64_t, ldq_kernel); - -WRAP_LD(uint32_t, ldub_user); -WRAP_LD(uint32_t, lduw_user); -WRAP_LD(uint32_t, ldl_user); -WRAP_LD(uint64_t, ldq_user); - -WRAP_LD(uint64_t, ldfq_kernel); -WRAP_LD(uint64_t, ldfq_user); - -#ifdef TARGET_SPARC64 -WRAP_LD(uint32_t, ldub_hypv); -WRAP_LD(uint32_t, lduw_hypv); -WRAP_LD(uint32_t, ldl_hypv); -WRAP_LD(uint64_t, ldq_hypv); - -WRAP_LD(uint64_t, ldfq_hypv); - -WRAP_LD(uint32_t, ldub_nucleus); -WRAP_LD(uint32_t, lduw_nucleus); -WRAP_LD(uint32_t, ldl_nucleus); -WRAP_LD(uint64_t, ldq_nucleus); - -WRAP_LD(uint32_t, ldub_kernel_secondary); -WRAP_LD(uint32_t, lduw_kernel_secondary); -WRAP_LD(uint32_t, ldl_kernel_secondary); -WRAP_LD(uint64_t, ldq_kernel_secondary); - -WRAP_LD(uint32_t, ldub_user_secondary); -WRAP_LD(uint32_t, lduw_user_secondary); -WRAP_LD(uint32_t, ldl_user_secondary); -WRAP_LD(uint64_t, ldq_user_secondary); -#endif -#undef WRAP_LD - -#define WRAP_ST(datatype, fn) \ - void cpu_ ## fn (CPUSPARCState *env1, target_ulong addr, datatype val) - -WRAP_ST(uint32_t, stb_kernel); -WRAP_ST(uint32_t, stw_kernel); -WRAP_ST(uint32_t, stl_kernel); -WRAP_ST(uint64_t, stq_kernel); - -WRAP_ST(uint32_t, stb_user); -WRAP_ST(uint32_t, stw_user); -WRAP_ST(uint32_t, stl_user); -WRAP_ST(uint64_t, stq_user); - -WRAP_ST(uint64_t, stfq_kernel); -WRAP_ST(uint64_t, stfq_user); - -#ifdef TARGET_SPARC64 -WRAP_ST(uint32_t, stb_hypv); -WRAP_ST(uint32_t, stw_hypv); -WRAP_ST(uint32_t, stl_hypv); -WRAP_ST(uint64_t, stq_hypv); - -WRAP_ST(uint64_t, stfq_hypv); - -WRAP_ST(uint32_t, stb_nucleus); -WRAP_ST(uint32_t, stw_nucleus); -WRAP_ST(uint32_t, stl_nucleus); -WRAP_ST(uint64_t, stq_nucleus); - -WRAP_ST(uint32_t, stb_kernel_secondary); -WRAP_ST(uint32_t, stw_kernel_secondary); -WRAP_ST(uint32_t, stl_kernel_secondary); -WRAP_ST(uint64_t, stq_kernel_secondary); - -WRAP_ST(uint32_t, stb_user_secondary); -WRAP_ST(uint32_t, stw_user_secondary); -WRAP_ST(uint32_t, stl_user_secondary); -WRAP_ST(uint64_t, stq_user_secondary); -#endif - -#undef WRAP_ST #endif int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); @@ -782,6 +699,8 @@ uint64_t cpu_tick_get_count(CPUTimer *timer); void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit); trap_state* cpu_tsptr(CPUSPARCState* env); #endif +void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write, + int is_user, void *retaddr); #define TB_FLAG_FPU_ENABLED (1 << 4) #define TB_FLAG_AM_ENABLED (1 << 5) diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c index 8468cde..1418205 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -64,6 +64,24 @@ #define QT0 (env->qt0) #define QT1 (env->qt1) +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#define MMUSUFFIX _mmu +#define ALIGNED_ONLY + +#define SHIFT 0 +#include "softmmu_template.h" + +#define SHIFT 1 +#include "softmmu_template.h" + +#define SHIFT 2 +#include "softmmu_template.h" + +#define SHIFT 3 +#include "softmmu_template.h" +#endif + #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) /* Calculates TSB pointer value for fault page size 8k or 64k */ static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register, @@ -523,17 +541,17 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size, case 9: /* Supervisor code access */ switch (size) { case 1: - ret = ldub_code(addr); + ret = cpu_ldub_code(env, addr); break; case 2: - ret = lduw_code(addr); + ret = cpu_lduw_code(env, addr); break; default: case 4: - ret = ldl_code(addr); + ret = cpu_ldl_code(env, addr); break; case 8: - ret = ldq_code(addr); + ret = cpu_ldq_code(env, addr); break; } break; @@ -2355,3 +2373,50 @@ void cpu_unassigned_access(CPUSPARCState *env, target_phys_addr_t addr, } #endif #endif + +#if !defined(CONFIG_USER_ONLY) +/* XXX: make it generic ? */ +static void cpu_restore_state2(CPUSPARCState *env, void *retaddr) +{ + TranslationBlock *tb; + unsigned long pc; + + if (retaddr) { + /* now we have a real cpu fault */ + pc = (unsigned long)retaddr; + tb = tb_find_pc(pc); + if (tb) { + /* the PC is inside the translated code. It means that we have + a virtual CPU fault */ + cpu_restore_state(tb, env, pc); + } + } +} + +void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write, + int is_user, void *retaddr) +{ +#ifdef DEBUG_UNALIGNED + printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx + "\n", addr, env->pc); +#endif + cpu_restore_state2(env, retaddr); + helper_raise_exception(env, TT_UNALIGNED); +} + +/* try to fill the TLB and return an exception if error. If retaddr is + 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(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx, + void *retaddr) +{ + int ret; + + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx); + if (ret) { + cpu_restore_state2(env, retaddr); + cpu_loop_exit(env); + } +} +#endif diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c deleted file mode 100644 index b7171d8..0000000 --- a/target-sparc/op_helper.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "cpu.h" -#include "dyngen-exec.h" -#include "helper.h" - -#if !defined(CONFIG_USER_ONLY) -#include "softmmu_exec.h" -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - void *retaddr); - -#define MMUSUFFIX _mmu -#define ALIGNED_ONLY - -#define SHIFT 0 -#include "softmmu_template.h" - -#define SHIFT 1 -#include "softmmu_template.h" - -#define SHIFT 2 -#include "softmmu_template.h" - -#define SHIFT 3 -#include "softmmu_template.h" - -/* XXX: make it generic ? */ -static void cpu_restore_state2(void *retaddr) -{ - TranslationBlock *tb; - unsigned long pc; - - if (retaddr) { - /* now we have a real cpu fault */ - pc = (unsigned long)retaddr; - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc); - } - } -} - -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - void *retaddr) -{ -#ifdef DEBUG_UNALIGNED - printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx - "\n", addr, env->pc); -#endif - cpu_restore_state2(retaddr); - helper_raise_exception(env, TT_UNALIGNED); -} - -/* try to fill the TLB and return an exception if error. If retaddr is - 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(CPUSPARCState *env1, target_ulong addr, int is_write, int mmu_idx, - void *retaddr) -{ - int ret; - CPUSPARCState *saved_env; - - saved_env = env; - env = env1; - - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx); - if (ret) { - cpu_restore_state2(retaddr); - cpu_loop_exit(env); - } - env = saved_env; -} - -#define WRAP_LD(rettype, fn) \ - rettype cpu_ ## fn (CPUSPARCState *env1, target_ulong addr) \ - { \ - CPUSPARCState *saved_env; \ - rettype ret; \ - \ - saved_env = env; \ - env = env1; \ - ret = fn(addr); \ - env = saved_env; \ - return ret; \ - } - -WRAP_LD(uint32_t, ldub_kernel) -WRAP_LD(uint32_t, lduw_kernel) -WRAP_LD(uint32_t, ldl_kernel) -WRAP_LD(uint64_t, ldq_kernel) - -WRAP_LD(uint32_t, ldub_user) -WRAP_LD(uint32_t, lduw_user) -WRAP_LD(uint32_t, ldl_user) -WRAP_LD(uint64_t, ldq_user) - -WRAP_LD(uint64_t, ldfq_kernel) -WRAP_LD(uint64_t, ldfq_user) -#ifdef TARGET_SPARC64 -WRAP_LD(uint32_t, ldub_hypv) -WRAP_LD(uint32_t, lduw_hypv) -WRAP_LD(uint32_t, ldl_hypv) -WRAP_LD(uint64_t, ldq_hypv) - -WRAP_LD(uint64_t, ldfq_hypv) - -WRAP_LD(uint32_t, ldub_nucleus) -WRAP_LD(uint32_t, lduw_nucleus) -WRAP_LD(uint32_t, ldl_nucleus) -WRAP_LD(uint64_t, ldq_nucleus) - -WRAP_LD(uint32_t, ldub_kernel_secondary) -WRAP_LD(uint32_t, lduw_kernel_secondary) -WRAP_LD(uint32_t, ldl_kernel_secondary) -WRAP_LD(uint64_t, ldq_kernel_secondary) - -WRAP_LD(uint32_t, ldub_user_secondary) -WRAP_LD(uint32_t, lduw_user_secondary) -WRAP_LD(uint32_t, ldl_user_secondary) -WRAP_LD(uint64_t, ldq_user_secondary) -#endif -#undef WRAP_LD - -#define WRAP_ST(datatype, fn) \ - void cpu_ ## fn (CPUSPARCState *env1, target_ulong addr, datatype val) \ - { \ - CPUSPARCState *saved_env; \ - \ - saved_env = env; \ - env = env1; \ - fn(addr, val); \ - env = saved_env; \ - } - -WRAP_ST(uint32_t, stb_kernel) -WRAP_ST(uint32_t, stw_kernel) -WRAP_ST(uint32_t, stl_kernel) -WRAP_ST(uint64_t, stq_kernel) - -WRAP_ST(uint32_t, stb_user) -WRAP_ST(uint32_t, stw_user) -WRAP_ST(uint32_t, stl_user) -WRAP_ST(uint64_t, stq_user) - -WRAP_ST(uint64_t, stfq_kernel) -WRAP_ST(uint64_t, stfq_user) - -#ifdef TARGET_SPARC64 -WRAP_ST(uint32_t, stb_hypv) -WRAP_ST(uint32_t, stw_hypv) -WRAP_ST(uint32_t, stl_hypv) -WRAP_ST(uint64_t, stq_hypv) - -WRAP_ST(uint64_t, stfq_hypv) - -WRAP_ST(uint32_t, stb_nucleus) -WRAP_ST(uint32_t, stw_nucleus) -WRAP_ST(uint32_t, stl_nucleus) -WRAP_ST(uint64_t, stq_nucleus) - -WRAP_ST(uint32_t, stb_kernel_secondary) -WRAP_ST(uint32_t, stw_kernel_secondary) -WRAP_ST(uint32_t, stl_kernel_secondary) -WRAP_ST(uint64_t, stq_kernel_secondary) - -WRAP_ST(uint32_t, stb_user_secondary) -WRAP_ST(uint32_t, stw_user_secondary) -WRAP_ST(uint32_t, stl_user_secondary) -WRAP_ST(uint64_t, stq_user_secondary) -#endif - -#undef WRAP_ST -#endif diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 670ea2b..4967152 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -2373,9 +2373,9 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2) goto nfpu_insn; /* before an instruction, dc->pc must be static */ -static void disas_sparc_insn(DisasContext * dc) +static void disas_sparc_insn(DisasContext * dc, unsigned int insn) { - unsigned int insn, opc, rs1, rs2, rd; + unsigned int opc, rs1, rs2, rd; TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2; TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32; TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64; @@ -2383,7 +2383,7 @@ static void disas_sparc_insn(DisasContext * dc) if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) tcg_gen_debug_insn_start(dc->pc); - insn = ldl_code(dc->pc); + opc = GET_FIELD(insn, 0, 1); rd = GET_FIELD(insn, 2, 6); @@ -5240,6 +5240,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, int j, lj = -1; int num_insns; int max_insns; + unsigned int insn; memset(dc, 0, sizeof(DisasContext)); dc->tb = tb; @@ -5299,7 +5300,8 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); last_pc = dc->pc; - disas_sparc_insn(dc); + insn = cpu_ldl_code(env, dc->pc); + disas_sparc_insn(dc, insn); num_insns++; if (dc->is_br) |