diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 234ab16f..15340dca 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -30,7 +30,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "106.79"; + static const string Version = "106.80"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "https://byuu.org/"; diff --git a/higan/processor/m68k/m68k.hpp b/higan/processor/m68k/m68k.hpp index 32593654..5fc075a6 100644 --- a/higan/processor/m68k/m68k.hpp +++ b/higan/processor/m68k/m68k.hpp @@ -90,7 +90,7 @@ struct M68K { //effective-address.cpp struct EffectiveAddress { - explicit EffectiveAddress(uint mode_, uint reg_) : mode(mode_), reg(reg_) { + explicit EffectiveAddress(uint4 mode_, uint3 reg_) : mode(mode_), reg(reg_) { if(mode == 7) mode += reg; //optimization: convert modes {7; 0-4} to {8-11} } diff --git a/higan/processor/tlcs900h/instruction.cpp b/higan/processor/tlcs900h/instruction.cpp index d461481a..9845b1f4 100644 --- a/higan/processor/tlcs900h/instruction.cpp +++ b/higan/processor/tlcs900h/instruction.cpp @@ -25,7 +25,7 @@ template auto TLCS900H::toImmediate3(uint3 constant) const -> Immedi auto TLCS900H::instruction() -> void { auto data = fetch(); - switch(data) { + switch(r.prefix = data) { case 0x00: return instructionNoOperation(); case 0x01: return (void)Undefined; case 0x02: return instructionPush(SR); @@ -293,8 +293,12 @@ auto TLCS900H::instructionRegister(R register) -> void { case 0x0b: if constexpr(bits != 32) return instructionDivideSigned(register, fetchImmediate()); return (void)Undefined; -//case 0x0c: LINK r,dd -//case 0x0d: UNLK r + case 0x0c: + if constexpr(bits == 32) return instructionLink(register, fetchImmediate()); + return (void)Undefined; + case 0x0d: + if constexpr(bits == 32) return instructionUnlink(register); + return (void)Undefined; case 0x0e: if constexpr(bits == 16) return instructionBitSearch1Forward(register); return (void)Undefined; @@ -311,7 +315,9 @@ auto TLCS900H::instructionRegister(R register) -> void { case 0x13: if constexpr(bits != 8) return instructionExtendSign(register); return (void)Undefined; -//case 0x14: PAA r + case 0x14: + if constexpr(bits != 8) return instructionPointerAdjustAccumulator(register); + return (void)Undefined; case 0x15: return (void)Undefined; case 0x16: if constexpr(bits == 16) return instructionMirror(register); @@ -321,7 +327,9 @@ auto TLCS900H::instructionRegister(R register) -> void { if constexpr(bits == 16) return instructionMultiplyAdd(register); return (void)Undefined; case 0x1a: case 0x1b: return (void)Undefined; -//case 0x1c: DJNZ r,d + case 0x1c: + if constexpr(bits != 32) return instructionDecrementJumpNotZero(register, fetchImmediate()); + return (void)Undefined; case 0x1d: case 0x1e: case 0x1f: return (void)Undefined; case 0x20: if constexpr(bits != 32) return instructionAndCarry(register, fetchImmediate()); @@ -373,13 +381,25 @@ auto TLCS900H::instructionRegister(R register) -> void { if constexpr(bits != 32) return instructionTestSet(register, fetchImmediate()); return (void)Undefined; case 0x35: case 0x36: case 0x37: return (void)Undefined; -//case 0x38: MINC1 #,r -//case 0x39: MINC2 #,r -//case 0x3a: MINC4 #,r + case 0x38: + if constexpr(bits == 16) return instructionModuloIncrement<1>(register, fetchImmediate()); + return (void)Undefined; + case 0x39: + if constexpr(bits == 16) return instructionModuloIncrement<2>(register, fetchImmediate()); + return (void)Undefined; + case 0x3a: + if constexpr(bits == 16) return instructionModuloIncrement<4>(register, fetchImmediate()); + return (void)Undefined; case 0x3b: return (void)Undefined; -//case 0x3c: MDEC1 #,r -//case 0x3d: MDEC2 #,r -//case 0x3e: MDEC4 #,r + case 0x3c: + if constexpr(bits == 16) return instructionModuloDecrement<1>(register, fetchImmediate()); + return (void)Undefined; + case 0x3d: + if constexpr(bits == 16) return instructionModuloDecrement<2>(register, fetchImmediate()); + return (void)Undefined; + case 0x3e: + if constexpr(bits == 16) return instructionModuloDecrement<4>(register, fetchImmediate()); + return (void)Undefined; case 0x3f: return (void)Undefined; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: if constexpr(bits != 32) return instructionMultiply(toRegister3(data), register); @@ -467,17 +487,45 @@ auto TLCS900H::instructionSourceMemory(M memory) -> void { if constexpr(bits == 32) return (void)Undefined; return instructionPush(memory); case 0x05: return (void)Undefined; -//case 0x06: RLD A,(mem) -//case 0x07: RRD A,(mem) + case 0x06: + if constexpr(bits == 8) return instructionRotateLeftDigit(A, memory); + return (void)Undefined; + case 0x07: + if constexpr(bits == 8) return instructionRotateRightDigit(A, memory); + return (void)Undefined; case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: return (void)Undefined; -//case 0x10: LDI -//case 0x11: LDIR -//case 0x12: LDIR -//case 0x13: LDDR -//case 0x14: CPI -//case 0x15: CPIR -//case 0x16: CPD -//case 0x17: CPDR + case 0x10: + if constexpr(bits == 8) return instructionLoad(); + if constexpr(bits == 16) return instructionLoad(); + return (void)Undefined; + case 0x11: + if constexpr(bits == 8) return instructionLoadRepeat(); + if constexpr(bits == 16) return instructionLoadRepeat(); + return (void)Undefined; + case 0x12: + if constexpr(bits == 8) return instructionLoad(); + if constexpr(bits == 16) return instructionLoad(); + return (void)Undefined; + case 0x13: + if constexpr(bits == 8) return instructionLoadRepeat(); + if constexpr(bits == 16) return instructionLoadRepeat(); + return (void)Undefined; + case 0x14: + if constexpr(bits == 8) return instructionCompare(A); + if constexpr(bits == 16) return instructionCompare(WA); + return (void)Undefined; + case 0x15: + if constexpr(bits == 8) return instructionCompareRepeat(A); + if constexpr(bits == 16) return instructionCompareRepeat(WA); + return (void)Undefined; + case 0x16: + if constexpr(bits == 8) return instructionCompare(A); + if constexpr(bits == 16) return instructionCompare(WA); + return (void)Undefined; + case 0x17: + if constexpr(bits == 8) return instructionCompareRepeat(A); + if constexpr(bits == 16) return instructionCompareRepeat(WA); + return (void)Undefined; case 0x18: return (void)Undefined; case 0x19: if constexpr(bits == 32) return (void)Undefined; diff --git a/higan/processor/tlcs900h/instructions.cpp b/higan/processor/tlcs900h/instructions.cpp index f1c03eee..b69b975d 100644 --- a/higan/processor/tlcs900h/instructions.cpp +++ b/higan/processor/tlcs900h/instructions.cpp @@ -63,6 +63,22 @@ auto TLCS900H::instructionChange(Target target, Offset offset) -> void { store(target, result); } +template +auto TLCS900H::instructionCompare(Target target) -> void { + auto source = toRegister3(r.prefix); + auto cf = CF; //CF is not modified; but algorithmSubtract will modify it + algorithmSubtract(load(target), load(toMemory(load(source)))); + store(source, load(source) + Adjust); + store(BC, load(BC) - 1); + CF = cf; + VF = load(BC) == 0; +} + +template +auto TLCS900H::instructionCompareRepeat(Target target) -> void { + do { instructionCompare(target); } while(VF && !ZF); +} + template auto TLCS900H::instructionCompare(Target target, Source source) -> void { algorithmSubtract(load(target), load(source)); @@ -93,6 +109,13 @@ auto TLCS900H::instructionDecrement(Target target, Source source) -> void { store(target, algorithmDecrement(load(target), immediate)); } +template +auto TLCS900H::instructionDecrementJumpNotZero(Target target, Offset offset) -> void { + auto result = load(target); + store(target, --result); + if(result) store(PC, load(PC) + load(offset)); +} + template auto TLCS900H::instructionDivide(Target target, Source source) -> void { using T = typename Target::type; @@ -156,6 +179,13 @@ auto TLCS900H::instructionJumpRelative(uint4 code, Source displacement) -> void if(condition(code)) store(PC, load(PC) + load(displacement)); } +template +auto TLCS900H::instructionLink(Target target, Offset offset) -> void { + push(target); + store(target, load(XSP)); + store(XSP, load(XSP) + load(offset)); +} + template auto TLCS900H::instructionLoad(Target target, Source source) -> void { store(target, load(source)); @@ -167,6 +197,22 @@ auto TLCS900H::instructionLoadCarry(Source source, Offset offset) -> void { CF = load(source).bit(load(offset) & Source::bits - 1); } +template auto TLCS900H::instructionLoad() -> void { + auto target = (uint3)r.prefix == 5 ? XIX : XDE; + auto source = (uint3)r.prefix == 5 ? XIY : XHL; + store(toMemory(load(target)), load(toMemory(load(source)))); + store(target, load(target) + Adjust); + store(source, load(source) + Adjust); + store(BC, load(BC) - 1); + NF = 0; + VF = load(BC) == 0; + HF = 0; +} + +template auto TLCS900H::instructionLoadRepeat() -> void { + do { instructionLoad(); } while(VF); +} + //reverse all bits in a 16-bit register //note: an 8-bit lookup table is faster (when in L1/L2 cache), but much more code auto TLCS900H::instructionMirror(Register register) -> void { @@ -177,6 +223,28 @@ auto TLCS900H::instructionMirror(Register register) -> void { store(register, data << 8 | data >> 8); } +template +auto TLCS900H::instructionModuloDecrement(Target target, Source source) -> void { + auto result = load(target); + auto number = load(source); + if(result % number == 0) { + store(target, result + (number - Modulo)); + } else { + store(target, result - Modulo); + } +} + +template +auto TLCS900H::instructionModuloIncrement(Target target, Source source) -> void { + auto result = load(target); + auto number = load(source); + if(result % number == number - Modulo) { + store(target, result - (number - Modulo)); + } else { + store(target, result + Modulo); + } +} + template auto TLCS900H::instructionMultiply(Target target, Source source) -> void { store(expand(target), load(target) * load(source)); @@ -221,6 +289,13 @@ auto TLCS900H::instructionOrCarry(Source source, Offset offset) -> void { CF |= load(source).bit(load(offset) & Source::bits - 1); } +//increments odd addresses only to ensure they are even (16-bit aligned) +template +auto TLCS900H::instructionPointerAdjustAccumulator(Target target) -> void { + auto result = load(target); + store(target, result + result.bit(0)); +} + template auto TLCS900H::instructionPop(Target target) -> void { pop(target); @@ -254,6 +329,23 @@ auto TLCS900H::instructionReturnInterrupt() -> void { store(INTNEST, load(INTNEST) - 1); } +template +auto TLCS900H::instructionRotateLeftDigit(LHS lhs, RHS rhs) -> void { + auto lvalue = load(lhs); + auto rvalue = load(rhs); + auto Lvalue = lvalue; + lvalue.bits(0,3) = rvalue.bits(4,7); + rvalue.bits(4,7) = rvalue.bits(0,3); + rvalue.bits(0,3) = Lvalue.bits(0,3); + store(lhs, lvalue); + store(rhs, rvalue); + NF = 0; + PF = parity(lvalue); + HF = 0; + ZF = lvalue == 0; + SF = lvalue.bit(-1); +} + template auto TLCS900H::instructionRotateLeft(Target target, Amount amount) -> void { auto result = load(target); @@ -277,6 +369,23 @@ auto TLCS900H::instructionRotateLeftWithoutCarry(Target target, Amount amount) - store(target, algorithmRotated(result)); } +template +auto TLCS900H::instructionRotateRightDigit(LHS lhs, RHS rhs) -> void { + auto lvalue = load(lhs); + auto rvalue = load(rhs); + auto Rvalue = rvalue; + rvalue.bits(0,3) = rvalue.bits(4,7); + rvalue.bits(4,7) = lvalue.bits(0,3); + lvalue.bits(0,3) = Rvalue.bits(0,3); + store(lhs, lvalue); + store(rhs, rvalue); + NF = 0; + PF = parity(lvalue); + HF = 0; + ZF = lvalue == 0; + SF = lvalue.bit(-1); +} + template auto TLCS900H::instructionRotateRight(Target target, Amount amount) -> void { auto result = load(target); @@ -404,6 +513,12 @@ auto TLCS900H::instructionTestSet(Target target, Offset offset) -> void { store(target, result); } +template +auto TLCS900H::instructionUnlink(Target target) -> void { + store(XSP, load(target)); + pop(target); +} + template auto TLCS900H::instructionXor(Target target, Source source) -> void { store(target, algorithmXor(load(target), load(source))); diff --git a/higan/processor/tlcs900h/tlcs900h.hpp b/higan/processor/tlcs900h/tlcs900h.hpp index 7860ffb8..59a83c80 100644 --- a/higan/processor/tlcs900h/tlcs900h.hpp +++ b/higan/processor/tlcs900h/tlcs900h.hpp @@ -102,10 +102,13 @@ struct TLCS900H { template auto instructionCall(uint4 code, Source) -> void; template auto instructionCallRelative(Source) -> void; template auto instructionChange(Target, Offset) -> void; + template auto instructionCompare(Target) -> void; + template auto instructionCompareRepeat(Target) -> void; template auto instructionCompare(Target, Source) -> void; template auto instructionComplement(Target) -> void; auto instructionDecimalAdjustAccumulator(Register) -> void; template auto instructionDecrement(Target, Source) -> void; + template auto instructionDecrementJumpNotZero(Target, Offset) -> void; template auto instructionDivide(Target, Source) -> void; template auto instructionDivideSigned(Target, Source) -> void; template auto instructionExchange(Target, Source) -> void; @@ -115,8 +118,13 @@ struct TLCS900H { template auto instructionIncrement(Target, Source) -> void; template auto instructionJump(uint4 code, Source) -> void; template auto instructionJumpRelative(uint4 code, Source) -> void; + template auto instructionLink(Target, Offset) -> void; template auto instructionLoad(Target, Source) -> void; template auto instructionLoadCarry(Source, Offset) -> void; + template auto instructionLoad() -> void; + template auto instructionLoadRepeat() -> void; + template auto instructionModuloDecrement(Target, Source) -> void; + template auto instructionModuloIncrement(Target, Source) -> void; auto instructionMirror(Register) -> void; template auto instructionMultiply(Target, Source) -> void; auto instructionMultiplyAdd(Register) -> void; @@ -125,14 +133,17 @@ struct TLCS900H { auto instructionNoOperation() -> void; template auto instructionOr(Target, Source) -> void; template auto instructionOrCarry(Source, Offset) -> void; + template auto instructionPointerAdjustAccumulator(Target) -> void; template auto instructionPop(Target) -> void; template auto instructionPush(Source) -> void; template auto instructionReset(Target, Offset) -> void; auto instructionReturn(uint4 code) -> void; template auto instructionReturnDeallocate(Source) -> void; auto instructionReturnInterrupt() -> void; + template auto instructionRotateLeftDigit(LHS, RHS) -> void; template auto instructionRotateLeft(Target, Amount) -> void; template auto instructionRotateLeftWithoutCarry(Target, Amount) -> void; + template auto instructionRotateRightDigit(LHS, RHS) -> void; template auto instructionRotateRight(Target, Amount) -> void; template auto instructionRotateRightWithoutCarry(Target, Amount) -> void; template auto instructionSet(Target, Offset) -> void; @@ -149,6 +160,7 @@ struct TLCS900H { template auto instructionSubtract(Target, Source) -> void; template auto instructionSubtractBorrow(Target, Source) -> void; template auto instructionTestSet(Target, Offset) -> void; + template auto instructionUnlink(Target) -> void; template auto instructionXor(Target, Source) -> void; template auto instructionXorCarry(Source, Offset) -> void; @@ -188,6 +200,7 @@ struct TLCS900H { uint3 iff = 7; //interrupt mask flip-flop uint1 halted; + uint8 prefix; //first opcode byte; needed for [CP|LD][ID](R) instructions } r; auto halted() const -> bool { return r.halted; } diff --git a/higan/sfc/ppu-fast/ppu.hpp b/higan/sfc/ppu-fast/ppu.hpp index c98009a7..24ac6eb0 100644 --- a/higan/sfc/ppu-fast/ppu.hpp +++ b/higan/sfc/ppu-fast/ppu.hpp @@ -223,9 +223,9 @@ public: }; struct Pixel { - uint source; - uint priority; - uint color; + uint source; + uint priority; + uint15 color; }; //io.cpp diff --git a/nall/primitives/integer.hpp b/nall/primitives/integer.hpp index f5c677f9..d6e5a77a 100644 --- a/nall/primitives/integer.hpp +++ b/nall/primitives/integer.hpp @@ -2,16 +2,16 @@ namespace nall { -template struct Integer { - enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested }; +template struct Integer { + static_assert(Precision >= 1 && Precision <= 64); static inline constexpr auto bits() -> uint { return Precision; } - using type = + using stype = typename conditional::type>::type>::type>::type; - using utype = typename Natural::type; + using utype = typename Natural::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 struct Integer { template 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 struct Integer { #undef lhs #undef rhs - inline auto bits(int lo, int hi) -> BitRange { return {(utype&)data, lo, hi}; } - inline auto bit(int index) -> BitRange { return {(utype&)data, index, index}; } - inline auto byte(int index) -> BitRange { 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 { return {(utype&)*this, lo, lo}; } - inline auto bit(int index) const -> const BitRange { return {(utype&)*this, index, index}; } - inline auto byte(int index) const -> const BitRange { return {(utype&)*this, index * 8 + 0, index * 8 + 7}; } + inline auto bits(int lo, int hi) -> BitRange { return {(utype&)data, lo, hi}; } + inline auto bit(int index) -> BitRange { return {(utype&)data, index, index}; } + inline auto byte(int index) -> BitRange { 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 { return {(utype&)*this, lo, lo}; } + inline auto bit(int index) const -> const BitRange { return {(utype&)*this, index, index}; } + inline auto byte(int index) const -> const BitRange { 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; + inline auto natural() const -> Natural; 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::type)l -#define rhs (typename Integer::type)r -template inline auto operator *(Integer l, Integer r) { return Integer{lhs * rhs}; } -template inline auto operator /(Integer l, Integer r) { return Integer{lhs / rhs}; } -template inline auto operator %(Integer l, Integer r) { return Integer{lhs % rhs}; } -template inline auto operator +(Integer l, Integer r) { return Integer{lhs + rhs}; } -template inline auto operator -(Integer l, Integer r) { return Integer{lhs - rhs}; } -template inline auto operator<<(Integer l, Integer r) { return Integer{lhs << rhs}; } -template inline auto operator>>(Integer l, Integer r) { return Integer{lhs >> rhs}; } -template inline auto operator &(Integer l, Integer r) { return Integer{lhs & rhs}; } -template inline auto operator ^(Integer l, Integer r) { return Integer{lhs ^ rhs}; } -template inline auto operator |(Integer l, Integer r) { return Integer{lhs | rhs}; } -#undef ALL -#undef ADD -#undef INC -#undef MAX -#undef MIN +#define lhs (int64_t)l +#define rhs r +template inline auto operator *(Integer l, Integer r) { return Integer<64>{lhs * rhs}; } +template inline auto operator /(Integer l, Integer r) { return Integer<64>{lhs / rhs}; } +template inline auto operator %(Integer l, Integer r) { return Integer<64>{lhs % rhs}; } +template inline auto operator +(Integer l, Integer r) { return Integer<64>{lhs + rhs}; } +template inline auto operator -(Integer l, Integer r) { return Integer<64>{lhs - rhs}; } +template inline auto operator<<(Integer l, Integer r) { return Integer<64>{lhs << rhs}; } +template inline auto operator>>(Integer l, Integer r) { return Integer<64>{lhs >> rhs}; } +template inline auto operator &(Integer l, Integer r) { return Integer<64>{lhs & rhs}; } +template inline auto operator ^(Integer l, Integer r) { return Integer<64>{lhs ^ rhs}; } +template inline auto operator |(Integer l, Integer r) { return Integer<64>{lhs | rhs}; } #undef lhs #undef rhs diff --git a/nall/primitives/natural.hpp b/nall/primitives/natural.hpp index 191d41a8..285839b3 100644 --- a/nall/primitives/natural.hpp +++ b/nall/primitives/natural.hpp @@ -2,23 +2,23 @@ namespace nall { -template struct Natural { - enum : uint { Precision = Requested < 1 ? 1 : Requested > 64 ? 64 : Requested }; +template struct Natural { + static_assert(Precision >= 1 && Precision <= 64); static inline constexpr auto bits() -> uint { return Precision; } - using type = + using utype = typename conditional::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 inline Natural(Natural value) { data = mask(value); } template 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 struct Natural { #undef lhs #undef rhs - inline auto bits(int lo, int hi) -> BitRange { return {(type&)data, lo, hi}; } - inline auto bit(int index) -> BitRange { return {(type&)data, index, index}; } - inline auto byte(int index) -> BitRange { return {(type&)data, index * 8 + 0, index * 8 + 7}; } + //work in progress: we want naturalprimitive and primitivenatural 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 inline auto operator *(const T& value) { return Natural<64>{lhs * rhs}; } + template inline auto operator /(const T& value) { return Natural<64>{lhs / rhs}; } + template inline auto operator %(const T& value) { return Natural<64>{lhs % rhs}; } + template inline auto operator +(const T& value) { return Natural<64>{lhs + rhs}; } + template inline auto operator -(const T& value) { return Natural<64>{lhs - rhs}; } + template inline auto operator<<(const T& value) { return Natural<64>{lhs << rhs}; } + template inline auto operator>>(const T& value) { return Natural<64>{lhs >> rhs}; } + template inline auto operator &(const T& value) { return Natural<64>{lhs & rhs}; } + template inline auto operator ^(const T& value) { return Natural<64>{lhs ^ rhs}; } + template 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 { return {(type&)data, lo, hi}; } - inline auto bit(int index) const -> const BitRange { return {(type&)data, index, index}; } - inline auto byte(int index) const -> const BitRange { return {(type&)data, index * 8 + 0, index * 8 + 7}; } + #define lhs l + #define rhs (uint64_t)r + template friend inline auto operator *(const T& l, Natural r) { return Natural<64>{lhs * rhs}; } + template friend inline auto operator %(const T& l, Natural r) { return Natural<64>{lhs / rhs}; } + template friend inline auto operator /(const T& l, Natural r) { return Natural<64>{lhs % rhs}; } + template friend inline auto operator +(const T& l, Natural r) { return Natural<64>{lhs + rhs}; } + template friend inline auto operator -(const T& l, Natural r) { return Natural<64>{lhs - rhs}; } + template friend inline auto operator<<(const T& l, Natural r) { return Natural<64>{lhs << rhs}; } + template friend inline auto operator>>(const T& l, Natural r) { return Natural<64>{lhs >> rhs}; } + template friend inline auto operator &(const T& l, Natural r) { return Natural<64>{lhs & rhs}; } + template friend inline auto operator ^(const T& l, Natural r) { return Natural<64>{lhs ^ rhs}; } + template 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 { return {(utype&)data, lo, hi}; } + inline auto bit(int index) -> BitRange { return {(utype&)data, index, index}; } + inline auto byte(int index) -> BitRange { return {(utype&)data, index * 8 + 0, index * 8 + 7}; } + + inline auto bits(int lo, int hi) const -> const BitRange { return {(utype&)data, lo, hi}; } + inline auto bit(int index) const -> const BitRange { return {(utype&)data, index, index}; } + inline auto byte(int index) const -> const BitRange { 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; + inline auto integer() const -> Integer; 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::type)l -#define rhs (typename Natural::type)r -template inline auto operator *(Natural l, Natural r) { return Natural{lhs * rhs}; } -template inline auto operator /(Natural l, Natural r) { return Natural{lhs / rhs}; } -template inline auto operator %(Natural l, Natural r) { return Natural{lhs % rhs}; } -template inline auto operator +(Natural l, Natural r) { return Natural{lhs + rhs}; } -template inline auto operator -(Natural l, Natural r) { return Natural{lhs - rhs}; } -template inline auto operator<<(Natural l, Natural r) { return Natural{lhs << rhs}; } -template inline auto operator>>(Natural l, Natural r) { return Natural{lhs >> rhs}; } -template inline auto operator &(Natural l, Natural r) { return Natural{lhs & rhs}; } -template inline auto operator ^(Natural l, Natural r) { return Natural{lhs ^ rhs}; } -template inline auto operator |(Natural l, Natural r) { return Natural{lhs | rhs}; } -#undef ALL -#undef ADD -#undef INC -#undef MAX -#undef MIN +#define lhs (uint64_t)l +#define rhs (uint64_t)r +template inline auto operator *(Natural l, Natural r) { return Natural<64>{lhs * rhs}; } +template inline auto operator /(Natural l, Natural r) { return Natural<64>{lhs / rhs}; } +template inline auto operator %(Natural l, Natural r) { return Natural<64>{lhs % rhs}; } +template inline auto operator +(Natural l, Natural r) { return Natural<64>{lhs + rhs}; } +template inline auto operator -(Natural l, Natural r) { return Natural<64>{lhs - rhs}; } +template inline auto operator<<(Natural l, Natural r) { return Natural<64>{lhs << rhs}; } +template inline auto operator>>(Natural l, Natural r) { return Natural<64>{lhs >> rhs}; } +template inline auto operator &(Natural l, Natural r) { return Natural<64>{lhs & rhs}; } +template inline auto operator ^(Natural l, Natural r) { return Natural<64>{lhs ^ rhs}; } +template inline auto operator |(Natural l, Natural r) { return Natural<64>{lhs | rhs}; } #undef lhs #undef rhs diff --git a/nall/primitives/real.hpp b/nall/primitives/real.hpp index ba8fa763..286835af 100644 --- a/nall/primitives/real.hpp +++ b/nall/primitives/real.hpp @@ -2,18 +2,20 @@ namespace nall { -template struct Real { - enum : uint { Precision = Requested <= 32 ? 32 : 64 }; +template struct Real { + static_assert(Precision == 32 || Precision == 64); static inline constexpr auto bits() -> uint { return Precision; } - using type = + using ftype = typename conditional::type>::type; inline Real() : data(0.0) {} - template inline Real(const T& value) : data((type)value) {} + template inline Real(Real value) : data((ftype)value) {} + template 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 struct Real { inline auto serialize(serializer& s) { s(data); } private: - type data; + ftype data; }; -#define lhs (long double)(typename Real::type)l +#define lhs (float64_t)(typename Real::type)l #define rhs (typename Real::type)r template inline auto operator*(Real l, Real r) { return Real<64>{lhs * rhs}; } template inline auto operator/(Real l, Real r) { return Real<64>{lhs / rhs}; } diff --git a/nall/string.hpp b/nall/string.hpp index 53c9d404..dd2d6244 100644 --- a/nall/string.hpp +++ b/nall/string.hpp @@ -362,4 +362,4 @@ inline auto operator"" _s(const char* value, std::size_t) -> string { return {va #include #include -//#include +#include diff --git a/nall/string/transform/dml.hpp b/nall/string/transform/dml.hpp index 046b58d0..31d6ae86 100644 --- a/nall/string/transform/dml.hpp +++ b/nall/string/transform/dml.hpp @@ -213,8 +213,8 @@ auto DML::markup(const string& s) -> string { boolean deletion; boolean code; - natural link, linkBase; - natural embed, embedBase; + uint link, linkBase; + uint embed, embedBase; for(uint n = 0; n < s.size();) { char a = s[n];