mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-02 21:30:40 +00:00
Floating-point fix-ups
Largely to fix setting flags, but partially to fix the incorrect nan emulation
This commit is contained in:
parent
b3eb1f6419
commit
329bcc68b1
@ -7,6 +7,7 @@
|
|||||||
- maximumspatium
|
- maximumspatium
|
||||||
- joevt
|
- joevt
|
||||||
- mihaip
|
- mihaip
|
||||||
|
- kkaisershot
|
||||||
|
|
||||||
## NT4/PPC fork
|
## NT4/PPC fork
|
||||||
|
|
||||||
|
@ -128,6 +128,18 @@ static void fpresult_update(double set_result) {
|
|||||||
ppc_state.fpscr |= FPCC_ZERO;
|
ppc_state.fpscr |= FPCC_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std::fetestexcept(FE_OVERFLOW)) {
|
||||||
|
ppc_state.fpscr |= (OX + FX);
|
||||||
|
}
|
||||||
|
if (std::fetestexcept(FE_UNDERFLOW)) {
|
||||||
|
ppc_state.fpscr |= (UX + FX);
|
||||||
|
}
|
||||||
|
if (std::fetestexcept(FE_DIVBYZERO)) {
|
||||||
|
ppc_state.fpscr |= (ZX + FX);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
|
||||||
if (std::isinf(set_result))
|
if (std::isinf(set_result))
|
||||||
ppc_state.fpscr |= FPCC_FUNAN;
|
ppc_state.fpscr |= FPCC_FUNAN;
|
||||||
}
|
}
|
||||||
@ -160,6 +172,12 @@ void dppc_interpreter::ppc_fadd() {
|
|||||||
max_double_check(val_reg_a, val_reg_b);
|
max_double_check(val_reg_a, val_reg_b);
|
||||||
|
|
||||||
double ppc_dblresult64_d = val_reg_a + val_reg_b;
|
double ppc_dblresult64_d = val_reg_a + 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)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
ppc_update_fex();
|
ppc_update_fex();
|
||||||
@ -179,8 +197,13 @@ void dppc_interpreter::ppc_fsub() {
|
|||||||
|
|
||||||
double ppc_dblresult64_d = val_reg_a - val_reg_b;
|
double ppc_dblresult64_d = val_reg_a - val_reg_b;
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
ppc_update_fex();
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
@ -199,6 +222,12 @@ void dppc_interpreter::ppc_fdiv() {
|
|||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if (isinf(val_reg_a) && isinf(val_reg_b))
|
||||||
|
ppc_state.fpscr |= VXIDI;
|
||||||
|
|
||||||
|
if ((val_reg_a == 0.0) && (val_reg_b == 0.0))
|
||||||
|
ppc_state.fpscr |= VXZDZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -216,6 +245,9 @@ void dppc_interpreter::ppc_fmul() {
|
|||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -234,6 +266,13 @@ void dppc_interpreter::ppc_fmadd() {
|
|||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -252,6 +291,13 @@ void dppc_interpreter::ppc_fmsub() {
|
|||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -267,9 +313,19 @@ void dppc_interpreter::ppc_fnmadd() {
|
|||||||
snan_single_check(reg_b);
|
snan_single_check(reg_b);
|
||||||
|
|
||||||
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b);
|
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||||
|
if (isnan(ppc_dblresult64_d)) {
|
||||||
|
ppc_dblresult64_d = -ppc_dblresult64_d;
|
||||||
|
}
|
||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -288,6 +344,13 @@ void dppc_interpreter::ppc_fnmsub() {
|
|||||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -304,6 +367,10 @@ void dppc_interpreter::ppc_fadds() {
|
|||||||
double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b);
|
double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b);
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
@ -321,6 +388,10 @@ void dppc_interpreter::ppc_fsubs() {
|
|||||||
|
|
||||||
double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
|
double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
@ -338,6 +409,13 @@ void dppc_interpreter::ppc_fdivs() {
|
|||||||
snan_double_check(reg_a, reg_b);
|
snan_double_check(reg_a, reg_b);
|
||||||
|
|
||||||
double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
|
double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
|
||||||
|
|
||||||
|
if (isinf(val_reg_a) && isinf(val_reg_b))
|
||||||
|
ppc_state.fpscr |= VXIDI;
|
||||||
|
|
||||||
|
if ((val_reg_a == 0.0) && (val_reg_b == 0.0))
|
||||||
|
ppc_state.fpscr |= VXZDZ;
|
||||||
|
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
@ -355,9 +433,14 @@ void dppc_interpreter::ppc_fmuls() {
|
|||||||
snan_double_check(reg_a, reg_c);
|
snan_double_check(reg_a, reg_c);
|
||||||
|
|
||||||
double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
|
double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -376,6 +459,13 @@ void dppc_interpreter::ppc_fmadds() {
|
|||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -390,10 +480,21 @@ void dppc_interpreter::ppc_fmsubs() {
|
|||||||
snan_double_check(reg_a, reg_c);
|
snan_double_check(reg_a, reg_c);
|
||||||
snan_single_check(reg_b);
|
snan_single_check(reg_b);
|
||||||
|
|
||||||
|
|
||||||
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
|
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
|
||||||
|
if (isnan(ppc_dblresult64_d)) {
|
||||||
|
ppc_dblresult64_d = -ppc_dblresult64_d;
|
||||||
|
}
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -409,9 +510,19 @@ void dppc_interpreter::ppc_fnmadds() {
|
|||||||
snan_single_check(reg_b);
|
snan_single_check(reg_b);
|
||||||
|
|
||||||
double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b);
|
double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||||
|
if (isnan(ppc_dblresult64_d)) {
|
||||||
|
ppc_dblresult64_d = -ppc_dblresult64_d;
|
||||||
|
}
|
||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
@ -430,6 +541,13 @@ void dppc_interpreter::ppc_fnmsubs() {
|
|||||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||||
fpresult_update(ppc_dblresult64_d);
|
fpresult_update(ppc_dblresult64_d);
|
||||||
|
|
||||||
|
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
|
||||||
|
ppc_state.fpscr |= VXIMZ;
|
||||||
|
|
||||||
|
double inf = std::numeric_limits<double>::infinity();
|
||||||
|
if ((val_reg_a == inf) && (val_reg_b == inf))
|
||||||
|
ppc_state.fpscr |= VXISI;
|
||||||
|
|
||||||
if (rec)
|
if (rec)
|
||||||
ppc_update_cr1();
|
ppc_update_cr1();
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ void do_ctx_sync() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_ctx_sync_action(const CtxSyncCallback& cb) {
|
static void add_ctx_sync_action(const CtxSyncCallback& cb) {
|
||||||
gCtxSyncCallbacks.push_back(cb);
|
gCtxSyncCallbacks.push_back(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
main.cpp
4
main.cpp
@ -53,9 +53,9 @@ static void sigabrt_handler(int signum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static string appDescription = string(
|
static string appDescription = string(
|
||||||
"\nDingusPPC - Alpha 1 (5/10/2024) "
|
"\nDingusPPC - Alpha 1.01 (10/31/2024) "
|
||||||
"\nWritten by divingkatae, maximumspatium, "
|
"\nWritten by divingkatae, maximumspatium, "
|
||||||
"\njoevt, mihaip, et. al. "
|
"\njoevt, mihaip, kkaisershot, et. al. "
|
||||||
"\n(c) 2018-2024 The DingusPPC Dev Team. "
|
"\n(c) 2018-2024 The DingusPPC Dev Team. "
|
||||||
"\nThis is a build intended for testing. "
|
"\nThis is a build intended for testing. "
|
||||||
"\nUse at your own discretion. "
|
"\nUse at your own discretion. "
|
||||||
|
Loading…
Reference in New Issue
Block a user