Merge branch 'ppc-fixes'

This commit is contained in:
dingusdev 2020-02-27 21:03:40 -07:00
commit 5991ef1dca

View File

@ -120,6 +120,7 @@ void ppc_grab_regsfpsab(bool int_rep) {
ppc_result64_b = ppc_state.ppc_fpr[reg_b].int64_r;
}
else {
ppc_dblresult64_d = fp_return_double(reg_s);
ppc_dblresult64_a = fp_return_double(reg_a);
ppc_dblresult64_c = fp_return_double(reg_c);
}
@ -225,7 +226,19 @@ int64_t round_to_neg_inf(double f) {
return (int32_t)(floor(f));
}
bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uint32_t op) {
void ppc_toggle_fpscr_fex() {
bool fex_result = ((ppc_state.ppc_fpscr & 0x20000000) & (ppc_state.ppc_fpscr & 0x80));
fex_result |= ((ppc_state.ppc_fpscr & 0x10000000) & (ppc_state.ppc_fpscr & 0x40));
fex_result |= ((ppc_state.ppc_fpscr & 0x8000000) & (ppc_state.ppc_fpscr & 0x20));
fex_result |= ((ppc_state.ppc_fpscr & 0x4000000) & (ppc_state.ppc_fpscr & 0x10));
fex_result |= ((ppc_state.ppc_fpscr & 0x2000000) & (ppc_state.ppc_fpscr & 0x8));
ppc_state.ppc_fpscr |= (fex_result << 30);
}
bool ppc_confirm_inf_nan(uint32_t chosen_reg_1, uint32_t chosen_reg_2, bool is_single, uint32_t op) {
uint64_t input_a = ppc_state.ppc_fpr[chosen_reg_1].int64_r;
uint64_t input_b = ppc_state.ppc_fpr[chosen_reg_2].int64_r;
if (is_single) {
uint32_t exp_a = (input_a >> 23) & 0xff;
uint32_t exp_b = (input_b >> 23) & 0xff;
@ -236,22 +249,26 @@ bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uin
case 36:
if ((exp_a == 0xff) & (exp_b == 0xff)) {
ppc_state.ppc_fpscr |= 0x80400000;
ppc_toggle_fpscr_fex();
return true;
}
else if ((input_a == 0) & (input_b == 0)) {
ppc_state.ppc_fpscr |= 0x80200000;
ppc_toggle_fpscr_fex();
return true;
}
break;
case 40:
if ((exp_a == 0xff) & (exp_b == 0xff)) {
ppc_state.ppc_fpscr |= 0x80800000;
ppc_toggle_fpscr_fex();
return true;
}
break;
case 50:
if (((exp_a == 0xff) & (input_b == 0)) | ((exp_b == 0xff) & (input_a == 0))) {
ppc_state.ppc_fpscr |= 0x80100000;
ppc_toggle_fpscr_fex();
return true;
}
break;
@ -259,6 +276,7 @@ bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uin
case 58:
if ((exp_a == 0xff) & (exp_b == 0xff)) {
ppc_state.ppc_fpscr |= 0x80800000;
ppc_toggle_fpscr_fex();
return true;
}
break;
@ -276,22 +294,26 @@ bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uin
case 36:
if ((exp_a == 0x7ff) & (exp_b == 0x7ff)) {
ppc_state.ppc_fpscr |= 0x80400000;
ppc_toggle_fpscr_fex();
return true;
}
else if ((input_a == 0) & (input_b == 0)) {
ppc_state.ppc_fpscr |= 0x80200000;
ppc_toggle_fpscr_fex();
return true;
}
break;
case 40:
if ((exp_a == 0x7ff) & (exp_b == 0x7ff)) {
ppc_state.ppc_fpscr |= 0x80800000;
ppc_toggle_fpscr_fex();
return true;
}
break;
case 50:
if (((exp_a == 0x7ff) & (input_b == 0)) | ((exp_b == 0x7ff) & (input_a == 0))) {
ppc_state.ppc_fpscr |= 0x80100000;
ppc_toggle_fpscr_fex();
return true;
}
break;
@ -299,6 +321,7 @@ bool ppc_confirm_inf_nan(uint64_t input_a, uint64_t input_b, bool is_single, uin
case 58:
if ((exp_a == 0xff) & (exp_b == 0xff)) {
ppc_state.ppc_fpscr |= 0x80800000;
ppc_toggle_fpscr_fex();
return true;
}
break;
@ -322,7 +345,7 @@ void ppc_fpresult_update(uint64_t set_result, bool confirm_arc) {
ppc_state.ppc_fpscr |= 0x80010000;
ppc_state.ppc_fpscr &= 0xFFFF0FFF;
if (set_result == 0) {
ppc_state.ppc_fpscr |= 0x2000;
}
@ -356,7 +379,7 @@ void ppc_changecrf1() {
void ppc_fadd() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 58)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -365,7 +388,7 @@ void ppc_fadd() {
void ppc_fadddot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 58)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d = ppc_dblresult64_a + ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -375,7 +398,7 @@ void ppc_fadddot() {
void ppc_fsub() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 56)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) {
ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -384,7 +407,7 @@ void ppc_fsub() {
void ppc_fsubdot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 56)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 56)) {
ppc_dblresult64_d = ppc_dblresult64_a - ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -394,7 +417,7 @@ void ppc_fsubdot() {
void ppc_fdiv() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 36)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) {
ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -403,7 +426,7 @@ void ppc_fdiv() {
void ppc_fdivdot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 36)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 36)) {
ppc_dblresult64_d = ppc_dblresult64_a / ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -413,7 +436,7 @@ void ppc_fdivdot() {
void ppc_fmult() {
ppc_grab_regsfpdac(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 50)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 50)) {
ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -422,7 +445,7 @@ void ppc_fmult() {
void ppc_fmultdot() {
ppc_grab_regsfpdac(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, false, 50)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 50)) {
ppc_dblresult64_d = ppc_dblresult64_a * ppc_dblresult64_b;
ppc_store_dfpresult(false);
}
@ -433,8 +456,12 @@ void ppc_fmultdot() {
void ppc_fmadd() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
ppc_dblresult64_d += ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d += ppc_dblresult64_b;
}
}
ppc_store_dfpresult(false);
}
@ -442,8 +469,12 @@ void ppc_fmadd() {
void ppc_fmadddot() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
ppc_dblresult64_d += ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d += ppc_dblresult64_b;
}
}
ppc_store_dfpresult(false);
ppc_changecrf1();
@ -452,8 +483,12 @@ void ppc_fmadddot() {
void ppc_fmsub() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
ppc_dblresult64_d -= ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
ppc_dblresult64_d -= ppc_dblresult64_b;
}
}
ppc_store_dfpresult(false);
}
@ -461,8 +496,12 @@ void ppc_fmsub() {
void ppc_fmsubdot() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
ppc_dblresult64_d -= ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
ppc_dblresult64_d -= ppc_dblresult64_b;
}
}
ppc_store_dfpresult(false);
ppc_changecrf1();
@ -471,16 +510,27 @@ void ppc_fmsubdot() {
void ppc_fnmadd() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = ppc_dblresult64_a * ppc_result64_c;
ppc_dblresult64_d += -ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d += ppc_dblresult64_b;
}
}
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
}
void ppc_fnmadddot() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = ppc_dblresult64_a * ppc_result64_c;
ppc_dblresult64_d += ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_a, reg_b, false, 58)) {
ppc_dblresult64_d += ppc_dblresult64_b;
}
}
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
@ -490,8 +540,12 @@ void ppc_fnmadddot() {
void ppc_fnmsub() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = ppc_dblresult64_a * ppc_result64_c;
ppc_dblresult64_d -= ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
ppc_dblresult64_d -= ppc_dblresult64_b;
}
}
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
@ -500,8 +554,12 @@ void ppc_fnmsub() {
void ppc_fnmsubdot() {
ppc_grab_regsfpdabc(false);
ppc_dblresult64_d = ppc_dblresult64_a * ppc_result64_c;
ppc_dblresult64_d -= ppc_dblresult64_b;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
ppc_dblresult64_d = (ppc_dblresult64_a * ppc_dblresult64_c);
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
ppc_dblresult64_d -= ppc_dblresult64_b;
}
}
ppc_dblresult64_d = -ppc_dblresult64_d;
ppc_store_dfpresult(false);
@ -511,7 +569,7 @@ void ppc_fnmsubdot() {
void ppc_fadds() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 58)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
float intermediate = (float)ppc_dblresult64_a + (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -521,7 +579,7 @@ void ppc_fadds() {
void ppc_faddsdot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 58)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
float intermediate = (float)ppc_dblresult64_a + (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -533,7 +591,7 @@ void ppc_faddsdot() {
void ppc_fsubs() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 56)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) {
float intermediate = (float)ppc_dblresult64_a - (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -543,7 +601,7 @@ void ppc_fsubs() {
void ppc_fsubsdot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 56)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 56)) {
float intermediate = (float)ppc_dblresult64_a - (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -555,7 +613,7 @@ void ppc_fsubsdot() {
void ppc_fmults() {
ppc_grab_regsfpdac(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 50)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 50)) {
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -565,7 +623,7 @@ void ppc_fmults() {
void ppc_fmultsdot() {
ppc_grab_regsfpdac(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 50)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 50)) {
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
@ -577,7 +635,7 @@ void ppc_fmultsdot() {
void ppc_fdivs() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 36)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) {
float intermediate = (float)ppc_dblresult64_a / (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -587,7 +645,7 @@ void ppc_fdivs() {
void ppc_fdivsdot() {
ppc_grab_regsfpdab(false);
if (!ppc_confirm_inf_nan(ppc_result64_a, ppc_result64_b, true, 36)) {
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 36)) {
float intermediate = (float)ppc_dblresult64_a / (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
@ -599,52 +657,88 @@ void ppc_fdivsdot() {
void ppc_fmadds() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate += (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate += (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
}
void ppc_fmaddsdot() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate += (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate += (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
ppc_changecrf1();
}
void ppc_fmsubs() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate -= (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
intermediate -= (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
}
void ppc_fmsubsdot() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate -= (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
intermediate -= (float)ppc_dblresult64_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
ppc_changecrf1();
}
void ppc_fnmadds() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate += (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate += (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
}
}
ppc_store_dfpresult(false);
}
@ -652,35 +746,58 @@ void ppc_fnmadds() {
void ppc_fnmaddsdot() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate += (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_a, reg_b, true, 58)) {
intermediate += (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
ppc_changecrf1();
}
void ppc_fnmsubs() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate -= (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
intermediate -= (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_store_dfpresult(false);
}
void ppc_fnmsubsdot() {
ppc_grab_regsfpdabc(false);
float intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
intermediate -= (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
float intermediate;
ppc_store_dfpresult(false);
if (!ppc_confirm_inf_nan(reg_a, reg_c, false, 50)) {
intermediate = (float)ppc_dblresult64_a * (float)ppc_dblresult64_c;
if (!ppc_confirm_inf_nan(reg_d, reg_b, false, 56)) {
intermediate -= (float)ppc_dblresult64_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_dfpresult(false);
}
}
ppc_changecrf1();
}