safe_ops: Avoid signed overflow in Negate()

Negation of values such as -9223372036854775808 can't be represented in
signed equivalents (such as long long), leading to signed overflow.
Therefore, we can just invert bits and add 1 to perform this behavior
with unsigned arithmetic.
This commit is contained in:
Lioncash 2018-07-17 14:39:07 -04:00 committed by MerryMage
parent af3e23b224
commit d0274f412a

View file

@ -103,7 +103,7 @@ T ArithmeticShiftRightDouble(T top, T bottom, int shift_amount) {
template<typename T> template<typename T>
T Negate(T value) { T Negate(T value) {
return static_cast<T>(-static_cast<std::make_signed_t<T>>(value)); return static_cast<T>(~static_cast<std::uintmax_t>(value) + 1);
} }
} // namespace Dynarmic::Safe } // namespace Dynarmic::Safe