From 452a6017c1ccbde30cc7dc76b1bad74b9e95e1bf Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Blue Swirl Date: Mon, 1 Aug 2011 12:19:05 +0000 Subject: [PATCH 6/6] 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 --- Makefile.target | 12 ++- configure | 7 ++ target-sparc/cpu.h | 85 +--------------------- target-sparc/ldst_helper.c | 73 +++++++++++++++++- target-sparc/op_helper.c | 174 -------------------------------------------- target-sparc/translate.c | 10 ++- 6 files changed, 93 insertions(+), 268 deletions(-) delete mode 100644 target-sparc/op_helper.c diff --git a/Makefile.target b/Makefile.target index 3a7e481..ed4c3bf 100644 --- a/Makefile.target +++ b/Makefile.target @@ -71,7 +71,10 @@ libobj-y = exec.o translate-all.o cpu-exec.o translate.o libobj-y += tcg/tcg.o tcg/optimize.o libobj-$(CONFIG_TCG_INTERPRETER) += tci.o libobj-y += fpu/softfloat.o -libobj-y += op_helper.o helper.o +ifneq ($(TARGET_BASE_ARCH), sparc) +libobj-y += op_helper.o +endif +libobj-y += helper.o ifeq ($(TARGET_BASE_ARCH), i386) libobj-y += cpuid.o endif @@ -92,9 +95,12 @@ tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci $(libobj-y): $(GENERATED_HEADERS) -# HELPER_CFLAGS is used for all the code compiled with static register +# HELPER_CFLAGS is used for all the legacy code compiled with static register # variables -op_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +ifneq ($(TARGET_BASE_ARCH), sparc) +op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) +endif +user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) # Note: this is a workaround. The real fix is to avoid compiling # cpu_signal_handler() in user-exec.c. diff --git a/configure b/configure index 0309dad..3abe80d 100755 --- a/configure +++ b/configure @@ -3552,6 +3552,13 @@ case "$target_arch2" in exit 1 ;; esac + +case "$target_arch2" in + sparc*) + echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak + ;; +esac + echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 143db17..71a890c 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -581,89 +581,6 @@ void cpu_unassigned_access(CPUState *env1, target_phys_addr_t addr, target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr, int mmu_idx); #endif - -#define WRAP_LD(rettype, fn) \ - rettype cpu_ ## fn (CPUState *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 (CPUState *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); @@ -776,6 +693,8 @@ uint64_t cpu_tick_get_count(CPUTimer *timer); void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit); trap_state* cpu_tsptr(CPUState* env); #endif +void do_unaligned_access(CPUState *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 6069974..6b9f089 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(CPUState *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; @@ -2347,3 +2365,50 @@ void cpu_unassigned_access(CPUState *env, target_phys_addr_t addr, } #endif #endif + +#if !defined(CONFIG_USER_ONLY) +/* XXX: make it generic ? */ +static void cpu_restore_state2(CPUState *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(CPUState *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(CPUState *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 e844947..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(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, - void *retaddr) -{ - int ret; - CPUState *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 (CPUState *env1, target_ulong addr) \ - { \ - CPUState *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 (CPUState *env1, target_ulong addr, datatype val) \ - { \ - CPUState *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 a7790c6..ea57b59 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) -- 1.7.2.5