diff options
author | 2015-01-12 10:35:19 -0500 | |
---|---|---|
committer | 2015-01-12 10:35:19 -0500 | |
commit | f3a7b66267a243c9e1a8bcd37f39389e41703fef (patch) | |
tree | 01635c0131e1e5dfa94bfa67747f14e29ee4e203 /src/core/arm/interpreter/armsupp.cpp | |
parent | 2f7069f9bda8ce466e99b1202eaa1cc06125fd6f (diff) | |
parent | 2843d1b98b74b7642f086833da09fd0b50f8ad57 (diff) |
Merge pull request #472 from lioncash/overflow
dyncom: Fix some more V-flag setting ops. Plus some cleanup.
Diffstat (limited to 'src/core/arm/interpreter/armsupp.cpp')
-rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 68ac2a0c..e2626eef 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp @@ -418,6 +418,22 @@ ARMul_NegZero (ARMul_State * state, ARMword result) } } +// Add with carry, indicates if a carry-out or signed overflow occurred. +u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) +{ + u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; + s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; + u64 result = (unsigned_sum & 0xFFFFFFFF); + + if (carry_out_occurred) + *carry_out_occurred = (result != unsigned_sum); + + if (overflow_occurred) + *overflow_occurred = ((s64)(s32)result != signed_sum); + + return (u32)result; +} + // Compute whether an addition of A and B, giving RESULT, overflowed. bool AddOverflow(ARMword a, ARMword b, ARMword result) { |