@@ -127,6 +127,18 @@ static void fpresult_update(double set_result) {
127
127
} else {
128
128
ppc_state.fpscr |= FPCC_ZERO;
129
129
}
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);
130
142
131
143
if (std::isinf (set_result))
132
144
ppc_state.fpscr |= FPCC_FUNAN;
@@ -160,6 +172,12 @@ void dppc_interpreter::ppc_fadd() {
160
172
max_double_check (val_reg_a, val_reg_b);
161
173
162
174
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
+
163
181
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
164
182
fpresult_update (ppc_dblresult64_d);
165
183
ppc_update_fex ();
@@ -179,8 +197,13 @@ void dppc_interpreter::ppc_fsub() {
179
197
180
198
double ppc_dblresult64_d = val_reg_a - val_reg_b;
181
199
200
+ double inf = std::numeric_limits<double >::infinity ();
201
+ if ((val_reg_a == inf) && (val_reg_b == inf))
202
+ ppc_state.fpscr |= VXISI;
203
+
182
204
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
183
205
fpresult_update (ppc_dblresult64_d);
206
+ ppc_update_fex ();
184
207
185
208
if (rec)
186
209
ppc_update_cr1 ();
@@ -199,6 +222,12 @@ void dppc_interpreter::ppc_fdiv() {
199
222
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
200
223
fpresult_update (ppc_dblresult64_d);
201
224
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
+
202
231
if (rec)
203
232
ppc_update_cr1 ();
204
233
}
@@ -216,6 +245,9 @@ void dppc_interpreter::ppc_fmul() {
216
245
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
217
246
fpresult_update (ppc_dblresult64_d);
218
247
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
+
219
251
if (rec)
220
252
ppc_update_cr1 ();
221
253
}
@@ -234,6 +266,13 @@ void dppc_interpreter::ppc_fmadd() {
234
266
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
235
267
fpresult_update (ppc_dblresult64_d);
236
268
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
+
237
276
if (rec)
238
277
ppc_update_cr1 ();
239
278
}
@@ -252,6 +291,13 @@ void dppc_interpreter::ppc_fmsub() {
252
291
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
253
292
fpresult_update (ppc_dblresult64_d);
254
293
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
+
255
301
if (rec)
256
302
ppc_update_cr1 ();
257
303
}
@@ -267,9 +313,19 @@ void dppc_interpreter::ppc_fnmadd() {
267
313
snan_single_check (reg_b);
268
314
269
315
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
+ }
270
319
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
271
320
fpresult_update (ppc_dblresult64_d);
272
321
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
+
273
329
if (rec)
274
330
ppc_update_cr1 ();
275
331
}
@@ -288,6 +344,13 @@ void dppc_interpreter::ppc_fnmsub() {
288
344
ppc_store_dfpresult_flt (reg_d, ppc_dblresult64_d);
289
345
fpresult_update (ppc_dblresult64_d);
290
346
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
+
291
354
if (rec)
292
355
ppc_update_cr1 ();
293
356
}
@@ -304,6 +367,10 @@ void dppc_interpreter::ppc_fadds() {
304
367
double ppc_dblresult64_d = (float )(val_reg_a + val_reg_b);
305
368
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
306
369
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
+
307
374
fpresult_update (ppc_dblresult64_d);
308
375
309
376
if (rec)
@@ -321,6 +388,10 @@ void dppc_interpreter::ppc_fsubs() {
321
388
322
389
double ppc_dblresult64_d = (float )(val_reg_a - val_reg_b);
323
390
391
+ double inf = std::numeric_limits<double >::infinity ();
392
+ if ((val_reg_a == inf) && (val_reg_b == inf))
393
+ ppc_state.fpscr |= VXISI;
394
+
324
395
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
325
396
fpresult_update (ppc_dblresult64_d);
326
397
@@ -338,6 +409,13 @@ void dppc_interpreter::ppc_fdivs() {
338
409
snan_double_check (reg_a, reg_b);
339
410
340
411
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
+
341
419
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
342
420
fpresult_update (ppc_dblresult64_d);
343
421
@@ -355,9 +433,14 @@ void dppc_interpreter::ppc_fmuls() {
355
433
snan_double_check (reg_a, reg_c);
356
434
357
435
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
+
358
440
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
359
441
fpresult_update (ppc_dblresult64_d);
360
442
443
+
361
444
if (rec)
362
445
ppc_update_cr1 ();
363
446
}
@@ -376,6 +459,13 @@ void dppc_interpreter::ppc_fmadds() {
376
459
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
377
460
fpresult_update (ppc_dblresult64_d);
378
461
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
+
379
469
if (rec)
380
470
ppc_update_cr1 ();
381
471
}
@@ -390,9 +480,20 @@ void dppc_interpreter::ppc_fmsubs() {
390
480
snan_double_check (reg_a, reg_c);
391
481
snan_single_check (reg_b);
392
482
483
+
393
484
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
+ }
394
488
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
395
489
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;
396
497
397
498
if (rec)
398
499
ppc_update_cr1 ();
@@ -409,9 +510,19 @@ void dppc_interpreter::ppc_fnmadds() {
409
510
snan_single_check (reg_b);
410
511
411
512
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
+ }
412
516
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
413
517
fpresult_update (ppc_dblresult64_d);
414
518
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
+
415
526
if (rec)
416
527
ppc_update_cr1 ();
417
528
}
@@ -430,6 +541,13 @@ void dppc_interpreter::ppc_fnmsubs() {
430
541
ppc_store_sfpresult_flt (reg_d, ppc_dblresult64_d);
431
542
fpresult_update (ppc_dblresult64_d);
432
543
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
+
433
551
if (rec)
434
552
ppc_update_cr1 ();
435
553
}
0 commit comments