Continued FPU fixes

This commit is contained in:
dingusdev 2024-10-30 07:46:44 -07:00
parent 5f826d6a9d
commit f660efcd54

View File

@ -185,6 +185,7 @@ void dppc_interpreter::ppc_fadd() {
ppc_dblresult64_d = set_endresult_nan(ppc_dblresult64_d);
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
@ -254,6 +255,10 @@ void dppc_interpreter::ppc_fdiv() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -280,6 +285,10 @@ void dppc_interpreter::ppc_fmul() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -301,8 +310,13 @@ void dppc_interpreter::ppc_fmadd() {
double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
double inf = std::numeric_limits<double>::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);
}
}
if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) ||
(std::isinf(val_reg_c) && (val_reg_a == 0.0))) {
@ -312,6 +326,10 @@ void dppc_interpreter::ppc_fmadd() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -348,6 +366,10 @@ void dppc_interpreter::ppc_fmsub() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -387,6 +409,10 @@ void dppc_interpreter::ppc_fnmadd() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -423,6 +449,10 @@ void dppc_interpreter::ppc_fnmsub() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -438,6 +468,7 @@ void dppc_interpreter::ppc_fadds() {
ppc_grab_regsfpdab(ppc_cur_instruction);
snan_double_check(reg_a, reg_b);
max_double_check(val_reg_a, val_reg_b);
double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b);
@ -449,6 +480,10 @@ void dppc_interpreter::ppc_fadds() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -512,6 +547,10 @@ void dppc_interpreter::ppc_fdivs() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -538,6 +577,10 @@ void dppc_interpreter::ppc_fmuls() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -570,9 +613,9 @@ void dppc_interpreter::ppc_fmadds() {
}
}
if (std::isnan(val_reg_b)) {
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -593,9 +636,6 @@ void dppc_interpreter::ppc_fmsubs() {
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
if (std::isnan(ppc_dblresult64_d)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
if ((std::isinf(val_reg_a) && (val_reg_c == 0.0)) ||
(std::isinf(val_reg_c) && (val_reg_a == 0.0))) {
@ -609,6 +649,10 @@ void dppc_interpreter::ppc_fmsubs() {
if ((val_reg_a == inf) && (val_reg_b == inf))
ppc_state.fpscr |= VXISI;
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -643,6 +687,10 @@ void dppc_interpreter::ppc_fnmadds() {
}
}
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -674,6 +722,10 @@ void dppc_interpreter::ppc_fnmsubs() {
if ((val_reg_a == inf) && (val_reg_b == inf))
ppc_state.fpscr |= VXISI;
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
fpresult_update(ppc_dblresult64_d);
@ -692,6 +744,10 @@ void dppc_interpreter::ppc_fabs() {
double ppc_dblresult64_d = abs(GET_FPR(reg_b));
if (std::isnan(GET_FPR(reg_b))) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
if (rec)
@ -710,6 +766,10 @@ void dppc_interpreter::ppc_fnabs() {
double ppc_dblresult64_d = abs(GET_FPR(reg_b));
ppc_dblresult64_d = -ppc_dblresult64_d;
if (std::isnan(GET_FPR(reg_b))) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
if (rec)
@ -727,6 +787,10 @@ void dppc_interpreter::ppc_fneg() {
double ppc_dblresult64_d = -(GET_FPR(reg_b));
if (std::isnan(GET_FPR(reg_b))) {
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
if (rec)