From 8595dd7d992d1bd3194752c946b8d5fa6047062d Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Tue, 2 Jan 2024 16:12:12 +0100 Subject: [PATCH] ppcfpopcodes: fix mtfsfi emulation. --- cpu/ppc/ppcfpopcodes.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index 1adf991..14facc5 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -892,11 +892,16 @@ void dppc_interpreter::ppc_mtfsf() { } void dppc_interpreter::ppc_mtfsfi() { - ppc_result_b = (ppc_cur_instruction >> 11) & 15; - crf_d = (ppc_cur_instruction >> 23) & 7; - crf_d = crf_d << 2; - ppc_state.fpscr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) | - ((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d); + int crf_d = (ppc_cur_instruction >> 21) & 0x1C; + uint32_t imm = (ppc_cur_instruction << 16) & 0xF0000000UL; + + // prepare field mask and ensure that neither FEX nor VX will be changed + uint32_t mask = (0xF0000000UL >> crf_d) & ~(FPSCR::FEX | FPSCR::VX); + + // copy imm to FPSCR[crf_d] under control of the field mask + ppc_state.fpscr = (ppc_state.fpscr & ~mask) | ((imm >> crf_d) & mask); + + // TODO: update FEX and VX according to the "usual rule" if (rc_flag) ppc_update_cr1();