From 2d65ed47fc57279c83cd606d5e3389fd0b470d40 Mon Sep 17 00:00:00 2001 From: dingusdev Date: Sat, 9 Oct 2021 19:42:25 -0700 Subject: [PATCH] Floating point overhaul, part 2 Further formatting fixes. Removed obsoleted separation definitions. Fixed rounding to nearest. --- cpu/ppc/ppcemu.h | 6 +-- cpu/ppc/ppcfpopcodes.cpp | 104 +++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 65 deletions(-) diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index 997b992..a4bacb2 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -202,6 +202,7 @@ enum class BB_end_kind { enum class CR_select { CR0_field = (0xF << 28), + CR1_field = (0xF << 24), }; enum class CRx_bit { @@ -479,15 +480,10 @@ extern void ppc_mtspr(); extern void ppc_mtfsb0(); extern void ppc_mtfsb1(); extern void ppc_mcrfs(); -extern void ppc_mtfsb0dot(); -extern void ppc_mtfsb1dot(); extern void ppc_fmr(); extern void ppc_mffs(); -extern void ppc_mffsdot(); extern void ppc_mtfsf(); -extern void ppc_mtfsfdot(); extern void ppc_mtfsfi(); -extern void ppc_mtfsfidot(); extern void ppc_addi(); extern void ppc_addic(); diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index e247c41..9bfd5ee 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -162,9 +162,9 @@ void ppc_divbyzero(uint64_t input_a, uint64_t input_b, bool is_single) { int64_t round_to_nearest(double f) { if (f >= 0.0) { - return static_cast(static_cast (f + 0.5)); + return static_cast(static_cast (ceil(f))); } else { - return static_cast(static_cast (-f + 0.5)); + return static_cast(static_cast (floor(f))); } } @@ -290,8 +290,8 @@ void fpresult_update(double set_result, bool confirm_arc) { } void ppc_changecrf1() { - ppc_state.cr &= 0xF0FFFFFF; - ppc_state.cr |= (ppc_state.fpscr & 0xF0000000) >> 4; + ppc_state.cr &= ~((uint32_t)CR_select::CR1_field); + ppc_state.cr |= (ppc_state.fpscr & (uint32_t)CR_select::CR0_field) >> 4; } // Floating Point Arithmetic @@ -558,7 +558,7 @@ void dppc_interpreter::ppc_fneg() { void dppc_interpreter::ppc_fsel() { ppc_grab_regsfpdabc(); - ppc_dblresult64_d = (val_reg_a >= 0.0) ? val_reg_c : val_reg_b; + ppc_dblresult64_d = (val_reg_a >= -0.0) ? val_reg_c : val_reg_b; ppc_store_dfpresult_flt(reg_d); @@ -613,11 +613,23 @@ void dppc_interpreter::ppc_frsp() { void dppc_interpreter::ppc_fres() { ppc_grab_regsfpdb(); - float testf2 = (float)GET_FPR(reg_b); + double start_num = GET_FPR(reg_b); + float testf2 = (float)start_num; testf2 = 1 / testf2; ppc_dblresult64_d = (double)testf2; ppc_store_dfpresult_flt(reg_d); + if (start_num == 0.0) { + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_ZX; + } + else if (std::isnan(start_num)) { + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXSNAN; + } + else if (std::isinf(start_num)){ + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXSNAN; + ppc_state.fpscr &= 0xFFF9FFFF; + } + if (rc_flag) ppc_changecrf1(); } @@ -628,15 +640,15 @@ void dppc_interpreter::ppc_fctiw() { if (std::isnan(val_reg_b)) { ppc_state.fpr[reg_d].int64_r = 0x80000000; - ppc_state.fpscr |= 0x1000100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXSNAN | (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else if (val_reg_b > static_cast(0x7fffffff)) { ppc_state.fpr[reg_d].int64_r = 0x7fffffff; - ppc_state.fpscr |= 0x100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else if (val_reg_b < -static_cast(0x80000000)) { ppc_state.fpr[reg_d].int64_r = 0x80000000; - ppc_state.fpscr |= 0x100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else { switch (ppc_state.fpscr & 0x3) { @@ -668,15 +680,15 @@ void dppc_interpreter::ppc_fctiwz() { if (std::isnan(val_reg_b)) { ppc_state.fpr[reg_d].int64_r = 0x80000000; - ppc_state.fpscr |= 0x1000100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXSNAN | (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else if (val_reg_b > static_cast(0x7fffffff)) { ppc_state.fpr[reg_d].int64_r = 0x7fffffff; - ppc_state.fpscr |= 0x100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else if (val_reg_b < -static_cast(0x80000000)) { ppc_state.fpr[reg_d].int64_r = 0x80000000; - ppc_state.fpscr |= 0x100; + ppc_state.fpscr |= (uint32_t)FPSCR_bit::FPSCR_VXCVI; } else { ppc_result64_d = round_to_zero(val_reg_b); @@ -873,22 +885,23 @@ void dppc_interpreter::ppc_fmr() { ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r; } - void dppc_interpreter::ppc_mffs() { ppc_grab_regsda(); - uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000; - uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF; - fpstore1 |= fpstore2; - fp_save_uint64(fpstore1); -} + uint64_t fpstore1 = 0; -void dppc_interpreter::ppc_mffsdot() { - ppc_grab_regsda(); - uint64_t fpstore1 = ppc_state.fpr[reg_d].int64_r & 0xFFFFFFFF00000000; - uint64_t fpstore2 = ppc_state.fpscr & 0x00000000FFFFFFFF; + if (ppc_state.spr[SPR::PVR] == PPC_VER::MPC601) { + fpstore1 = ppc_state.fpr[reg_d].int64_r & ((uint64_t)0xFFF80000 << 32); + } + else { + fpstore1 = ppc_state.fpr[reg_d].int64_r & ((uint64_t)0xFFFFFFFF << 32); + } + + uint64_t fpstore2 = ppc_state.fpscr & (uint64_t)0xFFFFFFFF; fpstore1 |= fpstore2; fp_save_uint64(fpstore1); - ppc_fp_changecrf1(); + + if (rc_flag) + ppc_fp_changecrf1(); } void dppc_interpreter::ppc_mtfsf() { @@ -904,22 +917,9 @@ void dppc_interpreter::ppc_mtfsf() { crm += (((fm_mask >> 7) & 1) == 1) ? 0x0000000F : 0x00000000; uint32_t quickfprval = (uint32_t)ppc_state.fpr[reg_b].int64_r; ppc_state.fpscr = (quickfprval & crm) | (quickfprval & ~(crm)); -} -void dppc_interpreter::ppc_mtfsfdot() { - reg_b = (ppc_cur_instruction >> 11) & 31; - uint32_t fm_mask = (ppc_cur_instruction >> 17) & 255; - crm += ((fm_mask & 1) == 1) ? 0xF0000000 : 0x00000000; - crm += (((fm_mask >> 1) & 1) == 1) ? 0x0F000000 : 0x00000000; - crm += (((fm_mask >> 2) & 1) == 1) ? 0x00F00000 : 0x00000000; - crm += (((fm_mask >> 3) & 1) == 1) ? 0x000F0000 : 0x00000000; - crm += (((fm_mask >> 4) & 1) == 1) ? 0x0000F000 : 0x00000000; - crm += (((fm_mask >> 5) & 1) == 1) ? 0x00000F00 : 0x00000000; - crm += (((fm_mask >> 6) & 1) == 1) ? 0x000000F0 : 0x00000000; - crm += (((fm_mask >> 7) & 1) == 1) ? 0x0000000F : 0x00000000; - uint32_t quickfprval = (uint32_t)ppc_state.fpr[reg_b].int64_r; - ppc_state.fpscr = (quickfprval & crm) | (quickfprval & ~(crm)); - ppc_fp_changecrf1(); + if (rc_flag) + ppc_fp_changecrf1(); } void dppc_interpreter::ppc_mtfsfi() { @@ -928,15 +928,9 @@ void dppc_interpreter::ppc_mtfsfi() { crf_d = crf_d << 2; ppc_state.fpscr = (ppc_state.cr & ~(0xF0000000UL >> crf_d)) | ((ppc_state.spr[SPR::XER] & 0xF0000000UL) >> crf_d); -} -void dppc_interpreter::ppc_mtfsfidot() { - 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); - ppc_fp_changecrf1(); + if (rc_flag) + ppc_fp_changecrf1(); } void dppc_interpreter::ppc_mtfsb0() { @@ -944,14 +938,9 @@ void dppc_interpreter::ppc_mtfsb0() { if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr &= ~(0x80000000UL >> crf_d); } -} -void dppc_interpreter::ppc_mtfsb0dot() { - crf_d = (ppc_cur_instruction >> 21) & 0x1F; - if ((crf_d == 0) || (crf_d > 2)) { - ppc_state.fpscr &= ~(0x80000000UL >> crf_d); - } - ppc_fp_changecrf1(); + if (rc_flag) + ppc_fp_changecrf1(); } void dppc_interpreter::ppc_mtfsb1() { @@ -959,14 +948,9 @@ void dppc_interpreter::ppc_mtfsb1() { if ((crf_d == 0) || (crf_d > 2)) { ppc_state.fpscr |= (0x80000000UL >> crf_d); } -} -void dppc_interpreter::ppc_mtfsb1dot() { - crf_d = (ppc_cur_instruction >> 21) & 0x1F; - if ((crf_d == 0) || (crf_d > 2)) { - ppc_state.fpscr |= (0x80000000UL >> crf_d); - } - ppc_fp_changecrf1(); + if (rc_flag) + ppc_fp_changecrf1(); } void dppc_interpreter::ppc_mcrfs() {