From e47262da1fe408538d4670493ce720255ff3a218 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Blue Swirl Date: Fri, 6 Apr 2012 11:45:44 +0000 Subject: [PATCH 2/4] softmmu: make unaligned access helper global Make the unaligned access functions global, take a parameter for CPUArchState and use QEMU_NORETURN for all architectures except Xtensa where it may return. Introduce wrappers for targets which use AREG0. Signed-off-by: Blue Swirl --- exec-all.h | 9 +++++++++ softmmu_template.h | 21 +++++++++++++-------- target-alpha/mem_helper.c | 4 ++-- target-mips/op_helper.c | 17 +++++++++++++---- target-sparc/cpu.h | 3 --- target-sparc/ldst_helper.c | 4 ++-- target-xtensa/op_helper.c | 18 +++++++++++++----- 7 files changed, 52 insertions(+), 24 deletions(-) diff --git a/exec-all.h b/exec-all.h index fa7bdfe..40847ec 100644 --- a/exec-all.h +++ b/exec-all.h @@ -306,6 +306,15 @@ void io_mem_write(struct MemoryRegion *mr, target_phys_addr_t addr, void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx, void *retaddr); +#ifndef TARGET_XTENSA +void QEMU_NORETURN cpu_unaligned_access(CPUArchState *env1, target_ulong addr, + int is_write, int is_user, + void *retaddr); +#else +void cpu_unaligned_access(CPUArchState *env1, target_ulong addr, + int is_write, int is_user, + void *retaddr); +#endif #include "softmmu_defs.h" diff --git a/softmmu_template.h b/softmmu_template.h index 02c4218..dcafacd 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -133,7 +133,8 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM do_unaligned_access: retaddr = GETPC(); #ifdef TARGET_ALIGNED_ONLY - do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + cpu_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, + retaddr); #endif res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr, mmu_idx, retaddr); @@ -142,7 +143,8 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM #ifdef TARGET_ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { retaddr = GETPC(); - do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + cpu_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, + retaddr); } #endif addend = env->tlb_table[mmu_idx][index].addend; @@ -152,8 +154,10 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM /* the page is not in the TLB : fill it */ retaddr = GETPC(); #ifdef TARGET_ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr); + if ((addr & (DATA_SIZE - 1)) != 0) { + cpu_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, + retaddr); + } #endif tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; @@ -278,7 +282,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM do_unaligned_access: retaddr = GETPC(); #ifdef TARGET_ALIGNED_ONLY - do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr); + cpu_unaligned_access(env, addr, 1, mmu_idx, retaddr); #endif glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_VAR addr, val, mmu_idx, retaddr); @@ -287,7 +291,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM #ifdef TARGET_ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { retaddr = GETPC(); - do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr); + cpu_unaligned_access(env, addr, 1, mmu_idx, retaddr); } #endif addend = env->tlb_table[mmu_idx][index].addend; @@ -297,8 +301,9 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM /* the page is not in the TLB : fill it */ retaddr = GETPC(); #ifdef TARGET_ALIGNED_ONLY - if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr); + if ((addr & (DATA_SIZE - 1)) != 0) { + cpu_unaligned_access(env, addr, 1, mmu_idx, retaddr); + } #endif tlb_fill(env, addr, 1, mmu_idx, retaddr); goto redo; diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c index 53b5a58..a32ee75 100644 --- a/target-alpha/mem_helper.c +++ b/target-alpha/mem_helper.c @@ -88,8 +88,8 @@ uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v) return ret; } -static void do_unaligned_access(CPUAlphaState *env, target_ulong addr, - int is_write, int is_user, void *retaddr) +void cpu_unaligned_access(CPUAlphaState *env, target_ulong addr, + int is_write, int is_user, void *retaddr) { uint64_t pc; uint32_t insn; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index a28da4a..fbe3224 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2292,9 +2292,6 @@ void helper_wait (void) #if !defined(CONFIG_USER_ONLY) -static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, - int is_user, void *retaddr); - #define MMUSUFFIX _mmu #define SHIFT 0 @@ -2309,13 +2306,25 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, #define SHIFT 3 #include "softmmu_template.h" -static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr) +static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, + int is_user, void *retaddr) { env->CP0_BadVAddr = addr; do_restore_state (retaddr); helper_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL); } +void cpu_unaligned_access(CPUMIPSState *env1, target_ulong addr, int is_write, + int is_user, void *retaddr) +{ + CPUMIPSState *saved_env; + + saved_env = env; + env = env1; + do_unaligned_access(addr, is_write, is_user, retaddr); + env = saved_env; +} + void tlb_fill(CPUMIPSState *env1, target_ulong addr, int is_write, int mmu_idx, void *retaddr) { diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 865288c..b5f2e28 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -700,9 +700,6 @@ 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 QEMU_NORETURN 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 8a48116..d288318 100644 --- a/target-sparc/ldst_helper.c +++ b/target-sparc/ldst_helper.c @@ -2392,8 +2392,8 @@ static void cpu_restore_state2(CPUSPARCState *env, void *retaddr) } } -void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write, - int is_user, void *retaddr) +void cpu_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 diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c index 08d2d59..ff0dad3 100644 --- a/target-xtensa/op_helper.c +++ b/target-xtensa/op_helper.c @@ -30,9 +30,6 @@ #include "helpers.h" #include "host-utils.h" -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - void *retaddr); - #define MMUSUFFIX _mmu #define SHIFT 0 @@ -58,8 +55,8 @@ static void do_restore_state(void *pc_ptr) } } -static void do_unaligned_access(target_ulong addr, int is_write, int is_user, - void *retaddr) +static void do_unaligned_access(target_ulong addr, int is_write, + int is_user, void *retaddr) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) && !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) { @@ -69,6 +66,17 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, } } +void cpu_unaligned_access(CPUXtensaState *env1, target_ulong addr, int is_write, + int is_user, void *retaddr) +{ + CPUXtensaState *saved_env; + + saved_env = env; + env = env1; + do_unaligned_access(addr, is_write, is_user, retaddr); + env = saved_env; +} + void tlb_fill(CPUXtensaState *env1, target_ulong vaddr, int is_write, int mmu_idx, void *retaddr) { -- 1.7.2.5