mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-30 04:50:08 +00:00
Eliminate branches from SBCD.
This commit is contained in:
parent
c6d84e7e60
commit
79c5af755f
@ -37,10 +37,11 @@ template <
|
||||
// Pull out the two halves, for simplicity.
|
||||
const uint8_t source = src.b;
|
||||
const uint8_t destination = dest.b;
|
||||
const int extend = (status.extend_flag ? 1 : 0);
|
||||
|
||||
// Perform the BCD add by evaluating the two nibbles separately.
|
||||
const int unadjusted_result = destination + source + (status.extend_flag ? 1 : 0);
|
||||
int result = (destination & 0xf) + (source & 0xf) + (status.extend_flag ? 1 : 0);
|
||||
const int unadjusted_result = destination + source + extend;
|
||||
int result = (destination & 0xf) + (source & 0xf) + extend;
|
||||
if(result > 0x09) result += 0x06;
|
||||
result += (destination & 0xf0) + (source & 0xf0);
|
||||
if(result > 0x9f) result += 0x60;
|
||||
@ -788,29 +789,25 @@ template <
|
||||
break;
|
||||
|
||||
#define sbcd(d) \
|
||||
/* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \
|
||||
const int unadjusted_result = destination - source - (status.extend_flag ? 1 : 0); \
|
||||
const int extend = (status.extend_flag ? 1 : 0); \
|
||||
const int unadjusted_result = destination - source - extend; \
|
||||
\
|
||||
int top = (destination & 0xf0) - (source & 0xf0); \
|
||||
if(unadjusted_result & 0x100) top -= 0x60; \
|
||||
const int top = (destination & 0xf0) - (source & 0xf0) - (0x60 & (unadjusted_result >> 4)); \
|
||||
\
|
||||
int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0); \
|
||||
if(result & 0xf0) { \
|
||||
result -= 0x06; \
|
||||
status.extend_flag = status.carry_flag = Status::FlagT((unadjusted_result - 0x6) & 0x300); \
|
||||
} else { \
|
||||
status.extend_flag = status.carry_flag = Status::FlagT(unadjusted_result & 0x300); \
|
||||
} \
|
||||
\
|
||||
result += top; \
|
||||
\
|
||||
/* Set all remaining flags essentially as if this were normal subtraction. */ \
|
||||
status.zero_result |= result & 0xff; \
|
||||
status.negative_flag = result & 0x80; \
|
||||
status.overflow_flag = unadjusted_result & ~result & 0x80; \
|
||||
int result = (destination & 0xf) - (source & 0xf) - extend; \
|
||||
const int low_adjustment = 0x06 & (result >> 4); \
|
||||
status.extend_flag = status.carry_flag = Status::FlagT( \
|
||||
(unadjusted_result - low_adjustment) & 0x300 \
|
||||
); \
|
||||
result = result + top - low_adjustment; \
|
||||
\
|
||||
/* Store the result. */ \
|
||||
d = uint8_t(result);
|
||||
d = uint8_t(result); \
|
||||
\
|
||||
/* Set all remaining flags essentially as if this were normal subtraction. */ \
|
||||
status.zero_result |= d; \
|
||||
status.negative_flag = result & 0x80; \
|
||||
status.overflow_flag = unadjusted_result & ~result & 0x80; \
|
||||
|
||||
/*
|
||||
SBCD subtracts the lowest byte of the source from that of the destination using
|
||||
|
Loading…
Reference in New Issue
Block a user