aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorGiuseppe Musacchio <thatlemon@gmail.com>2020-11-13 00:01:30 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2020-12-14 15:53:59 +1100
commit91699dbf30a94dea2575ae193412c364c7f3a5fd (patch)
tree0075a2ec21ddc2c204d465255b18f6044ea2f773 /target/ppc
parentbc92c260f6f0da73d3bdee5e1c2bf38d6f22e20a (diff)
downloadqemu-91699dbf30a94dea2575ae193412c364c7f3a5fd.zip
qemu-91699dbf30a94dea2575ae193412c364c7f3a5fd.tar.gz
qemu-91699dbf30a94dea2575ae193412c364c7f3a5fd.tar.bz2
ppc/translate: Raise exceptions after setting the cc
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 <thatlemon@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20201112230130.65262-5-thatlemon@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/fpu_helper.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index f5a4be5..44315fc 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());
}