target-mips: don't call cpu_loop_exit() from helper.c

In helper.c AREG0 may not correspond do env, so it's not possible to
call cpu_loop_exit() here. Call it from op_helper.c instead.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2010-02-06 17:02:45 +01:00
parent 3f26c1227e
commit c36bbb28ad
3 changed files with 22 additions and 8 deletions

View file

@ -599,8 +599,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
void do_interrupt (CPUState *env); void do_interrupt (CPUState *env);
void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra); void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
target_phys_addr_t do_translate_address (CPUState *env, target_ulong address, target_phys_addr_t cpu_mips_translate_address (CPUState *env, target_ulong address,
int rw); int rw);
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
{ {

View file

@ -311,7 +311,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
} }
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int rw) target_phys_addr_t cpu_mips_translate_address(CPUState *env, target_ulong address, int rw)
{ {
target_phys_addr_t physical; target_phys_addr_t physical;
int prot; int prot;
@ -326,10 +326,10 @@ target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int
address, rw, access_type); address, rw, access_type);
if (ret != TLBRET_MATCH) { if (ret != TLBRET_MATCH) {
raise_mmu_exception(env, address, rw, ret); raise_mmu_exception(env, address, rw, ret);
cpu_loop_exit(); return -1LL;
} else {
return physical;
} }
return physical;
} }
#endif #endif

View file

@ -276,10 +276,24 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
#endif #endif
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
static inline target_phys_addr_t do_translate_address(target_ulong address, int rw)
{
target_phys_addr_t lladdr;
lladdr = cpu_mips_translate_address(env, address, rw);
if (lladdr == -1LL) {
cpu_loop_exit();
} else {
return lladdr;
}
}
#define HELPER_LD_ATOMIC(name, insn) \ #define HELPER_LD_ATOMIC(name, insn) \
target_ulong helper_##name(target_ulong arg, int mem_idx) \ target_ulong helper_##name(target_ulong arg, int mem_idx) \
{ \ { \
env->lladdr = do_translate_address(env, arg, 0); \ env->lladdr = do_translate_address(arg, 0); \
env->llval = do_##insn(arg, mem_idx); \ env->llval = do_##insn(arg, mem_idx); \
return env->llval; \ return env->llval; \
} }
@ -298,7 +312,7 @@ target_ulong helper_##name(target_ulong arg1, target_ulong arg2, int mem_idx) \
env->CP0_BadVAddr = arg2; \ env->CP0_BadVAddr = arg2; \
helper_raise_exception(EXCP_AdES); \ helper_raise_exception(EXCP_AdES); \
} \ } \
if (do_translate_address(env, arg2, 1) == env->lladdr) { \ if (do_translate_address(arg2, 1) == env->lladdr) { \
tmp = do_##ld_insn(arg2, mem_idx); \ tmp = do_##ld_insn(arg2, mem_idx); \
if (tmp == env->llval) { \ if (tmp == env->llval) { \
do_##st_insn(arg2, arg1, mem_idx); \ do_##st_insn(arg2, arg1, mem_idx); \