diff options
Diffstat (limited to 'target-alpha/helper.c')
| -rw-r--r-- | target-alpha/helper.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 3f2e7c383d..765e650002 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "softfloat.h" +#include "helper.h" uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env) { @@ -81,7 +82,7 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env) break; } - if (env->fpcr_dnz) { + if (env->fp_status.flush_inputs_to_zero) { r |= FPCR_DNZ; } if (env->fpcr_dnod) { @@ -150,17 +151,25 @@ void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val) } env->fpcr_dyn_round = t; - env->fpcr_flush_to_zero - = (val & (FPCR_UNDZ|FPCR_UNFD)) == (FPCR_UNDZ|FPCR_UNFD); - - env->fpcr_dnz = (val & FPCR_DNZ) != 0; env->fpcr_dnod = (val & FPCR_DNOD) != 0; env->fpcr_undz = (val & FPCR_UNDZ) != 0; + env->fpcr_flush_to_zero = env->fpcr_dnod & env->fpcr_undz; + env->fp_status.flush_inputs_to_zero = (val & FPCR_DNZ) != 0; +} + +uint64_t helper_load_fpcr(CPUAlphaState *env) +{ + return cpu_alpha_load_fpcr(env); +} + +void helper_store_fpcr(CPUAlphaState *env, uint64_t val) +{ + cpu_alpha_store_fpcr(env, val); } #if defined(CONFIG_USER_ONLY) -int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, target_ulong address, int rw, - int mmu_idx) +int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong address, + int rw, int mmu_idx) { env->exception_index = EXCP_MMFAULT; env->trap_arg0 = address; @@ -484,3 +493,41 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf, } cpu_fprintf(f, "\n"); } + +void do_restore_state(CPUAlphaState *env, void *retaddr) +{ + uintptr_t pc = (uintptr_t)retaddr; + if (pc) { + TranslationBlock *tb = tb_find_pc(pc); + if (tb) { + cpu_restore_state(tb, env, pc); + } + } +} + +/* This should only be called from translate, via gen_excp. + We expect that ENV->PC has already been updated. */ +void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error) +{ + env->exception_index = excp; + env->error_code = error; + cpu_loop_exit(env); +} + +/* This may be called from any of the helpers to set up EXCEPTION_INDEX. */ +void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, void *retaddr, + int excp, int error) +{ + env->exception_index = excp; + env->error_code = error; + do_restore_state(env, retaddr); + cpu_loop_exit(env); +} + +void QEMU_NORETURN arith_excp(CPUAlphaState *env, void *retaddr, + int exc, uint64_t mask) +{ + env->trap_arg0 = exc; + env->trap_arg1 = mask; + dynamic_excp(env, retaddr, EXCP_ARITH, 0); +} |