Skip to content

Commit 329bcc6

Browse files
committed
Floating-point fix-ups
Largely to fix setting flags, but partially to fix the incorrect nan emulation
1 parent b3eb1f6 commit 329bcc6

File tree

4 files changed

+122
-3
lines changed

4 files changed

+122
-3
lines changed

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- maximumspatium
88
- joevt
99
- mihaip
10+
- kkaisershot
1011

1112
## NT4/PPC fork
1213

cpu/ppc/ppcfpopcodes.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,18 @@ static void fpresult_update(double set_result) {
127127
} else {
128128
ppc_state.fpscr |= FPCC_ZERO;
129129
}
130+
131+
if (std::fetestexcept(FE_OVERFLOW)) {
132+
ppc_state.fpscr |= (OX + FX);
133+
}
134+
if (std::fetestexcept(FE_UNDERFLOW)) {
135+
ppc_state.fpscr |= (UX + FX);
136+
}
137+
if (std::fetestexcept(FE_DIVBYZERO)) {
138+
ppc_state.fpscr |= (ZX + FX);
139+
}
140+
141+
std::feclearexcept(FE_ALL_EXCEPT);
130142

131143
if (std::isinf(set_result))
132144
ppc_state.fpscr |= FPCC_FUNAN;
@@ -160,6 +172,12 @@ void dppc_interpreter::ppc_fadd() {
160172
max_double_check(val_reg_a, val_reg_b);
161173

162174
double ppc_dblresult64_d = val_reg_a + val_reg_b;
175+
176+
double inf = std::numeric_limits<double>::infinity();
177+
if (((val_reg_a == inf) && (val_reg_b == -inf)) ||
178+
((val_reg_a == -inf) && (val_reg_b == inf)))
179+
ppc_state.fpscr |= VXISI;
180+
163181
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
164182
fpresult_update(ppc_dblresult64_d);
165183
ppc_update_fex();
@@ -179,8 +197,13 @@ void dppc_interpreter::ppc_fsub() {
179197

180198
double ppc_dblresult64_d = val_reg_a - val_reg_b;
181199

200+
double inf = std::numeric_limits<double>::infinity();
201+
if ((val_reg_a == inf) && (val_reg_b == inf))
202+
ppc_state.fpscr |= VXISI;
203+
182204
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
183205
fpresult_update(ppc_dblresult64_d);
206+
ppc_update_fex();
184207

185208
if (rec)
186209
ppc_update_cr1();
@@ -199,6 +222,12 @@ void dppc_interpreter::ppc_fdiv() {
199222
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
200223
fpresult_update(ppc_dblresult64_d);
201224

225+
if (isinf(val_reg_a) && isinf(val_reg_b))
226+
ppc_state.fpscr |= VXIDI;
227+
228+
if ((val_reg_a == 0.0) && (val_reg_b == 0.0))
229+
ppc_state.fpscr |= VXZDZ;
230+
202231
if (rec)
203232
ppc_update_cr1();
204233
}
@@ -216,6 +245,9 @@ void dppc_interpreter::ppc_fmul() {
216245
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
217246
fpresult_update(ppc_dblresult64_d);
218247

248+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
249+
ppc_state.fpscr |= VXIMZ;
250+
219251
if (rec)
220252
ppc_update_cr1();
221253
}
@@ -234,6 +266,13 @@ void dppc_interpreter::ppc_fmadd() {
234266
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
235267
fpresult_update(ppc_dblresult64_d);
236268

269+
double inf = std::numeric_limits<double>::infinity();
270+
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
271+
ppc_state.fpscr |= VXISI;
272+
273+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
274+
ppc_state.fpscr |= VXIMZ;
275+
237276
if (rec)
238277
ppc_update_cr1();
239278
}
@@ -252,6 +291,13 @@ void dppc_interpreter::ppc_fmsub() {
252291
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
253292
fpresult_update(ppc_dblresult64_d);
254293

294+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
295+
ppc_state.fpscr |= VXIMZ;
296+
297+
double inf = std::numeric_limits<double>::infinity();
298+
if ((val_reg_a == inf) && (val_reg_b == inf))
299+
ppc_state.fpscr |= VXISI;
300+
255301
if (rec)
256302
ppc_update_cr1();
257303
}
@@ -267,9 +313,19 @@ void dppc_interpreter::ppc_fnmadd() {
267313
snan_single_check(reg_b);
268314

269315
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b);
316+
if (isnan(ppc_dblresult64_d)) {
317+
ppc_dblresult64_d = -ppc_dblresult64_d;
318+
}
270319
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
271320
fpresult_update(ppc_dblresult64_d);
272321

322+
double inf = std::numeric_limits<double>::infinity();
323+
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
324+
ppc_state.fpscr |= VXISI;
325+
326+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
327+
ppc_state.fpscr |= VXIMZ;
328+
273329
if (rec)
274330
ppc_update_cr1();
275331
}
@@ -288,6 +344,13 @@ void dppc_interpreter::ppc_fnmsub() {
288344
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
289345
fpresult_update(ppc_dblresult64_d);
290346

347+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
348+
ppc_state.fpscr |= VXIMZ;
349+
350+
double inf = std::numeric_limits<double>::infinity();
351+
if ((val_reg_a == inf) && (val_reg_b == inf))
352+
ppc_state.fpscr |= VXISI;
353+
291354
if (rec)
292355
ppc_update_cr1();
293356
}
@@ -304,6 +367,10 @@ void dppc_interpreter::ppc_fadds() {
304367
double ppc_dblresult64_d = (float)(val_reg_a + val_reg_b);
305368
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
306369

370+
double inf = std::numeric_limits<double>::infinity();
371+
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
372+
ppc_state.fpscr |= VXISI;
373+
307374
fpresult_update(ppc_dblresult64_d);
308375

309376
if (rec)
@@ -321,6 +388,10 @@ void dppc_interpreter::ppc_fsubs() {
321388

322389
double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
323390

391+
double inf = std::numeric_limits<double>::infinity();
392+
if ((val_reg_a == inf) && (val_reg_b == inf))
393+
ppc_state.fpscr |= VXISI;
394+
324395
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
325396
fpresult_update(ppc_dblresult64_d);
326397

@@ -338,6 +409,13 @@ void dppc_interpreter::ppc_fdivs() {
338409
snan_double_check(reg_a, reg_b);
339410

340411
double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
412+
413+
if (isinf(val_reg_a) && isinf(val_reg_b))
414+
ppc_state.fpscr |= VXIDI;
415+
416+
if ((val_reg_a == 0.0) && (val_reg_b == 0.0))
417+
ppc_state.fpscr |= VXZDZ;
418+
341419
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
342420
fpresult_update(ppc_dblresult64_d);
343421

@@ -355,9 +433,14 @@ void dppc_interpreter::ppc_fmuls() {
355433
snan_double_check(reg_a, reg_c);
356434

357435
double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
436+
437+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
438+
ppc_state.fpscr |= VXIMZ;
439+
358440
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
359441
fpresult_update(ppc_dblresult64_d);
360442

443+
361444
if (rec)
362445
ppc_update_cr1();
363446
}
@@ -376,6 +459,13 @@ void dppc_interpreter::ppc_fmadds() {
376459
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
377460
fpresult_update(ppc_dblresult64_d);
378461

462+
double inf = std::numeric_limits<double>::infinity();
463+
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
464+
ppc_state.fpscr |= VXISI;
465+
466+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
467+
ppc_state.fpscr |= VXIMZ;
468+
379469
if (rec)
380470
ppc_update_cr1();
381471
}
@@ -390,9 +480,20 @@ void dppc_interpreter::ppc_fmsubs() {
390480
snan_double_check(reg_a, reg_c);
391481
snan_single_check(reg_b);
392482

483+
393484
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
485+
if (isnan(ppc_dblresult64_d)) {
486+
ppc_dblresult64_d = -ppc_dblresult64_d;
487+
}
394488
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
395489
fpresult_update(ppc_dblresult64_d);
490+
491+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
492+
ppc_state.fpscr |= VXIMZ;
493+
494+
double inf = std::numeric_limits<double>::infinity();
495+
if ((val_reg_a == inf) && (val_reg_b == inf))
496+
ppc_state.fpscr |= VXISI;
396497

397498
if (rec)
398499
ppc_update_cr1();
@@ -409,9 +510,19 @@ void dppc_interpreter::ppc_fnmadds() {
409510
snan_single_check(reg_b);
410511

411512
double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b);
513+
if (isnan(ppc_dblresult64_d)) {
514+
ppc_dblresult64_d = -ppc_dblresult64_d;
515+
}
412516
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
413517
fpresult_update(ppc_dblresult64_d);
414518

519+
double inf = std::numeric_limits<double>::infinity();
520+
if (((val_reg_a == inf) && (val_reg_b == -inf)) || ((val_reg_a == -inf) && (val_reg_b == inf)))
521+
ppc_state.fpscr |= VXISI;
522+
523+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
524+
ppc_state.fpscr |= VXIMZ;
525+
415526
if (rec)
416527
ppc_update_cr1();
417528
}
@@ -430,6 +541,13 @@ void dppc_interpreter::ppc_fnmsubs() {
430541
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
431542
fpresult_update(ppc_dblresult64_d);
432543

544+
if ((isinf(val_reg_a) && (val_reg_c == 0.0)) || (isinf(val_reg_c) && (val_reg_a == 0.0)))
545+
ppc_state.fpscr |= VXIMZ;
546+
547+
double inf = std::numeric_limits<double>::infinity();
548+
if ((val_reg_a == inf) && (val_reg_b == inf))
549+
ppc_state.fpscr |= VXISI;
550+
433551
if (rec)
434552
ppc_update_cr1();
435553
}

cpu/ppc/ppcopcodes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void do_ctx_sync() {
8484
}
8585
}
8686

87-
void add_ctx_sync_action(const CtxSyncCallback& cb) {
87+
static void add_ctx_sync_action(const CtxSyncCallback& cb) {
8888
gCtxSyncCallbacks.push_back(cb);
8989
}
9090

main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ static void sigabrt_handler(int signum) {
5353
}
5454

5555
static string appDescription = string(
56-
"\nDingusPPC - Alpha 1 (5/10/2024) "
56+
"\nDingusPPC - Alpha 1.01 (10/31/2024) "
5757
"\nWritten by divingkatae, maximumspatium, "
58-
"\njoevt, mihaip, et. al. "
58+
"\njoevt, mihaip, kkaisershot, et. al. "
5959
"\n(c) 2018-2024 The DingusPPC Dev Team. "
6060
"\nThis is a build intended for testing. "
6161
"\nUse at your own discretion. "

0 commit comments

Comments
 (0)