mirror of
https://github.com/TomHarte/CLK.git
synced 2025-05-08 22:43:14 +00:00
Use contractions.
This commit is contained in:
parent
01ddc24c02
commit
da1d52033b
@ -152,8 +152,9 @@ struct Executor {
|
|||||||
if constexpr (flags.set_condition_codes()) {
|
if constexpr (flags.set_condition_codes()) {
|
||||||
// "For a subtraction, including the comparison instruction CMP, C is set to 0 if
|
// "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."
|
// 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));
|
using NumOp = Numeric::Operation;
|
||||||
registers_.set_v(Numeric::overflow<Numeric::Operation::Subtract>(lhs, rhs, conditions));
|
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())) {
|
if constexpr (!is_comparison(flags.operation())) {
|
||||||
@ -185,8 +186,9 @@ struct Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (flags.set_condition_codes()) {
|
if constexpr (flags.set_condition_codes()) {
|
||||||
registers_.set_c(Numeric::carried_out<Numeric::Operation::Add, 31>(operand1, operand2, conditions));
|
using NumOp = Numeric::Operation;
|
||||||
registers_.set_v(Numeric::overflow<Numeric::Operation::Add>(operand1, operand2, conditions));
|
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())) {
|
if constexpr (!is_comparison(flags.operation())) {
|
||||||
|
@ -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 void add_sub(const IntT source, IntT &destination, Status &status) {
|
||||||
static_assert(!std::numeric_limits<IntT>::is_signed);
|
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;
|
constexpr bool is_add = operation == Numeric::Operation::Add;
|
||||||
IntT result = is_add ?
|
IntT result = is_add ?
|
||||||
destination + source :
|
destination + source :
|
||||||
destination - source;
|
destination - source;
|
||||||
status.carry_flag = is_add ? result < destination : result > destination;
|
status.carry_flag = is_add ? result < destination : result > destination;
|
||||||
@ -520,6 +521,7 @@ template <
|
|||||||
Status &status,
|
Status &status,
|
||||||
FlowController &flow_controller
|
FlowController &flow_controller
|
||||||
) {
|
) {
|
||||||
|
using NumOp = Numeric::Operation;
|
||||||
switch((operation != Operation::Undefined) ? operation : instruction.operation) {
|
switch((operation != Operation::Undefined) ? operation : instruction.operation) {
|
||||||
/*
|
/*
|
||||||
ABCD adds the lowest bytes from the source and destination using BCD arithmetic,
|
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;
|
// 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.
|
// 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::ADDb: Primitive::add_sub<NumOp::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::SUBb: Primitive::add_sub<NumOp::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::ADDXb: Primitive::add_sub<NumOp::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::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::ADDw: Primitive::add_sub<NumOp::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::SUBw: Primitive::add_sub<NumOp::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::ADDXw: Primitive::add_sub<NumOp::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::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::ADDl: Primitive::add_sub<NumOp::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::SUBl: Primitive::add_sub<NumOp::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::ADDXl: Primitive::add_sub<NumOp::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::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::ADDAw: dest.l += u_extend16(src.w); break;
|
||||||
case Operation::ADDAl: dest.l += src.l; break;
|
case Operation::ADDAl: dest.l += src.l; break;
|
||||||
|
@ -30,12 +30,13 @@ void add(
|
|||||||
*/
|
*/
|
||||||
const IntT result = destination + source + (with_carry ? context.flags.template carry_bit<IntT>() : 0);
|
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>(
|
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>(
|
context.flags.template set_from<Flag::AuxiliaryCarry>(
|
||||||
Numeric::carried_in<4>(destination, source, result));
|
Numeric::carried_in<4>(destination, source, result));
|
||||||
context.flags.template set_from<Flag::Overflow>(
|
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);
|
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);
|
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>(
|
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>(
|
context.flags.template set_from<Flag::AuxiliaryCarry>(
|
||||||
Numeric::carried_in<4>(destination, source, result));
|
Numeric::carried_in<4>(destination, source, result));
|
||||||
context.flags.template set_from<Flag::Overflow>(
|
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);
|
context.flags.template set_from<IntT, Flag::Zero, Flag::Sign, Flag::ParityOdd>(result);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user