From 5f826d6a9daf77e59a2374015c5fdc9d3c785d40 Mon Sep 17 00:00:00 2001 From: dingusdev <52434309+dingusdev@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:51:16 -0700 Subject: [PATCH] More floating point fixes Down to 752 failing tests --- cpu/ppc/ppcfpopcodes.cpp | 75 +++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/cpu/ppc/ppcfpopcodes.cpp b/cpu/ppc/ppcfpopcodes.cpp index aa0cf68..7e4e9e8 100644 --- a/cpu/ppc/ppcfpopcodes.cpp +++ b/cpu/ppc/ppcfpopcodes.cpp @@ -237,11 +237,11 @@ void dppc_interpreter::ppc_fdiv() { snan_double_check(reg_a, reg_b); double ppc_dblresult64_d = val_reg_a / val_reg_b; + if (val_reg_b == 0.0) { - ppc_state.fpscr |= FX + VX; + ppc_state.fpscr |= 0xa0000000; + ppc_dblresult64_d = -ppc_dblresult64_d; } - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); if (std::isinf(val_reg_a) && std::isinf(val_reg_b)) { ppc_state.fpscr |= VXIDI; @@ -254,6 +254,9 @@ void dppc_interpreter::ppc_fdiv() { } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -268,8 +271,6 @@ void dppc_interpreter::ppc_fmul() { snan_double_check(reg_a, reg_c); double ppc_dblresult64_d = val_reg_a * val_reg_c; - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { @@ -279,6 +280,10 @@ void dppc_interpreter::ppc_fmul() { } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + + if (rec) ppc_update_cr1(); } @@ -294,8 +299,6 @@ void dppc_interpreter::ppc_fmadd() { snan_single_check(reg_b); double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b); - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); double inf = std::numeric_limits::infinity(); if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) @@ -309,6 +312,10 @@ void dppc_interpreter::ppc_fmadd() { } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + + if (rec) ppc_update_cr1(); } @@ -324,8 +331,6 @@ void dppc_interpreter::ppc_fmsub() { snan_single_check(reg_b); double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, -val_reg_b); - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { @@ -333,18 +338,19 @@ void dppc_interpreter::ppc_fmsub() { if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } - } double inf = std::numeric_limits::infinity(); - if (((val_reg_a == inf) && (val_reg_b == -inf)) || \ - ((val_reg_a == -inf) && (val_reg_b == inf))) { + if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) { ppc_state.fpscr |= VXISI; if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -360,15 +366,13 @@ void dppc_interpreter::ppc_fnmadd() { snan_single_check(reg_b); double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b); + if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); } - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); double inf = std::numeric_limits::infinity(); - if (((val_reg_a == inf) && (val_reg_b == -inf)) || \ - ((val_reg_a == -inf) && (val_reg_b == inf))) { + if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) { ppc_state.fpscr |= VXISI; if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); @@ -383,6 +387,10 @@ void dppc_interpreter::ppc_fnmadd() { } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + + if (rec) ppc_update_cr1(); } @@ -398,10 +406,8 @@ void dppc_interpreter::ppc_fnmsub() { snan_single_check(reg_b); double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, -val_reg_b); - ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); - if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || \ + if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { ppc_state.fpscr |= VXIMZ; if (std::isnan(ppc_dblresult64_d)) { @@ -410,14 +416,16 @@ void dppc_interpreter::ppc_fnmsub() { } double inf = std::numeric_limits::infinity(); - if (((val_reg_a == inf) && (val_reg_b == -inf)) || \ - ((val_reg_a == -inf) && (val_reg_b == inf))) { + if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) { ppc_state.fpscr |= VXISI; if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d); } } + ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -432,7 +440,6 @@ void dppc_interpreter::ppc_fadds() { snan_double_check(reg_a, reg_b); double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b); - ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); double inf = std::numeric_limits::infinity(); if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) { @@ -442,6 +449,7 @@ void dppc_interpreter::ppc_fadds() { } } + ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); fpresult_update(ppc_dblresult64_d); if (rec) @@ -489,7 +497,8 @@ void dppc_interpreter::ppc_fdivs() { double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b); if (val_reg_b == 0.0) { - ppc_state.fpscr |= FX + VX; + ppc_state.fpscr |= 0xa0000000; + ppc_dblresult64_d = -ppc_dblresult64_d; } if (std::isinf(val_reg_a) && std::isinf(val_reg_b)) { @@ -548,8 +557,6 @@ void dppc_interpreter::ppc_fmadds() { snan_single_check(reg_b); double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, val_reg_b); - ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); double inf = std::numeric_limits::infinity(); if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) @@ -567,6 +574,9 @@ void dppc_interpreter::ppc_fmadds() { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); } + ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -586,8 +596,6 @@ void dppc_interpreter::ppc_fmsubs() { if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); } - ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { @@ -601,6 +609,9 @@ void dppc_interpreter::ppc_fmsubs() { if ((val_reg_a == inf) && (val_reg_b == inf)) ppc_state.fpscr |= VXISI; + ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -619,8 +630,6 @@ void dppc_interpreter::ppc_fnmadds() { if (std::isnan(ppc_dblresult64_d)) { ppc_dblresult64_d = std::numeric_limits::quiet_NaN(); } - ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); double inf = std::numeric_limits::infinity(); if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf))) @@ -634,6 +643,9 @@ void dppc_interpreter::ppc_fnmadds() { } } + ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); } @@ -649,8 +661,6 @@ void dppc_interpreter::ppc_fnmsubs() { snan_single_check(reg_b); double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, -val_reg_b); - ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); - fpresult_update(ppc_dblresult64_d); if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) || (std::isinf(val_reg_c) && (val_reg_a == 0.0))) { @@ -664,6 +674,9 @@ void dppc_interpreter::ppc_fnmsubs() { if ((val_reg_a == inf) && (val_reg_b == inf)) ppc_state.fpscr |= VXISI; + ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d); + fpresult_update(ppc_dblresult64_d); + if (rec) ppc_update_cr1(); }