1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//! Utility for checking binary arithmetic flags for ALU operations.

/// Returns if the sum of an addition operation between two integers generated
/// an arithmetic carry.
///
/// Since operation is carried out between two u32 integers, if the results
/// is greater than 0xFFFF_FFFF, then bit 31 was carried into bit 32, indicating
/// a carry.
pub fn did_add_generate_carry(sum: u64) -> bool {
    sum > 0xFFFF_FFFF
}

/// Returns if the difference of an subtraction operation between two
/// integers generated an arithmetic borrow.
///
/// Since the operation is carried out between two u32 integers, if the
/// difference is less than 0x1_0000_0000, then bit 32 wasn't borrowed.
pub fn did_sub_generate_borrow(difference: u64) -> bool {
    difference < 0x1_0000_0000
}

/// Returns if two addends and their sum generated an arithmetic overflow.
///
/// An addition overflow is identified if the sign of both addends are the same
/// and the sign of the sum is different from both addends.
pub fn did_add_generate_overflow(addend_a: u32, addend_b: u32, sum: u32) -> bool {
    !(addend_a ^ addend_b) & (addend_a ^ sum) & 0x8000_0000 != 0
}

/// Returns if the subtraction operation between the minuend and subtrahend
/// integers and their difference generated an arithmetic overflow.
///
/// An subtraction overflow is identified if the sign of the minuend and
/// subtrahend are different and the difference has the same sign as the
/// subtrahend.
pub fn did_sub_generate_overflow(minuend: u32, subtrahend: u32, difference: u32) -> bool {
    (minuend ^ subtrahend) & (minuend ^ difference) & 0x8000_0000 > 0
}