diff options
Diffstat (limited to 'target/sh4')
-rw-r--r-- | target/sh4/helper.h | 1 | ||||
-rw-r--r-- | target/sh4/op_helper.c | 16 | ||||
-rw-r--r-- | target/sh4/translate.c | 2 |
3 files changed, 19 insertions, 0 deletions
diff --git a/target/sh4/helper.h b/target/sh4/helper.h index 6c6fa04732..1e768fcbc7 100644 --- a/target/sh4/helper.h +++ b/target/sh4/helper.h @@ -37,6 +37,7 @@ DEF_HELPER_FLAGS_3(fsub_FT, TCG_CALL_NO_WG, f32, env, f32, f32) DEF_HELPER_FLAGS_3(fsub_DT, TCG_CALL_NO_WG, f64, env, f64, f64) DEF_HELPER_FLAGS_2(fsqrt_FT, TCG_CALL_NO_WG, f32, env, f32) DEF_HELPER_FLAGS_2(fsqrt_DT, TCG_CALL_NO_WG, f64, env, f64) +DEF_HELPER_FLAGS_2(fsrra_FT, TCG_CALL_NO_WG, f32, env, f32) DEF_HELPER_FLAGS_2(ftrc_FT, TCG_CALL_NO_WG, i32, env, f32) DEF_HELPER_FLAGS_2(ftrc_DT, TCG_CALL_NO_WG, i32, env, f64) DEF_HELPER_3(fipr, void, env, i32, i32) diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c index 8513f38849..d798f239cf 100644 --- a/target/sh4/op_helper.c +++ b/target/sh4/op_helper.c @@ -406,6 +406,22 @@ float64 helper_fsqrt_DT(CPUSH4State *env, float64 t0) 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); diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 92a2c002fc..ce84fbb966 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -1731,6 +1731,8 @@ static void _decode_opc(DisasContext * ctx) return; case 0xf07d: /* fsrra FRn */ CHECK_FPU_ENABLED + CHECK_FPSCR_PR_0 + gen_helper_fsrra_FT(FREG(B11_8), cpu_env, FREG(B11_8)); break; case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ CHECK_FPU_ENABLED |