diff options
Diffstat (limited to 'target/nios2/op_helper.c')
| -rw-r--r-- | target/nios2/op_helper.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c index 49fccf2c2c..a19b504b0e 100644 --- a/target/nios2/op_helper.c +++ b/target/nios2/op_helper.c @@ -31,6 +31,35 @@ void helper_raise_exception(CPUNios2State *env, uint32_t index) cpu_loop_exit(cs); } +static void maybe_raise_div(CPUNios2State *env, uintptr_t ra) +{ + Nios2CPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + if (cpu->diverr_present) { + cs->exception_index = EXCP_DIV; + cpu_loop_exit_restore(cs, ra); + } +} + +int32_t helper_divs(CPUNios2State *env, int32_t num, int32_t den) +{ + if (unlikely(den == 0) || unlikely(den == -1 && num == INT32_MIN)) { + maybe_raise_div(env, GETPC()); + return num; /* undefined */ + } + return num / den; +} + +uint32_t helper_divu(CPUNios2State *env, uint32_t num, uint32_t den) +{ + if (unlikely(den == 0)) { + maybe_raise_div(env, GETPC()); + return num; /* undefined */ + } + return num / den; +} + #ifndef CONFIG_USER_ONLY void helper_eret(CPUNios2State *env, uint32_t new_status, uint32_t new_pc) { |