diff options
author | Giuseppe Musacchio | 2020-11-13 00:01:29 +0100 |
---|---|---|
committer | David Gibson | 2020-12-14 05:53:52 +0100 |
commit | bc92c260f6f0da73d3bdee5e1c2bf38d6f22e20a (patch) | |
tree | da1d5c4702c49ca4f74b04ec27b9b0f71d59657b /target | |
parent | ppc/translate: Turn the helper macros into functions (diff) | |
download | qemu-bc92c260f6f0da73d3bdee5e1c2bf38d6f22e20a.tar.gz qemu-bc92c260f6f0da73d3bdee5e1c2bf38d6f22e20a.tar.xz qemu-bc92c260f6f0da73d3bdee5e1c2bf38d6f22e20a.zip |
ppc/translate: Delay NaN checking after comparison
Since we always perform a comparison between the two operands avoid
checking for NaN unless the result states they're unordered.
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201112230130.65262-4-thatlemon@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/fpu_helper.c | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 34f5bc1f3c..f5a4be595a 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2475,25 +2475,6 @@ static inline void do_scalar_cmp(CPUPPCState *env, ppc_vsr_t *xa, ppc_vsr_t *xb, 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; - if (fpscr_ve == 0 && ordered) { - vxvc_flag = true; - } - } else if (float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || - float64_is_quiet_nan(xb->VsrD(0), &env->fp_status)) { - if (ordered) { - vxvc_flag = true; - } - } - if (vxsnan_flag) { - float_invalid_op_vxsnan(env, GETPC()); - } - if (vxvc_flag) { - float_invalid_op_vxvc(env, 0, GETPC()); - } - switch (float64_compare(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) { case float_relation_less: cc = CRF_LT; @@ -2506,6 +2487,27 @@ static inline void do_scalar_cmp(CPUPPCState *env, ppc_vsr_t *xa, ppc_vsr_t *xb, break; case float_relation_unordered: cc = CRF_SO; + + if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || + float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { + vxsnan_flag = true; + if (fpscr_ve == 0 && ordered) { + vxvc_flag = true; + } + } else if (float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || + float64_is_quiet_nan(xb->VsrD(0), &env->fp_status)) { + if (ordered) { + vxvc_flag = true; + } + } + + if (vxsnan_flag) { + float_invalid_op_vxsnan(env, GETPC()); + } + if (vxvc_flag) { + float_invalid_op_vxvc(env, 0, GETPC()); + } + break; default: g_assert_not_reached(); @@ -2538,25 +2540,6 @@ static inline void do_scalar_cmpq(CPUPPCState *env, ppc_vsr_t *xa, 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; - if (fpscr_ve == 0 && ordered) { - vxvc_flag = true; - } - } else if (float128_is_quiet_nan(xa->f128, &env->fp_status) || - float128_is_quiet_nan(xb->f128, &env->fp_status)) { - if (ordered) { - vxvc_flag = true; - } - } - if (vxsnan_flag) { - float_invalid_op_vxsnan(env, GETPC()); - } - if (vxvc_flag) { - float_invalid_op_vxvc(env, 0, GETPC()); - } - switch (float128_compare(xa->f128, xb->f128, &env->fp_status)) { case float_relation_less: cc = CRF_LT; @@ -2569,6 +2552,27 @@ static inline void do_scalar_cmpq(CPUPPCState *env, ppc_vsr_t *xa, break; case float_relation_unordered: cc = CRF_SO; + + if (float128_is_signaling_nan(xa->f128, &env->fp_status) || + float128_is_signaling_nan(xb->f128, &env->fp_status)) { + vxsnan_flag = true; + if (fpscr_ve == 0 && ordered) { + vxvc_flag = true; + } + } else if (float128_is_quiet_nan(xa->f128, &env->fp_status) || + float128_is_quiet_nan(xb->f128, &env->fp_status)) { + if (ordered) { + vxvc_flag = true; + } + } + + if (vxsnan_flag) { + float_invalid_op_vxsnan(env, GETPC()); + } + if (vxvc_flag) { + float_invalid_op_vxvc(env, 0, GETPC()); + } + break; default: g_assert_not_reached(); |