#include "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
+#include "fpu/softfloat.h"
#ifndef CONFIG_USER_ONLY
cpu_loop_exit_restore(cs, retaddr);
}
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr)
{
int ret;
- ret = superh_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
+ ret = superh_cpu_handle_mmu_fault(cs, addr, size, access_type, mmu_idx);
if (ret) {
/* now we have a real cpu fault */
cpu_loop_exit_restore(cs, retaddr);
raise_exception(env, 0x160, 0);
}
+void helper_exclusive(CPUSH4State *env)
+{
+ /* We do not want cpu_restore_state to run. */
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), 0);
+}
+
void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value)
{
if (cpu_sh4_is_cached (env, address))
return t0;
}
-void helper_fcmp_eq_FT(CPUSH4State *env, float32 t0, float32 t1)
+uint32_t helper_fcmp_eq_FT(CPUSH4State *env, float32 t0, float32 t1)
{
int relation;
set_float_exception_flags(0, &env->fp_status);
relation = float32_compare(t0, t1, &env->fp_status);
update_fpscr(env, GETPC());
- env->sr_t = (relation == float_relation_equal);
+ return relation == float_relation_equal;
}
-void helper_fcmp_eq_DT(CPUSH4State *env, float64 t0, float64 t1)
+uint32_t helper_fcmp_eq_DT(CPUSH4State *env, float64 t0, float64 t1)
{
int relation;
set_float_exception_flags(0, &env->fp_status);
relation = float64_compare(t0, t1, &env->fp_status);
update_fpscr(env, GETPC());
- env->sr_t = (relation == float_relation_equal);
+ return relation == float_relation_equal;
}
-void helper_fcmp_gt_FT(CPUSH4State *env, float32 t0, float32 t1)
+uint32_t helper_fcmp_gt_FT(CPUSH4State *env, float32 t0, float32 t1)
{
int relation;
set_float_exception_flags(0, &env->fp_status);
relation = float32_compare(t0, t1, &env->fp_status);
update_fpscr(env, GETPC());
- env->sr_t = (relation == float_relation_greater);
+ return relation == float_relation_greater;
}
-void helper_fcmp_gt_DT(CPUSH4State *env, float64 t0, float64 t1)
+uint32_t helper_fcmp_gt_DT(CPUSH4State *env, float64 t0, float64 t1)
{
int relation;
set_float_exception_flags(0, &env->fp_status);
relation = float64_compare(t0, t1, &env->fp_status);
update_fpscr(env, GETPC());
- env->sr_t = (relation == float_relation_greater);
+ return relation == float_relation_greater;
}
float64 helper_fcnvsd_FT_DT(CPUSH4State *env, float32 t0)
return t0;
}
-float32 helper_fneg_T(float32 t0)
-{
- return float32_chs(t0);
-}
-
float32 helper_fsqrt_FT(CPUSH4State *env, float32 t0)
{
set_float_exception_flags(0, &env->fp_status);
return t0;
}
+float32 helper_fsrra_FT(CPUSH4State *env, float32 t0)
+{
+ set_float_exception_flags(0, &env->fp_status);
+ /* "Approximate" 1/sqrt(x) via actual computation. */
+ t0 = float32_sqrt(t0, &env->fp_status);
+ t0 = float32_div(float32_one, t0, &env->fp_status);
+ /* Since this is supposed to be an approximation, an imprecision
+ exception is required. One supposes this also follows the usual
+ IEEE rule that other exceptions take precidence. */
+ if (get_float_exception_flags(&env->fp_status) == 0) {
+ set_float_exception_flags(float_flag_inexact, &env->fp_status);
+ }
+ update_fpscr(env, GETPC());
+ return t0;
+}
+
float32 helper_fsub_FT(CPUSH4State *env, float32 t0, float32 t1)
{
set_float_exception_flags(0, &env->fp_status);