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,16 +2,16 @@
namespace nall {
template<int Requested> struct Integer {
enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested };
template<int Precision> struct Integer {
static_assert(Precision >= 1 && Precision <= 64);
static inline constexpr auto bits() -> uint { return Precision; }
using type =
using stype =
typename conditional<bits() <= 8, int8_t,
typename conditional<bits() <= 16, int16_t,
typename conditional<bits() <= 32, int32_t,
typename conditional<bits() <= 64, int64_t,
void>::type>::type>::type>::type;
using utype = typename Natural<Requested>::type;
using utype = typename Natural<Precision>::utype;
static inline constexpr auto mask() -> utype { return ~0ull >> 64 - bits(); }
static inline constexpr auto sign() -> utype { return 1ull << Precision - 1; }
@@ -20,7 +20,7 @@ template<int Requested> struct Integer {
template<typename T> inline Integer(const T& value) { data = mask(value); }
explicit inline operator bool() const { return data; }
inline operator type() const { return data; }
inline operator int64_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; }
@@ -49,59 +49,54 @@ template<int Requested> struct Integer {
#undef lhs
#undef rhs
inline auto bits(int lo, int hi) -> BitRange<Requested> { return {(utype&)data, lo, hi}; }
inline auto bit(int index) -> BitRange<Requested> { return {(utype&)data, index, index}; }
inline auto byte(int index) -> BitRange<Requested> { return {(utype&)data, index * 8 + 0, index * 8 + 7}; }
#define lhs (int64_t)data
#define rhs value
#undef lhs
#undef rhs
inline auto bits(int lo, int hi) const -> const BitRange<Requested> { return {(utype&)*this, lo, lo}; }
inline auto bit(int index) const -> const BitRange<Requested> { return {(utype&)*this, index, index}; }
inline auto byte(int index) const -> const BitRange<Requested> { return {(utype&)*this, index * 8 + 0, index * 8 + 7}; }
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 clamp(uint bits) -> type {
inline auto bits(int lo, int hi) const -> const BitRange<Precision> { return {(utype&)*this, lo, lo}; }
inline auto bit(int index) const -> const BitRange<Precision> { return {(utype&)*this, index, index}; }
inline auto byte(int index) const -> const BitRange<Precision> { return {(utype&)*this, index * 8 + 0, index * 8 + 7}; }
inline auto clamp(uint bits) {
const intmax b = 1ull << (bits - 1);
const intmax m = b - 1;
return data > m ? m : data < -b ? -b : data;
return Integer<64>{data > m ? m : data < -b ? -b : data};
}
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) ^ b) - b;
return Integer<64>{(data & m ^ b) - b};
}
inline auto serialize(serializer& s) { s(data); }
inline auto natural() const -> Natural<Requested>;
inline auto natural() const -> Natural<Precision>;
private:
inline auto mask(type value) const -> type {
inline auto mask(stype value) const -> stype {
return (value & mask() ^ sign()) - sign();
}
type data;
stype 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 (int64_t)(typename Integer<LHS>::type)l
#define rhs (typename Integer<RHS>::type)r
template<int LHS, int RHS> inline auto operator *(Integer<LHS> l, Integer<RHS> r) { return Integer<ADD>{lhs * rhs}; }
template<int LHS, int RHS> inline auto operator /(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs / rhs}; }
template<int LHS, int RHS> inline auto operator %(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs % rhs}; }
template<int LHS, int RHS> inline auto operator +(Integer<LHS> l, Integer<RHS> r) { return Integer<INC>{lhs + rhs}; }
template<int LHS, int RHS> inline auto operator -(Integer<LHS> l, Integer<RHS> r) { return Integer<INC>{lhs - rhs}; }
template<int LHS, int RHS> inline auto operator<<(Integer<LHS> l, Integer<RHS> r) { return Integer<ALL>{lhs << rhs}; }
template<int LHS, int RHS> inline auto operator>>(Integer<LHS> l, Integer<RHS> r) { return Integer<LHS>{lhs >> rhs}; }
template<int LHS, int RHS> inline auto operator &(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs & rhs}; }
template<int LHS, int RHS> inline auto operator ^(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs ^ rhs}; }
template<int LHS, int RHS> inline auto operator |(Integer<LHS> l, Integer<RHS> r) { return Integer<MAX>{lhs | rhs}; }
#undef ALL
#undef ADD
#undef INC
#undef MAX
#undef MIN
#define lhs (int64_t)l
#define rhs r
template<int LHS, int RHS> inline auto operator *(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs * rhs}; }
template<int LHS, int RHS> inline auto operator /(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs / rhs}; }
template<int LHS, int RHS> inline auto operator %(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs % rhs}; }
template<int LHS, int RHS> inline auto operator +(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs + rhs}; }
template<int LHS, int RHS> inline auto operator -(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs - rhs}; }
template<int LHS, int RHS> inline auto operator<<(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs << rhs}; }
template<int LHS, int RHS> inline auto operator>>(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs >> rhs}; }
template<int LHS, int RHS> inline auto operator &(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs & rhs}; }
template<int LHS, int RHS> inline auto operator ^(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs ^ rhs}; }
template<int LHS, int RHS> inline auto operator |(Integer<LHS> l, Integer<RHS> r) { return Integer<64>{lhs | rhs}; }
#undef lhs
#undef rhs

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

View File

@@ -2,18 +2,20 @@
namespace nall {
template<int Requested> struct Real {
enum : uint { Precision = Requested <= 32 ? 32 : 64 };
template<int Precision> struct Real {
static_assert(Precision == 32 || Precision == 64);
static inline constexpr auto bits() -> uint { return Precision; }
using type =
using ftype =
typename conditional<bits() == 32, float32_t,
typename conditional<bits() == 64, float64_t,
void>::type>::type;
inline Real() : data(0.0) {}
template<typename T> inline Real(const T& value) : data((type)value) {}
template<int Bits> inline Real(Real<Bits> value) : data((ftype)value) {}
template<typename T> inline Real(const T& value) : data((ftype)value) {}
inline operator type() const { return data; }
explicit inline operator bool() const { return data; }
inline operator float64_t() const { return data; }
inline auto operator++(int) { auto value = *this; ++data; return value; }
inline auto operator--(int) { auto value = *this; --data; return value; }
@@ -31,10 +33,10 @@ template<int Requested> struct Real {
inline auto serialize(serializer& s) { s(data); }
private:
type data;
ftype data;
};
#define lhs (long double)(typename Real<LHS>::type)l
#define lhs (float64_t)(typename Real<LHS>::type)l
#define rhs (typename Real<RHS>::type)r
template<int LHS, int RHS> inline auto operator*(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs * rhs}; }
template<int LHS, int RHS> inline auto operator/(Real<LHS> l, Real<RHS> r) { return Real<64>{lhs / rhs}; }