diff --git a/target/s390x/fpu_helper.c b/target/s390x/fpu_helper.c index 13af158748..a42741eec6 100644 --- a/target/s390x/fpu_helper.c +++ b/target/s390x/fpu_helper.c @@ -168,6 +168,34 @@ uint32_t set_cc_nz_f128(float128 v) } } +/* condition codes for FP to integer conversion ops */ +static uint32_t set_cc_conv_f32(float32 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f32(v); + } +} + +static uint32_t set_cc_conv_f64(float64 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f64(v); + } +} + +static uint32_t set_cc_conv_f128(float128 v, float_status *stat) +{ + if (stat->float_exception_flags & float_flag_invalid) { + return 3; + } else { + return set_cc_nz_f128(v); + } +} + static inline uint8_t round_from_m34(uint32_t m34) { return extract32(m34, 0, 4); @@ -506,9 +534,11 @@ uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int64_t ret = float32_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return INT64_MIN; } @@ -520,9 +550,11 @@ uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int64_t ret = float64_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return INT64_MIN; } @@ -535,9 +567,11 @@ uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); float128 v2 = make_float128(h, l); int64_t ret = float128_to_int64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float128_is_any_nan(v2)) { return INT64_MIN; } @@ -549,9 +583,11 @@ uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int32_t ret = float32_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return INT32_MIN; } @@ -563,9 +599,11 @@ uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); int32_t ret = float64_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return INT32_MIN; } @@ -578,9 +616,11 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); float128 v2 = make_float128(h, l); int32_t ret = float128_to_int32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float128_is_any_nan(v2)) { return INT32_MIN; } @@ -592,8 +632,11 @@ uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint64_t ret = float32_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); + s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return 0; } @@ -605,9 +648,11 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint64_t ret = float64_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return 0; } @@ -618,11 +663,14 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); - uint64_t ret = float128_to_uint64(make_float128(h, l), &env->fpu_status); + float128 v2 = make_float128(h, l); + uint64_t ret = float128_to_uint64(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); - if (float128_is_any_nan(make_float128(h, l))) { + env->cc_op = cc; + if (float128_is_any_nan(v2)) { return 0; } return ret; @@ -633,9 +681,11 @@ uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint32_t ret = float32_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f32(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float32_is_any_nan(v2)) { return 0; } @@ -647,9 +697,11 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); uint32_t ret = float64_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f64(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); + env->cc_op = cc; if (float64_is_any_nan(v2)) { return 0; } @@ -660,11 +712,14 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34) uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34) { int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34)); - uint32_t ret = float128_to_uint32(make_float128(h, l), &env->fpu_status); + float128 v2 = make_float128(h, l); + uint32_t ret = float128_to_uint32(v2, &env->fpu_status); + uint32_t cc = set_cc_conv_f128(v2, &env->fpu_status); s390_restore_bfp_rounding_mode(env, old_mode); handle_exceptions(env, xxc_from_m34(m34), GETPC()); - if (float128_is_any_nan(make_float128(h, l))) { + env->cc_op = cc; + if (float128_is_any_nan(v2)) { return 0; } return ret; diff --git a/target/s390x/helper.h b/target/s390x/helper.h index ba045f559d..6215ca00bc 100644 --- a/target/s390x/helper.h +++ b/target/s390x/helper.h @@ -64,18 +64,18 @@ DEF_HELPER_FLAGS_5(cxb, TCG_CALL_NO_WG_SE, i32, env, i64, i64, i64, i64) DEF_HELPER_FLAGS_3(keb, TCG_CALL_NO_WG, i32, env, i64, i64) DEF_HELPER_FLAGS_3(kdb, TCG_CALL_NO_WG, i32, env, i64, i64) DEF_HELPER_FLAGS_5(kxb, TCG_CALL_NO_WG, i32, env, i64, i64, i64, i64) -DEF_HELPER_FLAGS_3(cgeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(cgdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(cgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(cfeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(cfdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(cfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(clgeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(clgdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(clgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) -DEF_HELPER_FLAGS_3(clfeb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_3(clfdb, TCG_CALL_NO_WG, i64, env, i64, i32) -DEF_HELPER_FLAGS_4(clfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) +DEF_HELPER_3(cgeb, i64, env, i64, i32) +DEF_HELPER_3(cgdb, i64, env, i64, i32) +DEF_HELPER_4(cgxb, i64, env, i64, i64, i32) +DEF_HELPER_3(cfeb, i64, env, i64, i32) +DEF_HELPER_3(cfdb, i64, env, i64, i32) +DEF_HELPER_4(cfxb, i64, env, i64, i64, i32) +DEF_HELPER_3(clgeb, i64, env, i64, i32) +DEF_HELPER_3(clgdb, i64, env, i64, i32) +DEF_HELPER_4(clgxb, i64, env, i64, i64, i32) +DEF_HELPER_3(clfeb, i64, env, i64, i32) +DEF_HELPER_3(clfdb, i64, env, i64, i32) +DEF_HELPER_4(clfxb, i64, env, i64, i64, i32) DEF_HELPER_FLAGS_3(fieb, TCG_CALL_NO_WG, i64, env, i64, i32) DEF_HELPER_FLAGS_3(fidb, TCG_CALL_NO_WG, i64, env, i64, i32) DEF_HELPER_FLAGS_4(fixb, TCG_CALL_NO_WG, i64, env, i64, i64, i32) diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 03dab9f350..71ae3f333e 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -563,21 +563,6 @@ static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val) gen_op_update1_cc_i64(s, CC_OP_NZ, val); } -static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val) -{ - gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val); -} - -static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val) -{ - gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val); -} - -static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl) -{ - gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl); -} - /* CC value is in env->cc_op */ static void set_cc_static(DisasContext *s) { @@ -1836,7 +1821,7 @@ static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o) } gen_helper_cfeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1849,7 +1834,7 @@ static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o) } gen_helper_cfdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1862,7 +1847,7 @@ static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o) } gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1875,7 +1860,7 @@ static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o) } gen_helper_cgeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1888,7 +1873,7 @@ static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o) } gen_helper_cgdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1901,7 +1886,7 @@ static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o) } gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1914,7 +1899,7 @@ static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o) } gen_helper_clfeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1927,7 +1912,7 @@ static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o) } gen_helper_clfdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1940,7 +1925,7 @@ static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o) } gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1953,7 +1938,7 @@ static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o) } gen_helper_clgeb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f32(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1966,7 +1951,7 @@ static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o) } gen_helper_clgdb(o->out, cpu_env, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f64(s, o->in2); + set_cc_static(s); return DISAS_NEXT; } @@ -1979,7 +1964,7 @@ static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o) } gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m34); tcg_temp_free_i32(m34); - gen_set_cc_nz_f128(s, o->in1, o->in2); + set_cc_static(s); return DISAS_NEXT; }