#define BIT(x, bit) ((x) & (1 << (bit))) #define BIT_SHIFT(x, bit) (((x) >> (bit)) & 1) #define BITS(x, high, low) ((x) & (((1<<((high)+1))-1) & ~((1<<(low))-1))) #define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((1<<((high)-(low)+1))-1)) #define BIT_SET(x, bit) (((x) & (1 << (bit))) ? 1 : 0) #define ISNEG(x) BIT((x), 31) #define ISPOS(x) (!(BIT(x, 31))) word do_add(word a, word b, int carry_in, int *carry, int *ovl) { word val; val = a + b + carry_in; *carry = (ISNEG(a & b) || // both operands are negative, or (ISNEG(a ^ b) && ISPOS(val))); // exactly one of the operands is negative, and result is positive *ovl = (!(ISNEG(a ^ b))) && (ISNEG(a ^ val)); return val; } add: result = do_add(a, b, 0, &carry, &ovl); sub: result = do_add(a, ~b, 1, &carry, &ovl); rsb: result = do_add(b, ~a, 1, &carry, &ovl); adc: result = do_add(a, b, get_condition(PSR_CC_CARRY) ? 1 : 0, &carry, &ovl); sbc: result = do_add(a, ~b, get_condition(PSR_CC_CARRY) ? 1 : 0, &carry, &ovl); rsc: result = do_add(b, ~a, get_condition(PSR_CC_CARRY) ? 1 : 0, &carry, &ovl);