Signed-off-by: James Clarke <jrt...@jrtc27.com> --- target-ppc/cpu.h | 6 ++++++ target-ppc/translate.c | 15 +++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 3a967b7..d811bc9 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -718,6 +718,12 @@ enum { #define FP_RN1 (1ull << FPSCR_RN1) #define FP_RN (1ull << FPSCR_RN) +/* the exception bits which can be cleared by mcrfs - includes FX */ +#define FP_EX_CLEAR_BITS (FP_FX | FP_OX | FP_UX | FP_ZX | \ + FP_XX | FP_VXSNAN | FP_VXISI | FP_VXIDI | \ + FP_VXZDZ | FP_VXIMZ | FP_VXVC | FP_VXSOFT | \ + FP_VXSQRT | FP_VXCVI) + /*****************************************************************************/ /* Vector status and control register */ #define VSCR_NJ 16 /* Vector non-java */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 4be7eaa..989f683 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -2501,17 +2501,24 @@ static void gen_mcrfs(DisasContext *ctx) { TCGv tmp = tcg_temp_new(); int bfa; + int nibble; + int shift; if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; } - bfa = 4 * (7 - crfS(ctx->opcode)); - tcg_gen_shri_tl(tmp, cpu_fpscr, bfa); + bfa = crfS(ctx->opcode); + nibble = 7 - bfa; + shift = 4 * nibble; + tcg_gen_shri_tl(tmp, cpu_fpscr, shift); tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp); - tcg_temp_free(tmp); tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf); - tcg_gen_andi_tl(cpu_fpscr, cpu_fpscr, ~(0xF << bfa)); + /* Only the exception bits (including FX) should be cleared if read */ + tcg_gen_andi_tl(tmp, cpu_fpscr, ~((0xF << shift) & FP_EX_CLEAR_BITS)); + /* FEX and VX need to be updated, so don't set fpscr directly */ + gen_helper_store_fpscr(cpu_env, tmp, 1 << nibble); + tcg_temp_free(tmp); } /* mffs */ -- 2.7.0