Continued clean-up

This commit is contained in:
dingusdev 2023-11-23 16:56:58 -07:00
parent ada68ffc71
commit 4753ba5361
2 changed files with 98 additions and 111 deletions

View File

@ -43,7 +43,7 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
break;
case Except_Type::EXC_MACHINE_CHECK:
if (!(ppc_state.msr & 0x1000)) {
if (!(ppc_state.msr & MSR::ME)) {
/* TODO: handle internal checkstop */
}
ppc_state.spr[SPR::SRR0] = ppc_state.pc & 0xFFFFFFFC;
@ -117,7 +117,7 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
/* copy MSR[ILE] to MSR[LE] */
ppc_state.msr = (ppc_state.msr & 0xFFFFFFFE) | ((ppc_state.msr >> 16) & 1);
if (ppc_state.msr & 0x40) {
if (ppc_state.msr & MSR::IP) {
ppc_next_instruction_address |= 0xFFF00000;
}

View File

@ -170,10 +170,9 @@ void update_fex() {
}
template <typename T, const FPOP fpop>
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3, bool rc_flag = false) {
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool rc_flag = false) {
T input_a = T(ppc_state.fpr[chosen_reg_1].dbl64_r);
T input_b = T(ppc_state.fpr[chosen_reg_2].dbl64_r);
T input_c = T(ppc_state.fpr[chosen_reg_3].dbl64_r);
ppc_state.fpscr &= 0x7fbfffff;
@ -208,29 +207,10 @@ void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, int chosen_reg_3, b
update_fex();
break;
case FPOP::MUL:
if (std::isnan(input_a) && std::isnan(input_c)) {
if (std::isnan(input_a) && std::isnan(input_b)) {
ppc_state.fpscr |= (FPSCR::FX);
}
update_fex();
break;
case FPOP::FMSUB:
case FPOP::FNMSUB:
if (std::isnan(input_a) || std::isnan(input_b) || std::isnan(input_c)) {
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXSNAN);
if (((input_a == FP_ZERO) && (input_c == FP_INFINITE)) ||
((input_c == FP_ZERO) && (input_a == FP_INFINITE))) {
ppc_state.fpscr |= FPSCR::VXIMZ;
}
}
update_fex();
break;
case FPOP::FMADD:
case FPOP::FNMADD:
if (std::isnan(input_a) || std::isnan(input_b) || std::isnan(input_c)) {
ppc_state.fpscr |= (FPSCR::VXSNAN | FPSCR::FPCC_FUNAN);
}
update_fex();
break;
}
@ -240,7 +220,10 @@ static void fpresult_update(double set_result, bool confirm_arc) {
if (ppc_state.fpscr & 0x3)
ppc_state.cr |= 0x2;
if (set_result > 0.0) {
if (std::isnan(set_result)) {
ppc_state.fpscr |= FPCC_FUNAN;
}
else if (set_result > 0.0) {
ppc_state.fpscr |= FPCC_POS;
} else if (set_result < 0.0) {
ppc_state.fpscr |= FPCC_NEG;
@ -280,12 +263,9 @@ void ppc_changecrf1(double set_result) {
void dppc_interpreter::ppc_fadd() {
ppc_grab_regsfpdab();
if ((val_reg_a == DBL_MAX) || (val_reg_b == DBL_MAX)) {
ppc_state.fpscr |= FX | OX | XX;
}
else if(std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_state.fpscr |= FPCC_FUNAN;
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, 0, rc_flag);
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = double(val_reg_a + val_reg_b);
@ -299,11 +279,9 @@ void dppc_interpreter::ppc_fadd() {
void dppc_interpreter::ppc_fsub() {
ppc_grab_regsfpdab();
if ((val_reg_a == DBL_MAX) || (val_reg_b == DBL_MAX)) {
ppc_state.fpscr |= FX | OX | XX;
} else if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_state.fpscr |= FPCC_FUNAN;
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, 0, rc_flag);
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = double(val_reg_a - val_reg_b);
@ -317,10 +295,8 @@ void dppc_interpreter::ppc_fsub() {
void dppc_interpreter::ppc_fdiv() {
ppc_grab_regsfpdab();
if (val_reg_b == 0.0) {
ppc_state.fpscr |= FX | OX | XX;
} else if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, DIV>(reg_a, reg_b, 0, rc_flag);
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, DIV>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = val_reg_a / val_reg_b;
@ -334,12 +310,8 @@ void dppc_interpreter::ppc_fdiv() {
void dppc_interpreter::ppc_fmul() {
ppc_grab_regsfpdac();
if (((val_reg_a == FP_ZERO) && (val_reg_c == FP_INFINITE)) ||
((val_reg_c == FP_ZERO) && (val_reg_a == FP_INFINITE))) {
ppc_state.fpscr |= (FPSCR::FX | FPSCR::VXSNAN | FPSCR::VXIMZ);
}
else if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_b, 0, rc_flag);
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
ppc_dblresult64_d = val_reg_a * val_reg_c;
@ -353,8 +325,11 @@ void dppc_interpreter::ppc_fmul() {
void dppc_interpreter::ppc_fmadd() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, FMADD>(reg_a, reg_b, reg_c);
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -368,9 +343,11 @@ void dppc_interpreter::ppc_fmadd() {
void dppc_interpreter::ppc_fmsub() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, FMSUB>(reg_a, reg_b, reg_c);
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = (val_reg_a * val_reg_c);
@ -385,8 +362,11 @@ void dppc_interpreter::ppc_fmsub() {
void dppc_interpreter::ppc_fnmadd() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, FNMADD>(reg_a, reg_b, reg_c);
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -418,14 +398,14 @@ void dppc_interpreter::ppc_fnmsub() {
void dppc_interpreter::ppc_fadds() {
ppc_grab_regsfpdab();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<float, SUB>(reg_a, reg_b, rc_flag);
}
float ppc_fltresult32_d = (float)(val_reg_a) + (float)val_reg_b;
ppc_dblresult64_d = (double)ppc_fltresult32_d;
ppc_store_sfpresult_flt(reg_d);
if (std::isnan(ppc_dblresult64_d)) {
ppc_confirm_inf_nan<float, ADD>(reg_a, reg_b, 0, rc_flag);
}
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
@ -435,14 +415,13 @@ void dppc_interpreter::ppc_fadds() {
void dppc_interpreter::ppc_fsubs() {
ppc_grab_regsfpdab();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<float, SUB>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
ppc_store_sfpresult_flt(reg_d);
if (!std::isnan(ppc_dblresult64_d)) {
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, SUB>(reg_a, reg_b, 0, rc_flag);
}
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -451,15 +430,13 @@ void dppc_interpreter::ppc_fsubs() {
void dppc_interpreter::ppc_fdivs() {
ppc_grab_regsfpdab();
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<float, DIV>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
ppc_store_sfpresult_flt(reg_d);
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, DIV>(reg_a, reg_b, 0, rc_flag);
}
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -468,31 +445,32 @@ void dppc_interpreter::ppc_fdivs() {
void dppc_interpreter::ppc_fmuls() {
ppc_grab_regsfpdac();
ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, MUL>(reg_a, 0, reg_c, rc_flag);
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<float, MUL>(reg_a, reg_c, rc_flag);
}
ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
}
void dppc_interpreter::ppc_fmadds() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
ppc_dblresult64_d = static_cast<double>(
std::fma((float)val_reg_a, (float)val_reg_c, (float)val_reg_b));
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FMADD>(reg_a, reg_b, reg_c, rc_flag);
}
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -501,16 +479,18 @@ void dppc_interpreter::ppc_fmadds() {
void dppc_interpreter::ppc_fmsubs() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
float intermediate = float(val_reg_a * val_reg_c);
intermediate -= (float)val_reg_b;
ppc_dblresult64_d = static_cast<double>(intermediate);
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FMSUB>(reg_a, reg_b, reg_c, rc_flag);
}
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -519,17 +499,19 @@ void dppc_interpreter::ppc_fmsubs() {
void dppc_interpreter::ppc_fnmadds() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, ADD>(reg_a, reg_b, rc_flag);
}
float intermediate = (float)val_reg_a * (float)val_reg_c;
intermediate += (float)val_reg_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FNMADD>(reg_a, reg_b, reg_c, rc_flag);
}
ppc_dblresult64_d = static_cast<double>(intermediate);
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -538,18 +520,20 @@ void dppc_interpreter::ppc_fnmadds() {
void dppc_interpreter::ppc_fnmsubs() {
ppc_grab_regsfpdabc();
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
ppc_confirm_inf_nan<double, MUL>(reg_a, reg_c, rc_flag);
}
if (std::isnan(val_reg_b)) {
ppc_confirm_inf_nan<double, SUB>(reg_a, reg_b, rc_flag);
}
float intermediate = (float)val_reg_a * (float)val_reg_c;
intermediate -= (float)val_reg_b;
intermediate = -intermediate;
ppc_dblresult64_d = static_cast<double>(intermediate);
if (!std::isnan(ppc_dblresult64_d)) {
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
} else {
ppc_confirm_inf_nan<float, FNMSUB>(reg_a, reg_b, reg_c, rc_flag);
}
ppc_store_sfpresult_flt(reg_d);
fpresult_update(ppc_dblresult64_d, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -601,10 +585,11 @@ void dppc_interpreter::ppc_fsel() {
}
void dppc_interpreter::ppc_fsqrt() {
ppc_grab_regsfpdb();
ppc_dblresult64_d = std::sqrt(GET_FPR(reg_b));
ppc_grab_regsfpdb();
double testd2 = (double)(GET_FPR(reg_b));
ppc_dblresult64_d = std::sqrt(testd2);
ppc_store_dfpresult_flt(reg_d);
ppc_confirm_inf_nan<double, SQRT>(0, reg_b, 0, rc_flag);
ppc_confirm_inf_nan<double, SQRT>(0, reg_b, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -612,9 +597,10 @@ void dppc_interpreter::ppc_fsqrt() {
void dppc_interpreter::ppc_fsqrts() {
ppc_grab_regsfpdb();
ppc_dblresult64_d = (float)std::sqrt(GET_FPR(reg_b));
double testd2 = (double)(GET_FPR(reg_b));
ppc_dblresult64_d = (float)std::sqrt(testd2);
ppc_store_sfpresult_flt(reg_d);
ppc_confirm_inf_nan<float, SQRT>(0, reg_b, 0, rc_flag);
ppc_confirm_inf_nan<float, SQRT>(0, reg_b, rc_flag);
if (rc_flag)
ppc_changecrf1(ppc_dblresult64_d);
@ -624,6 +610,7 @@ void dppc_interpreter::ppc_frsqrte() {
ppc_grab_regsfpdb();
double testd2 = (double)(GET_FPR(reg_b));
ppc_dblresult64_d = 1.0 / sqrt(testd2);
ppc_confirm_inf_nan<float, SQRT>(0, reg_b, rc_flag);
ppc_store_dfpresult_flt(reg_d);
@ -655,8 +642,8 @@ void dppc_interpreter::ppc_fres() {
ppc_state.fpscr |= FPSCR::VXSNAN;
}
else if (std::isinf(start_num)){
ppc_state.fpscr |= FPSCR::VXSNAN;
ppc_state.fpscr &= 0xFFF9FFFF;
ppc_state.fpscr |= FPSCR::VXSNAN;
}
if (rc_flag)