From: Giuseppe Musacchio <thatle...@gmail.com> The PowerISA reference states that the comparison operators update the FPCC, CR and FPSCR and, if VE=1, jump to the exception handler.
Moving the exception-triggering code after the CC update sequence solves the problem. Signed-off-by: Giuseppe Musacchio <thatle...@gmail.com> Reviewed-by: Richard Henderson <richard.hender...@linaro.org> Message-Id: <20201112230130.65262-5-thatle...@gmail.com> Signed-off-by: David Gibson <da...@gibson.dropbear.id.au> --- target/ppc/fpu_helper.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index f5a4be595a..44315fca0b 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2501,13 +2501,6 @@ static inline void do_scalar_cmp(CPUPPCState *env, ppc_vsr_t *xa, ppc_vsr_t *xb, } } - 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(); @@ -2517,6 +2510,13 @@ static inline void do_scalar_cmp(CPUPPCState *env, ppc_vsr_t *xa, ppc_vsr_t *xb, env->fpscr |= cc << FPSCR_FPCC; env->crf[crf_idx] = cc; + if (vxsnan_flag) { + float_invalid_op_vxsnan(env, GETPC()); + } + if (vxvc_flag) { + float_invalid_op_vxvc(env, 0, GETPC()); + } + do_float_check_status(env, GETPC()); } @@ -2566,13 +2566,6 @@ static inline void do_scalar_cmpq(CPUPPCState *env, ppc_vsr_t *xa, } } - 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(); @@ -2582,6 +2575,13 @@ static inline void do_scalar_cmpq(CPUPPCState *env, ppc_vsr_t *xa, env->fpscr |= cc << FPSCR_FPCC; env->crf[crf_idx] = cc; + if (vxsnan_flag) { + float_invalid_op_vxsnan(env, GETPC()); + } + if (vxvc_flag) { + float_invalid_op_vxvc(env, 0, GETPC()); + } + do_float_check_status(env, GETPC()); } -- 2.29.2