Hello Richard, Can you have a look at the following patch, and was that are the right direction? From b4d6ca1d6376fab1f1be06eb472e10b908887c2b Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Sat, 2 May 2020 05:59:25 +0800 Subject: [PATCH] [ppc fp] Step 1. Rearrange the fp helpers to eliminate helper_reset_fpstatus(). I've mentioned this before, that it's possible to leave the steady-state of env->fp_status.exception_flags == 0, so there's no need for a separate function call. I suspect this is worth a decent speedup by itself. --- target/ppc/fpu_helper.c | 53 ++---------------------------- target/ppc/helper.h | 1 - target/ppc/translate/fp-impl.inc.c | 23 ------------- 3 files changed, 3 insertions(+), 74 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index d9a8773ee1..4fc5a7ff1c 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -821,6 +821,9 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr) env->error_code, raddr); } } + if (status) { + set_float_exception_flags(0, &env->fp_status); + } } void helper_float_check_status(CPUPPCState *env) @@ -828,11 +831,6 @@ void helper_float_check_status(CPUPPCState *env) do_float_check_status(env, GETPC()); } -void helper_reset_fpstatus(CPUPPCState *env) -{ - set_float_exception_flags(0, &env->fp_status); -} - static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc, uintptr_t retaddr, int classes) { @@ -2110,9 +2108,6 @@ void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2152,8 +2147,6 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t t = *xt; float_status tstat; - helper_reset_fpstatus(env); - tstat = env->fp_status; if (unlikely(Rc(opcode) != 0)) { tstat.float_rounding_mode = float_round_to_odd; @@ -2189,9 +2182,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2228,13 +2218,11 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t t = *xt; float_status tstat; - helper_reset_fpstatus(env); tstat = env->fp_status; if (unlikely(Rc(opcode) != 0)) { tstat.float_rounding_mode = float_round_to_odd; } - set_float_exception_flags(0, &tstat); t.f128 = float128_mul(xa->f128, xb->f128, &tstat); env->fp_status.float_exception_flags |= tstat.float_exception_flags; @@ -2263,9 +2251,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2305,7 +2290,6 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t t = *xt; float_status tstat; - helper_reset_fpstatus(env); tstat = env->fp_status; if (unlikely(Rc(opcode) != 0)) { tstat.float_rounding_mode = float_round_to_odd; @@ -2342,9 +2326,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ if (unlikely(tp##_is_signaling_nan(xb->fld, &env->fp_status))) { \ float_invalid_op_vxsnan(env, GETPC()); \ @@ -2382,9 +2363,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2430,9 +2408,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2592,9 +2567,6 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ { \ ppc_vsr_t t = *xt; \ int i; \ - \ - helper_reset_fpstatus(env); \ - \ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ @@ -2765,9 +2737,6 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ { \ uint32_t cc = 0; \ bool vxsnan_flag = false, vxvc_flag = false; \ - \ - helper_reset_fpstatus(env); \ - \ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \ vxsnan_flag = true; \ @@ -2813,9 +2782,6 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ { \ uint32_t cc = 0; \ bool vxsnan_flag = false, vxvc_flag = false; \ - \ - helper_reset_fpstatus(env); \ - \ if (float128_is_signaling_nan(xa->f128, &env->fp_status) || \ float128_is_signaling_nan(xb->f128, &env->fp_status)) { \ vxsnan_flag = true; \ @@ -3177,9 +3143,6 @@ uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { uint64_t result, sign, exp, frac; - float_status tstat = env->fp_status; - set_float_exception_flags(0, &tstat); - sign = extract64(xb, 63, 1); exp = extract64(xb, 52, 11); frac = extract64(xb, 0, 52) | 0x10000000000000ULL; @@ -3446,8 +3409,6 @@ VSX_ROUND(xvrspiz, 4, float32, VsrW(i), float_round_to_zero, 0) uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb) { - helper_reset_fpstatus(env); - uint64_t xt = helper_frsp(env, xb); helper_compute_fprf_float64(env, xt); @@ -3593,8 +3554,6 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode, uint8_t rmode = 0; float_status tstat; - helper_reset_fpstatus(env); - if (r == 0 && rmc == 0) { rmode = float_round_ties_away; } else if (r == 0 && rmc == 0x3) { @@ -3650,8 +3609,6 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode, floatx80 round_res; float_status tstat; - helper_reset_fpstatus(env); - if (r == 0 && rmc == 0) { rmode = float_round_ties_away; } else if (r == 0 && rmc == 0x3) { @@ -3700,8 +3657,6 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t t = { }; float_status tstat; - helper_reset_fpstatus(env); - tstat = env->fp_status; if (unlikely(Rc(opcode) != 0)) { tstat.float_rounding_mode = float_round_to_odd; @@ -3734,8 +3689,6 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t t = *xt; float_status tstat; - helper_reset_fpstatus(env); - tstat = env->fp_status; if (unlikely(Rc(opcode) != 0)) { tstat.float_rounding_mode = float_round_to_odd; diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 4e192de97b..b486c9991f 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -58,7 +58,6 @@ DEF_HELPER_FLAGS_1(cntlzw32, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_FLAGS_2(brinc, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_1(float_check_status, void, env) -DEF_HELPER_1(reset_fpstatus, void, env) DEF_HELPER_2(compute_fprf_float64, void, env, i64) DEF_HELPER_3(store_fpscr, void, env, i64, i32) DEF_HELPER_2(fpscr_clrbit, void, env, i32) diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c index e18e268fe5..5e8cd9970e 100644 --- a/target/ppc/translate/fp-impl.inc.c +++ b/target/ppc/translate/fp-impl.inc.c @@ -4,11 +4,6 @@ * Standard FPU translation */ -static inline void gen_reset_fpstatus(void) -{ - gen_helper_reset_fpstatus(cpu_env); -} - static inline void gen_compute_fprf_float64(TCGv_i64 arg) { gen_helper_compute_fprf_float64(cpu_env, arg); @@ -48,7 +43,6 @@ static void gen_f##name(DisasContext *ctx) \ t3 = tcg_temp_new_i64(); \ /* NIP cannot be restored if the memory exception comes from an helper */ \ gen_update_nip(ctx, ctx->base.pc_next - 4); \ - gen_reset_fpstatus(); \ get_fpr(t0, rA(ctx->opcode)); \ get_fpr(t1, rC(ctx->opcode)); \ get_fpr(t2, rB(ctx->opcode)); \ @@ -88,7 +82,6 @@ static void gen_f##name(DisasContext *ctx) \ t2 = tcg_temp_new_i64(); \ /* NIP cannot be restored if the memory exception comes from an helper */ \ gen_update_nip(ctx, ctx->base.pc_next - 4); \ - gen_reset_fpstatus(); \ get_fpr(t0, rA(ctx->opcode)); \ get_fpr(t1, rB(ctx->opcode)); \ gen_helper_f##op(t2, cpu_env, t0, t1); \ @@ -123,7 +116,6 @@ static void gen_f##name(DisasContext *ctx) \ t0 = tcg_temp_new_i64(); \ t1 = tcg_temp_new_i64(); \ t2 = tcg_temp_new_i64(); \ - gen_reset_fpstatus(); \ get_fpr(t0, rA(ctx->opcode)); \ get_fpr(t1, rC(ctx->opcode)); \ gen_helper_f##op(t2, cpu_env, t0, t1); \ @@ -156,7 +148,6 @@ static void gen_f##name(DisasContext *ctx) \ } \ t0 = tcg_temp_new_i64(); \ t1 = tcg_temp_new_i64(); \ - gen_reset_fpstatus(); \ get_fpr(t0, rB(ctx->opcode)); \ gen_helper_f##name(t1, cpu_env, t0); \ set_fpr(rD(ctx->opcode), t1); \ @@ -181,7 +172,6 @@ static void gen_f##name(DisasContext *ctx) \ } \ t0 = tcg_temp_new_i64(); \ t1 = tcg_temp_new_i64(); \ - gen_reset_fpstatus(); \ get_fpr(t0, rB(ctx->opcode)); \ gen_helper_f##name(t1, cpu_env, t0); \ set_fpr(rD(ctx->opcode), t1); \ @@ -222,7 +212,6 @@ static void gen_frsqrtes(DisasContext *ctx) } t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); get_fpr(t0, rB(ctx->opcode)); gen_helper_frsqrte(t1, cpu_env, t0); gen_helper_frsp(t1, cpu_env, t1); @@ -252,7 +241,6 @@ static void gen_fsqrt(DisasContext *ctx) } t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); get_fpr(t0, rB(ctx->opcode)); gen_helper_fsqrt(t1, cpu_env, t0); set_fpr(rD(ctx->opcode), t1); @@ -274,7 +262,6 @@ static void gen_fsqrts(DisasContext *ctx) } t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); get_fpr(t0, rB(ctx->opcode)); gen_helper_fsqrt(t1, cpu_env, t0); gen_helper_frsp(t1, cpu_env, t1); @@ -380,7 +367,6 @@ static void gen_fcmpo(DisasContext *ctx) } t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); crf = tcg_const_i32(crfD(ctx->opcode)); get_fpr(t0, rA(ctx->opcode)); get_fpr(t1, rB(ctx->opcode)); @@ -403,7 +389,6 @@ static void gen_fcmpu(DisasContext *ctx) } t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); crf = tcg_const_i32(crfD(ctx->opcode)); get_fpr(t0, rA(ctx->opcode)); get_fpr(t1, rB(ctx->opcode)); @@ -612,7 +597,6 @@ static void gen_mffs(DisasContext *ctx) return; } t0 = tcg_temp_new_i64(); - gen_reset_fpstatus(); tcg_gen_extu_tl_i64(t0, cpu_fpscr); set_fpr(rD(ctx->opcode), t0); if (unlikely(Rc(ctx->opcode))) { @@ -635,7 +619,6 @@ static void gen_mffsl(DisasContext *ctx) return; } t0 = tcg_temp_new_i64(); - gen_reset_fpstatus(); tcg_gen_extu_tl_i64(t0, cpu_fpscr); /* Mask everything except mode, status, and enables. */ tcg_gen_andi_i64(t0, t0, FP_DRN | FP_STATUS | FP_ENABLES | FP_RN); @@ -660,7 +643,6 @@ static void gen_mffsce(DisasContext *ctx) t0 = tcg_temp_new_i64(); - gen_reset_fpstatus(); tcg_gen_extu_tl_i64(t0, cpu_fpscr); set_fpr(rD(ctx->opcode), t0); @@ -678,7 +660,6 @@ static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1) TCGv_i64 t0 = tcg_temp_new_i64(); TCGv_i32 mask = tcg_const_i32(0x0001); - gen_reset_fpstatus(); tcg_gen_extu_tl_i64(t0, cpu_fpscr); tcg_gen_andi_i64(t0, t0, FP_DRN | FP_ENABLES | FP_RN); set_fpr(rD(ctx->opcode), t0); @@ -750,7 +731,6 @@ static void gen_mtfsb0(DisasContext *ctx) return; } crb = 31 - crbD(ctx->opcode); - gen_reset_fpstatus(); if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) { TCGv_i32 t0; t0 = tcg_const_i32(crb); @@ -773,7 +753,6 @@ static void gen_mtfsb1(DisasContext *ctx) return; } crb = 31 - crbD(ctx->opcode); - gen_reset_fpstatus(); /* XXX: we pretend we can only do IEEE floating-point computations */ if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) { TCGv_i32 t0; @@ -807,7 +786,6 @@ static void gen_mtfsf(DisasContext *ctx) gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); return; } - gen_reset_fpstatus(); if (l) { t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff); } else { @@ -844,7 +822,6 @@ static void gen_mtfsfi(DisasContext *ctx) return; } sh = (8 * w) + 7 - bf; - gen_reset_fpstatus(); t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh)); t1 = tcg_const_i32(1 << sh); gen_helper_store_fpscr(cpu_env, t0, t1); -- 2.23.0.windows.1 On Sat, May 2, 2020 at 4:49 AM Richard Henderson < richard.henderson@linaro.org> wrote: > On 5/1/20 1:04 PM, 罗勇刚(Yonggang Luo) wrote: > > And fp_status can not represent all the Invalid Operation Exception > flags. > > What I need to do to represent all the Invalid Operation Exception > > Ideally, we add them to include/fpu/softfloat-types.h, expand the > float_exception_flags field in float_status to match, and generate the new > flags in fpu/softfloat.c. > > This would actually help target/tricore as well. > > > r~ > -- 此致 礼 罗勇刚 Yours sincerely, Yonggang Luo