Update to v106r80 release.

byuu says:

Any usage of natural and integer cast to 64-bit math operations now.
Hopefully this will be the last of the major changes for a bit on
nall/primitives, at least until serious work begins on removing implicit
conversion to primitive types.

I also completed the initial TLCS900H core, sans SWI (kind of a ways off
from support interrupts.) I really shouldn't say completed, though. The
micro DMA unit is missing, interrupt priority handling is missing,
there's no debugger, and, of course, there's surely dozens of absolutely
critical CPU bugs that are going to be an absolute hellscape nightmare
to track down.

It was a damn shame, right up until the very last eight instructions,
[CP|LD][I|D](R), the instruction encoding was consistent. Of course,
there could be other inconsistencies that I missed. In fact, that's
somewhat likely ... sigh.
This commit is contained in:
Tim Allen
2019-01-16 00:09:50 +11:00
parent 17fc6d8d51
commit 25145f59cc
11 changed files with 314 additions and 116 deletions

View File

@@ -2,23 +2,23 @@
namespace nall {
template<int Requested> struct Natural {
enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested };
template<int Precision> struct Natural {
static_assert(Precision >= 1 && Precision <= 64);
static inline constexpr auto bits() -> uint { return Precision; }
using type =
using utype =
typename conditional<bits() <= 8, uint8_t,
typename conditional<bits() <= 16, uint16_t,
typename conditional<bits() <= 32, uint32_t,
typename conditional<bits() <= 64, uint64_t,
void>::type>::type>::type>::type;
static inline constexpr auto mask() -> type { return ~0ull >> 64 - bits(); }
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
inline Natural() : data(0) {}
template<int Bits> inline Natural(Natural<Bits> value) { data = mask(value); }
template<typename T> inline Natural(const T& value) { data = mask(value); }
explicit inline operator bool() const { return data; }
inline operator type() const { return data; }
inline operator uint64_t() const { return data; }
inline auto operator++(int) { auto value = *this; data = mask(data + 1); return value; }
inline auto operator--(int) { auto value = *this; data = mask(data - 1); return value; }
@@ -47,59 +47,84 @@ template<int Requested> struct Natural {
#undef lhs
#undef rhs
inline auto bits(int lo, int hi) -> BitRange<Requested> { return {(type&)data, lo, hi}; }
inline auto bit(int index) -> BitRange<Requested> { return {(type&)data, index, index}; }
inline auto byte(int index) -> BitRange<Requested> { return {(type&)data, index * 8 + 0, index * 8 + 7}; }
//work in progress: we want natural<op>primitive and primitive<op>natural to result in natural<64> ...
//however, these operators will create ambiguous overloads unless operator uint64_t() is explicit.
//a large volume of existing code will need to be updated before this will be possible.
#if 0
#define lhs (uint64_t)data
#define rhs value
template<typename T> inline auto operator *(const T& value) { return Natural<64>{lhs * rhs}; }
template<typename T> inline auto operator /(const T& value) { return Natural<64>{lhs / rhs}; }
template<typename T> inline auto operator %(const T& value) { return Natural<64>{lhs % rhs}; }
template<typename T> inline auto operator +(const T& value) { return Natural<64>{lhs + rhs}; }
template<typename T> inline auto operator -(const T& value) { return Natural<64>{lhs - rhs}; }
template<typename T> inline auto operator<<(const T& value) { return Natural<64>{lhs << rhs}; }
template<typename T> inline auto operator>>(const T& value) { return Natural<64>{lhs >> rhs}; }
template<typename T> inline auto operator &(const T& value) { return Natural<64>{lhs & rhs}; }
template<typename T> inline auto operator ^(const T& value) { return Natural<64>{lhs ^ rhs}; }
template<typename T> inline auto operator |(const T& value) { return Natural<64>{lhs | rhs}; }
#undef lhs
#undef rhs
inline auto bits(int lo, int hi) const -> const BitRange<Requested> { return {(type&)data, lo, hi}; }
inline auto bit(int index) const -> const BitRange<Requested> { return {(type&)data, index, index}; }
inline auto byte(int index) const -> const BitRange<Requested> { return {(type&)data, index * 8 + 0, index * 8 + 7}; }
#define lhs l
#define rhs (uint64_t)r
template<typename T> friend inline auto operator *(const T& l, Natural r) { return Natural<64>{lhs * rhs}; }
template<typename T> friend inline auto operator %(const T& l, Natural r) { return Natural<64>{lhs / rhs}; }
template<typename T> friend inline auto operator /(const T& l, Natural r) { return Natural<64>{lhs % rhs}; }
template<typename T> friend inline auto operator +(const T& l, Natural r) { return Natural<64>{lhs + rhs}; }
template<typename T> friend inline auto operator -(const T& l, Natural r) { return Natural<64>{lhs - rhs}; }
template<typename T> friend inline auto operator<<(const T& l, Natural r) { return Natural<64>{lhs << rhs}; }
template<typename T> friend inline auto operator>>(const T& l, Natural r) { return Natural<64>{lhs >> rhs}; }
template<typename T> friend inline auto operator &(const T& l, Natural r) { return Natural<64>{lhs & rhs}; }
template<typename T> friend inline auto operator ^(const T& l, Natural r) { return Natural<64>{lhs ^ rhs}; }
template<typename T> friend inline auto operator |(const T& l, Natural r) { return Natural<64>{lhs | rhs}; }
#undef lhs
#undef rhs
#endif
inline auto clamp(uint bits) -> type {
inline auto bits(int lo, int hi) -> BitRange<Precision> { return {(utype&)data, lo, hi}; }
inline auto bit(int index) -> BitRange<Precision> { return {(utype&)data, index, index}; }
inline auto byte(int index) -> BitRange<Precision> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
inline auto bits(int lo, int hi) const -> const BitRange<Precision> { return {(utype&)data, lo, hi}; }
inline auto bit(int index) const -> const BitRange<Precision> { return {(utype&)data, index, index}; }
inline auto byte(int index) const -> const BitRange<Precision> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
inline auto clamp(uint bits) {
const uintmax b = 1ull << (bits - 1);
const uintmax m = b * 2 - 1;
return data < m ? data : m;
return Natural<64>{data < m ? data : m};
}
inline auto clip(uint bits) -> type {
inline auto clip(uint bits) {
const uintmax b = 1ull << (bits - 1);
const uintmax m = b * 2 - 1;
return data & m;
return Natural<64>{data & m};
}
inline auto serialize(serializer& s) { s(data); }
inline auto integer() const -> Integer<Requested>;
inline auto integer() const -> Integer<Precision>;
private:
inline auto mask(type value) const -> type {
inline auto mask(utype value) const -> utype {
return value & mask();
}
type data;
utype data;
};
#define ALL 64
#define ADD 64 //LHS + RHS
#define INC 64 //1 + (LHS >= RHS ? LHS : RHS)
#define MAX 64 //LHS >= RHS ? LHS : RHS
#define MIN 64 //LHS <= RHS ? LHS : RHS
#define lhs (uint64_t)(typename Natural<LHS>::type)l
#define rhs (typename Natural<RHS>::type)r
template<int LHS, int RHS> inline auto operator *(Natural<LHS> l, Natural<RHS> r) { return Natural<ADD>{lhs * rhs}; }
template<int LHS, int RHS> inline auto operator /(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs / rhs}; }
template<int LHS, int RHS> inline auto operator %(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs % rhs}; }
template<int LHS, int RHS> inline auto operator +(Natural<LHS> l, Natural<RHS> r) { return Natural<INC>{lhs + rhs}; }
template<int LHS, int RHS> inline auto operator -(Natural<LHS> l, Natural<RHS> r) { return Natural<INC>{lhs - rhs}; }
template<int LHS, int RHS> inline auto operator<<(Natural<LHS> l, Natural<RHS> r) { return Natural<ALL>{lhs << rhs}; }
template<int LHS, int RHS> inline auto operator>>(Natural<LHS> l, Natural<RHS> r) { return Natural<LHS>{lhs >> rhs}; }
template<int LHS, int RHS> inline auto operator &(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs & rhs}; }
template<int LHS, int RHS> inline auto operator ^(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs ^ rhs}; }
template<int LHS, int RHS> inline auto operator |(Natural<LHS> l, Natural<RHS> r) { return Natural<MAX>{lhs | rhs}; }
#undef ALL
#undef ADD
#undef INC
#undef MAX
#undef MIN
#define lhs (uint64_t)l
#define rhs (uint64_t)r
template<int LHS, int RHS> inline auto operator *(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs * rhs}; }
template<int LHS, int RHS> inline auto operator /(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs / rhs}; }
template<int LHS, int RHS> inline auto operator %(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs % rhs}; }
template<int LHS, int RHS> inline auto operator +(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs + rhs}; }
template<int LHS, int RHS> inline auto operator -(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs - rhs}; }
template<int LHS, int RHS> inline auto operator<<(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs << rhs}; }
template<int LHS, int RHS> inline auto operator>>(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs >> rhs}; }
template<int LHS, int RHS> inline auto operator &(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs & rhs}; }
template<int LHS, int RHS> inline auto operator ^(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs ^ rhs}; }
template<int LHS, int RHS> inline auto operator |(Natural<LHS> l, Natural<RHS> r) { return Natural<64>{lhs | rhs}; }
#undef lhs
#undef rhs