1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-03-27 19:33:26 +00:00

Use contractions.

This commit is contained in:
Thomas Harte 2025-01-28 18:19:31 -05:00
parent 01ddc24c02
commit da1d52033b
3 changed files with 27 additions and 21 deletions

View File

@ -152,8 +152,9 @@ struct Executor {
if constexpr (flags.set_condition_codes()) {
// "For a subtraction, including the comparison instruction CMP, C is set to 0 if
// the subtraction produced a borrow (that is, an unsigned underflow), and to 1 otherwise."
registers_.set_c(!Numeric::carried_out<Numeric::Operation::Subtract, 31>(lhs, rhs, conditions));
registers_.set_v(Numeric::overflow<Numeric::Operation::Subtract>(lhs, rhs, conditions));
using NumOp = Numeric::Operation;
registers_.set_c(!Numeric::carried_out<NumOp::Subtract, 31>(lhs, rhs, conditions));
registers_.set_v(Numeric::overflow<NumOp::Subtract>(lhs, rhs, conditions));
}
if constexpr (!is_comparison(flags.operation())) {
@ -185,8 +186,9 @@ struct Executor {
}
if constexpr (flags.set_condition_codes()) {
registers_.set_c(Numeric::carried_out<Numeric::Operation::Add, 31>(operand1, operand2, conditions));
registers_.set_v(Numeric::overflow<Numeric::Operation::Add>(operand1, operand2, conditions));
using NumOp = Numeric::Operation;
registers_.set_c(Numeric::carried_out<NumOp::Add, 31>(operand1, operand2, conditions));
registers_.set_v(Numeric::overflow<NumOp::Add>(operand1, operand2, conditions));
}
if constexpr (!is_comparison(flags.operation())) {

View File

@ -32,8 +32,9 @@ template <Numeric::Operation operation, bool is_extend, typename IntT>
static void add_sub(const IntT source, IntT &destination, Status &status) {
static_assert(!std::numeric_limits<IntT>::is_signed);
static_assert(operation == Numeric::Operation::Add || operation == Numeric::Operation::Subtract);
constexpr bool is_add = operation == Numeric::Operation::Add;
IntT result = is_add ?
IntT result = is_add ?
destination + source :
destination - source;
status.carry_flag = is_add ? result < destination : result > destination;
@ -520,6 +521,7 @@ template <
Status &status,
FlowController &flow_controller
) {
using NumOp = Numeric::Operation;
switch((operation != Operation::Undefined) ? operation : instruction.operation) {
/*
ABCD adds the lowest bytes from the source and destination using BCD arithmetic,
@ -552,20 +554,20 @@ template <
// ADD and ADDA add two quantities, the latter sign extending and without setting any flags;
// ADDQ and SUBQ act as ADD and SUB, but taking the second argument from the instruction code.
case Operation::ADDb: Primitive::add_sub<Numeric::Operation::Add, false>(src.b, dest.b, status); break;
case Operation::SUBb: Primitive::add_sub<Numeric::Operation::Subtract, false>(src.b, dest.b, status); break;
case Operation::ADDXb: Primitive::add_sub<Numeric::Operation::Add, true>(src.b, dest.b, status); break;
case Operation::SUBXb: Primitive::add_sub<Numeric::Operation::Subtract, true>(src.b, dest.b, status); break;
case Operation::ADDb: Primitive::add_sub<NumOp::Add, false>(src.b, dest.b, status); break;
case Operation::SUBb: Primitive::add_sub<NumOp::Subtract, false>(src.b, dest.b, status); break;
case Operation::ADDXb: Primitive::add_sub<NumOp::Add, true>(src.b, dest.b, status); break;
case Operation::SUBXb: Primitive::add_sub<NumOp::Subtract, true>(src.b, dest.b, status); break;
case Operation::ADDw: Primitive::add_sub<Numeric::Operation::Add, false>(src.w, dest.w, status); break;
case Operation::SUBw: Primitive::add_sub<Numeric::Operation::Subtract, false>(src.w, dest.w, status); break;
case Operation::ADDXw: Primitive::add_sub<Numeric::Operation::Add, true>(src.w, dest.w, status); break;
case Operation::SUBXw: Primitive::add_sub<Numeric::Operation::Subtract, true>(src.w, dest.w, status); break;
case Operation::ADDw: Primitive::add_sub<NumOp::Add, false>(src.w, dest.w, status); break;
case Operation::SUBw: Primitive::add_sub<NumOp::Subtract, false>(src.w, dest.w, status); break;
case Operation::ADDXw: Primitive::add_sub<NumOp::Add, true>(src.w, dest.w, status); break;
case Operation::SUBXw: Primitive::add_sub<NumOp::Subtract, true>(src.w, dest.w, status); break;
case Operation::ADDl: Primitive::add_sub<Numeric::Operation::Add, false>(src.l, dest.l, status); break;
case Operation::SUBl: Primitive::add_sub<Numeric::Operation::Subtract, false>(src.l, dest.l, status); break;
case Operation::ADDXl: Primitive::add_sub<Numeric::Operation::Add, true>(src.l, dest.l, status); break;
case Operation::SUBXl: Primitive::add_sub<Numeric::Operation::Subtract, true>(src.l, dest.l, status); break;
case Operation::ADDl: Primitive::add_sub<NumOp::Add, false>(src.l, dest.l, status); break;
case Operation::SUBl: Primitive::add_sub<NumOp::Subtract, false>(src.l, dest.l, status); break;
case Operation::ADDXl: Primitive::add_sub<NumOp::Add, true>(src.l, dest.l, status); break;
case Operation::SUBXl: Primitive::add_sub<NumOp::Subtract, true>(src.l, dest.l, status); break;
case Operation::ADDAw: dest.l += u_extend16(src.w); break;
case Operation::ADDAl: dest.l += src.l; break;

View File

@ -30,12 +30,13 @@ void add(
*/
const IntT result = destination + source + (with_carry ? context.flags.template carry_bit<IntT>() : 0);
using NumOp = Numeric::Operation;
context.flags.template set_from<Flag::Carry>(
Numeric::carried_out<Numeric::Operation::Add, Numeric::bit_size<IntT>() - 1>(destination, source, result));
Numeric::carried_out<NumOp::Add, Numeric::bit_size<IntT>() - 1>(destination, source, result));
context.flags.template set_from<Flag::AuxiliaryCarry>(
Numeric::carried_in<4>(destination, source, result));
context.flags.template set_from<Flag::Overflow>(
Numeric::overflow<Numeric::Operation::Add, IntT>(destination, source, result));
Numeric::overflow<NumOp::Add, IntT>(destination, source, result));
context.flags.template set_from<IntT, Flag::Zero, Flag::Sign, Flag::ParityOdd>(result);
@ -56,12 +57,13 @@ void sub(
*/
const IntT result = destination - source - (with_borrow ? context.flags.template carry_bit<IntT>() : 0);
using NumOp = Numeric::Operation;
context.flags.template set_from<Flag::Carry>(
Numeric::carried_out<Numeric::Operation::Subtract, Numeric::bit_size<IntT>() - 1>(destination, source, result));
Numeric::carried_out<NumOp::Subtract, Numeric::bit_size<IntT>() - 1>(destination, source, result));
context.flags.template set_from<Flag::AuxiliaryCarry>(
Numeric::carried_in<4>(destination, source, result));
context.flags.template set_from<Flag::Overflow>(
Numeric::overflow<Numeric::Operation::Subtract, IntT>(destination, source, result));
Numeric::overflow<NumOp::Subtract, IntT>(destination, source, result));
context.flags.template set_from<IntT, Flag::Zero, Flag::Sign, Flag::ParityOdd>(result);