cpu_loop_exit(cs);
}
-static bool check_divz(CPUMBState *env, uint32_t b, uintptr_t ra)
+/* Raises ESR_EC_DIVZERO if exceptions are enabled. */
+static void raise_divzero(CPUMBState *env, uint32_t esr, uintptr_t unwind_pc)
{
- if (unlikely(b == 0)) {
- env->msr |= MSR_DZ;
-
- if ((env->msr & MSR_EE) &&
- env_archcpu(env)->cfg.div_zero_exception) {
- CPUState *cs = env_cpu(env);
-
- env->esr = ESR_EC_DIVZERO;
- cs->exception_index = EXCP_HW_EXCP;
- cpu_loop_exit_restore(cs, ra);
- }
- return false;
+ env->msr |= MSR_DZ;
+
+ if ((env->msr & MSR_EE) && env_archcpu(env)->cfg.div_zero_exception) {
+ CPUState *cs = env_cpu(env);
+
+ env->esr = esr;
+ cs->exception_index = EXCP_HW_EXCP;
+ cpu_loop_exit_restore(cs, unwind_pc);
}
- return true;
}
-uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divs(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return (int32_t)a / (int32_t)b;
+ return (int32_t)rb / (int32_t)ra;
}
-uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
+uint32_t helper_divu(CPUMBState *env, uint32_t ra, uint32_t rb)
{
- if (!check_divz(env, b, GETPC())) {
+ if (!ra) {
+ raise_divzero(env, ESR_EC_DIVZERO, GETPC());
return 0;
}
- return a / b;
+ return rb / ra;
}
/* raise FPU exception. */
DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
-/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
-static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divs(out, tcg_env, inb, ina);
-}
-
-static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
-{
- gen_helper_divu(out, tcg_env, inb, ina);
-}
+ENV_WRAPPER3(gen_idiv, gen_helper_divs)
+ENV_WRAPPER3(gen_idivu, gen_helper_divu)
DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)