1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Eliminate bitwise macros.

This commit is contained in:
Thomas Harte 2022-10-17 15:21:54 -04:00
parent ee3a3df0b5
commit f095bba1ca

View File

@ -93,9 +93,34 @@ inline void sbcd(uint8_t rhs, uint8_t lhs, uint8_t &destination, Status &status)
status.overflow_flag = unadjusted_result & ~result & 0x80; status.overflow_flag = unadjusted_result & ~result & 0x80;
} }
template <Operation operation, typename IntT>
void bitwise(IntT source, IntT &destination, Status &status) {
static_assert(
operation == Operation::ANDb || operation == Operation::ANDw || operation == Operation::ANDl ||
operation == Operation::ORb || operation == Operation::ORw || operation == Operation::ORl ||
operation == Operation::EORb || operation == Operation::EORw || operation == Operation::EORl
);
switch(operation) {
case Operation::ANDb: case Operation::ANDw: case Operation::ANDl:
destination &= source;
break;
case Operation::ORb: case Operation::ORw: case Operation::ORl:
destination |= source;
break;
case Operation::EORb: case Operation::EORw: case Operation::EORl:
destination ^= source;
break;
}
status.overflow_flag = status.carry_flag = 0;
status.zero_result = destination;
status.negative_flag = destination & top_bit<IntT>();
}
/// Performs a compare of @c source to @c destination, setting zero, carry, negative and overflow flags. /// Performs a compare of @c source to @c destination, setting zero, carry, negative and overflow flags.
template <typename IntT> template <typename IntT>
static void compare(IntT source, IntT destination, Status &status) { void compare(IntT source, IntT destination, Status &status) {
const IntT result = destination - source; const IntT result = destination - source;
status.zero_result = result; status.zero_result = result;
status.carry_flag = result > destination; status.carry_flag = result > destination;
@ -733,37 +758,17 @@ template <
Bitwise operators: AND, OR and EOR. All three clear the overflow and carry flags, Bitwise operators: AND, OR and EOR. All three clear the overflow and carry flags,
and set zero and negative appropriately. and set zero and negative appropriately.
*/ */
#define op_and(x, y) x &= y case Operation::ANDb: Primitive::bitwise<Operation::ANDb>(src.b, dest.b, status); break;
#define op_or(x, y) x |= y case Operation::ANDw: Primitive::bitwise<Operation::ANDw>(src.w, dest.w, status); break;
#define op_eor(x, y) x ^= y case Operation::ANDl: Primitive::bitwise<Operation::ANDl>(src.l, dest.l, status); break;
#define bitwise(source, dest, sign_mask, operator) \ case Operation::ORb: Primitive::bitwise<Operation::ORb>(src.b, dest.b, status); break;
operator(dest, source); \ case Operation::ORw: Primitive::bitwise<Operation::ORw>(src.w, dest.w, status); break;
status.overflow_flag = status.carry_flag = 0; \ case Operation::ORl: Primitive::bitwise<Operation::ORl>(src.l, dest.l, status); break;
status.zero_result = dest; \
status.negative_flag = dest & sign_mask;
#define andx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_and) case Operation::EORb: Primitive::bitwise<Operation::EORb>(src.b, dest.b, status); break;
#define eorx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_eor) case Operation::EORw: Primitive::bitwise<Operation::EORw>(src.w, dest.w, status); break;
#define orx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_or) case Operation::EORl: Primitive::bitwise<Operation::EORl>(src.l, dest.l, status); break;
#define op_bwl(name, op) \
case Operation::name##b: op(src.b, dest.b, 0x80); break; \
case Operation::name##w: op(src.w, dest.w, 0x8000); break; \
case Operation::name##l: op(src.l, dest.l, 0x80000000); break;
op_bwl(AND, andx);
op_bwl(EOR, eorx);
op_bwl(OR, orx);
#undef op_bwl
#undef orx
#undef eorx
#undef andx
#undef bitwise
#undef op_eor
#undef op_or
#undef op_and
// NOTs: take the logical inverse, affecting the negative and zero flags. // NOTs: take the logical inverse, affecting the negative and zero flags.
case Operation::NOTb: case Operation::NOTb: