1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-21 02:17:08 +00:00

Start factoring out useful ALU stuff.

This commit is contained in:
Thomas Harte
2023-10-11 11:06:20 -04:00
parent 4a803e2d43
commit fbd647080d
3 changed files with 107 additions and 102 deletions
+49
View File
@@ -16,9 +16,17 @@ namespace Numeric {
/// • borrow after calculating @c lhs - @c rhs if @c is_add is false;
/// producing @c result.
template <bool is_add, int bit, typename IntT> bool carried_out(IntT lhs, IntT rhs, IntT result) {
// Additive:
//
// 0 and 0 => didn't.
// 0 and 1 or 1 and 0 => did if 0.
// 1 and 1 => did.
//
// Subtractive:
//
// 1 and 0 => didn't
// 1 and 1 or 0 and 0 => did if 1.
// 0 and 1 => did.
if constexpr (!is_add) {
rhs = ~rhs;
}
@@ -40,6 +48,47 @@ template <int bit, typename IntT> bool carried_in(IntT lhs, IntT rhs, IntT resul
return IntT(1 << bit) & (lhs ^ rhs ^ result);
}
//
// BEGIN TEMPORARY COPY AND PASTE SECTION.
//
// The following are largely excised from the M68k PerformImplementation.hpp; if there proves to be no
// reason further to specialise them, there'll be a factoring out. In some cases I've tightened the documentation.
//
/// @returns An int of type @c IntT with only the most-significant bit set.
template <typename IntT> constexpr IntT top_bit() {
static_assert(!std::numeric_limits<IntT>::is_signed);
constexpr IntT max = std::numeric_limits<IntT>::max();
return max - (max >> 1);
}
/// @returns The number of bits in @c IntT.
template <typename IntT> constexpr int bit_size() {
return sizeof(IntT) * 8;
}
/// @returns An int with the top bit indicating whether overflow occurred during the calculation of
/// • @c lhs + @c rhs (if @c is_add is true); or
/// • @c lhs - @c rhs (if @c is_add is false)
/// and the result was @c result. All other bits will be clear.
template <bool is_add, typename IntT>
IntT overflow(IntT lhs, IntT rhs, IntT result) {
const IntT output_changed = result ^ lhs;
const IntT input_differed = lhs ^ rhs;
if constexpr (is_add) {
return top_bit<IntT>() & output_changed & ~input_differed;
} else {
return top_bit<IntT>() & output_changed & input_differed;
}
}
// NOTE TO FUTURE SELF: the original 68k `overflow` treats lhs and rhs the other way
// around, affecting subtractive overflow. Be careful.
//
// END COPY AND PASTE SECTION.
//
}
#endif /* Carry_hpp */