summaryrefslogtreecommitdiffstats
path: root/target/ppc/translate
diff options
context:
space:
mode:
authorLucas Mateus Castro (alqotel)2021-12-17 17:57:12 +0100
committerCédric Le Goater2021-12-17 17:57:12 +0100
commitc3a824b0cf23f98353fa91c715fe4918432d7928 (patch)
tree27950607a47f2f2391b188f9d37ad41f44990bb3 /target/ppc/translate
parenthw/ppc/mac.h: Remove MAX_CPUS macro (diff)
downloadqemu-c3a824b0cf23f98353fa91c715fe4918432d7928.tar.gz
qemu-c3a824b0cf23f98353fa91c715fe4918432d7928.tar.xz
qemu-c3a824b0cf23f98353fa91c715fe4918432d7928.zip
target/ppc: Fixed call to deferred exception
mtfsf, mtfsfi and mtfsb1 instructions call helper_float_check_status after updating the value of FPSCR, but helper_float_check_status checks fp_status and fp_status isn't updated based on FPSCR and since the value of fp_status is reset earlier in the instruction, it's always 0. Because of this helper_float_check_status would change the FI bit to 0 as this bit checks if the last operation was inexact and float_flag_inexact is always 0. These instructions also don't throw exceptions correctly since helper_float_check_status throw exceptions based on fp_status. This commit created a new helper, helper_fpscr_check_status that checks FPSCR value instead of fp_status and checks for a larger variety of exceptions than do_float_check_status. Since fp_status isn't used, gen_reset_fpstatus() was removed. The hardware used to compare QEMU's behavior to was a Power9. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br> Message-Id: <20211201163808.440385-2-lucas.araujo@eldorado.org.br> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'target/ppc/translate')
-rw-r--r--target/ppc/translate/fp-impl.c.inc9
1 files changed, 3 insertions, 6 deletions
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index c9e05201d9..8afd6a087d 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -769,7 +769,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;
@@ -782,7 +781,7 @@ static void gen_mtfsb1(DisasContext *ctx)
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
}
/* We can raise a deferred exception */
- gen_helper_float_check_status(cpu_env);
+ gen_helper_fpscr_check_status(cpu_env);
}
/* mtfsf */
@@ -803,7 +802,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 {
@@ -818,7 +816,7 @@ static void gen_mtfsf(DisasContext *ctx)
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
}
/* We can raise a deferred exception */
- gen_helper_float_check_status(cpu_env);
+ gen_helper_fpscr_check_status(cpu_env);
tcg_temp_free_i64(t1);
}
@@ -840,7 +838,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);
@@ -851,7 +848,7 @@ static void gen_mtfsfi(DisasContext *ctx)
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
}
/* We can raise a deferred exception */
- gen_helper_float_check_status(cpu_env);
+ gen_helper_fpscr_check_status(cpu_env);
}
static void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 dest, TCGv addr)