diff options
Diffstat (limited to 'target-mips/op_helper.c')
-rw-r--r-- | target-mips/op_helper.c | 369 |
1 files changed, 349 insertions, 20 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 97dffa2b7e..7f6e8217b2 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2447,6 +2447,7 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr, #define FLOAT_TWO32 make_float32(1 << 30) #define FLOAT_TWO64 make_float64(1ULL << 62) + #define FP_TO_INT32_OVERFLOW 0x7fffffff #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL @@ -2682,7 +2683,7 @@ uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0) return fdt2; } -uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -2695,7 +2696,7 @@ uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_cvtl_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -2790,7 +2791,7 @@ uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0) return wt2; } -uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -2803,7 +2804,7 @@ uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } -uint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2; @@ -2816,7 +2817,7 @@ uint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0) return wt2; } -uint64_t helper_float_roundl_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -2831,7 +2832,7 @@ uint64_t helper_float_roundl_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_roundl_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -2846,7 +2847,7 @@ uint64_t helper_float_roundl_s(CPUMIPSState *env, uint32_t fst0) return dt2; } -uint32_t helper_float_roundw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2; @@ -2861,7 +2862,7 @@ uint32_t helper_float_roundw_d(CPUMIPSState *env, uint64_t fdt0) return wt2; } -uint32_t helper_float_roundw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -2876,7 +2877,7 @@ uint32_t helper_float_roundw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } -uint64_t helper_float_truncl_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -2889,7 +2890,7 @@ uint64_t helper_float_truncl_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_truncl_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -2902,7 +2903,7 @@ uint64_t helper_float_truncl_s(CPUMIPSState *env, uint32_t fst0) return dt2; } -uint32_t helper_float_truncw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2; @@ -2915,7 +2916,7 @@ uint32_t helper_float_truncw_d(CPUMIPSState *env, uint64_t fdt0) return wt2; } -uint32_t helper_float_truncw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -2928,7 +2929,7 @@ uint32_t helper_float_truncw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } -uint64_t helper_float_ceill_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -2943,7 +2944,7 @@ uint64_t helper_float_ceill_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_ceill_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -2958,7 +2959,7 @@ uint64_t helper_float_ceill_s(CPUMIPSState *env, uint32_t fst0) return dt2; } -uint32_t helper_float_ceilw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2; @@ -2973,7 +2974,7 @@ uint32_t helper_float_ceilw_d(CPUMIPSState *env, uint64_t fdt0) return wt2; } -uint32_t helper_float_ceilw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -2988,7 +2989,7 @@ uint32_t helper_float_ceilw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } -uint64_t helper_float_floorl_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -3003,7 +3004,7 @@ uint64_t helper_float_floorl_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_floorl_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -3018,7 +3019,7 @@ uint64_t helper_float_floorl_s(CPUMIPSState *env, uint32_t fst0) return dt2; } -uint32_t helper_float_floorw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2; @@ -3033,7 +3034,7 @@ uint32_t helper_float_floorw_d(CPUMIPSState *env, uint64_t fdt0) return wt2; } -uint32_t helper_float_floorw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -3048,6 +3049,334 @@ uint32_t helper_float_floorw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } +uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint64_t dt2; + + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0) +{ + uint64_t dt2; + + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint32_t wt2; + + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0) +{ + uint32_t wt2; + + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_nearest_even, + &env->active_fpu.fp_status); + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_nearest_even, + &env->active_fpu.fp_status); + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_nearest_even, + &env->active_fpu.fp_status); + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_nearest_even, + &env->active_fpu.fp_status); + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint64_t dt2; + + dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0) +{ + uint64_t dt2; + + dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint32_t wt2; + + wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0) +{ + uint32_t wt2; + + wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0) +{ + uint64_t dt2; + + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + dt2 = 0; + } + } + update_fcr31(env, GETPC()); + return dt2; +} + +uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float64_is_any_nan(fdt0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + +uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0) +{ + uint32_t wt2; + + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); + restore_rounding_mode(env); + if (get_float_exception_flags(&env->active_fpu.fp_status) + & float_flag_invalid) { + if (float32_is_any_nan(fst0)) { + wt2 = 0; + } + } + update_fcr31(env, GETPC()); + return wt2; +} + /* unary operations, not modifying fp status */ #define FLOAT_UNOP(name) \ uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ |