mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-12 16:30:44 +00:00
Fix fmadd et al. to set FPSCR[VXISI] only if any of the multiply operands
is an inifinity (2.1.5 -- don't set based on the intermediate result)
This commit is contained in:
parent
e020d63591
commit
98dea63921
@ -346,7 +346,7 @@ template<> struct fp_exception_condition<op_fdiv> : fp_divide_exception_conditio
|
|||||||
template< class FP, bool negate >
|
template< class FP, bool negate >
|
||||||
struct fp_fma_exception_condition {
|
struct fp_fma_exception_condition {
|
||||||
static inline uint32 apply(FP a, FP b, FP c) {
|
static inline uint32 apply(FP a, FP b, FP c) {
|
||||||
return
|
int exceptions =
|
||||||
fp_invalid_operation_condition<FP>::
|
fp_invalid_operation_condition<FP>::
|
||||||
apply(FPSCR_VXSNAN_field::mask(), a) |
|
apply(FPSCR_VXSNAN_field::mask(), a) |
|
||||||
fp_invalid_operation_condition<FP>::
|
fp_invalid_operation_condition<FP>::
|
||||||
@ -354,10 +354,21 @@ struct fp_fma_exception_condition {
|
|||||||
fp_invalid_operation_condition<FP>::
|
fp_invalid_operation_condition<FP>::
|
||||||
apply(FPSCR_VXSNAN_field::mask(), c) |
|
apply(FPSCR_VXSNAN_field::mask(), c) |
|
||||||
fp_invalid_operation_condition<FP>::
|
fp_invalid_operation_condition<FP>::
|
||||||
apply(FPSCR_VXIMZ_field::mask(), a, b) |
|
apply(FPSCR_VXIMZ_field::mask(), a, b);
|
||||||
fp_invalid_operation_condition<FP>::
|
// 2.1.5 -- The XER bit definitions are based on the
|
||||||
apply(FPSCR_VXISI_field::mask(), a * b, c, negate)
|
// operation of an instruction considered as a whole,
|
||||||
;
|
// not on intermediate results
|
||||||
|
if ((isinf(a) || isinf(b)) && isinf(c)) {
|
||||||
|
FP m = a * b;
|
||||||
|
if (isinf(m)) {
|
||||||
|
// make sure the intermediate result is an infinity and not a NaN
|
||||||
|
// FIXME: it could be faster to use (exceptions & IMZ) == 0 instead of isinf()
|
||||||
|
if (( negate && (signbit(m) == signbit(c))) ||
|
||||||
|
(!negate && (signbit(m) != signbit(c))))
|
||||||
|
exceptions |= FPSCR_VXISI_field::mask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exceptions;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user