bsnes/nall/primitives.hpp

24 lines
703 B
C++
Raw Normal View History

#pragma once
#include <nall/serializer.hpp>
#include <nall/traits.hpp>
namespace nall {
Update to v106r77 release. byuu says: So this turned out to be a rather unproductive ten-hour rabbit hole, but ... I reworked nall/primitives.hpp a lot. And because the changes are massive, testing of this WIP for regressions is critically important. I really can't stress that enough, we're almost certainly going to have some hidden regressions here ... We now have a nall/primitives/ subfolder that splits up the classes into manageable components. The bit-field support is now shared between both Natural and Integer. All of the assignment operator overloads are now templated and take references instead of values. Things like the GSU::Register class are non-copyable on account of the function<> object inside of it, and previously only operator= would work with classes like that. The big change is nall/primitives/operators.hpp, which is a really elaborate system to compute the minimum number of bits needed for any operation, and to return a Natural<T> or Integer<T> when one or both of the arguments are such a type. Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3 breaks if we include operators.hpp. Zelda 3 runs fine with this, but I had to make a huge amount of core changes, including introducing a new ternary(bool, lhs, rhs) function to nall/algorithm to get past Natural<X> and Natural<Y> not being equivalent (is_integral types get a special exemption to ternary ?: type equivalence, yet it's impossible to simulate with our own classes, which is bullshit.) The horrifying part is that ternary() will evaluate both lhs and rhs, unlike ?: I converted some of the functions to test ? uint(x) : uint(y), and others to ternary(test, x, y) ... I don't have a strong preference either way yet. But the part where things may have gotten broken is in the changes to where ternary() was placed. Some cases like in the GBA PPU renderer, it was rather unclear the order of evaluations, so I may have made a mistake somewhere. So again, please please test this if you can. Or even better, look over the diff. Longer-term, I'd really like the enable nall/primitives/operators.hpp, but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help would be appreciated, but ... it's gonna be really complex and difficult to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
struct Boolean;
template<int Precision> struct Natural;
template<int Precision> struct Integer;
Update to v106r76 release. byuu says: I added some useful new functions to nall/primitives: auto Natural<T>::integer() const -> Integer<T>; auto Integer<T>::natural() const -> Natural<T>; These let you cast between signed and unsigned representation without having to care about the value of T (eg if you take a Natural<T> as a template parameter.) So for instance when you're given an unsigned type but it's supposed to be a sign-extended type (example: signed multiplication), eg Natural<T> → Integer<T>, you can just say: x = y.integer() * z.integer(); The TLCS900H core gained some more pesky instructions such as DAA, BS1F, BS1B. I stole an optimization from RACE for calculating the overflow flag on addition. Assuming: z = x + y + c; Before: ~(x ^ y) & (x ^ z) & signBit; After: (x ^ z) & (y ^ z) & signBit; Subtraction stays the same. Assuming: z = x - y - c; Same: (x ^ y) & (x ^ z) & signBit; However, taking a speed penalty, I've implemented the carry computation in a way that doesn't require an extra bit. Adding before: uint9 z = x + y + c; c = z & 0x100; Subtracting before: uint9 z = x - y - c; c = z & 0x100; Adding after: uint8 z = x + y + c; c = z < x || z == x && c; Subtracting after: uint8 z = x - y - c; c = z > x || z == x && c; I haven't been able to code golf the new carry computation to be any shorter, unless I include an extra bit, eg for adding: c = z < x + c; But that defeats the entire point of the change. I want the computation to work even when T is uintmax_t. If anyone can come up with a faster method, please let me know. Anyway ... I also had to split off INC and DEC because they compute flags differently (word and long modes don't set flags at all, byte mode doesn't set carry at all.) I also added division by zero support, although I don't know if it's actually hardware accurate. It's what other emulators do, though.
2019-01-11 01:51:18 +00:00
}
Update to v106r77 release. byuu says: So this turned out to be a rather unproductive ten-hour rabbit hole, but ... I reworked nall/primitives.hpp a lot. And because the changes are massive, testing of this WIP for regressions is critically important. I really can't stress that enough, we're almost certainly going to have some hidden regressions here ... We now have a nall/primitives/ subfolder that splits up the classes into manageable components. The bit-field support is now shared between both Natural and Integer. All of the assignment operator overloads are now templated and take references instead of values. Things like the GSU::Register class are non-copyable on account of the function<> object inside of it, and previously only operator= would work with classes like that. The big change is nall/primitives/operators.hpp, which is a really elaborate system to compute the minimum number of bits needed for any operation, and to return a Natural<T> or Integer<T> when one or both of the arguments are such a type. Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3 breaks if we include operators.hpp. Zelda 3 runs fine with this, but I had to make a huge amount of core changes, including introducing a new ternary(bool, lhs, rhs) function to nall/algorithm to get past Natural<X> and Natural<Y> not being equivalent (is_integral types get a special exemption to ternary ?: type equivalence, yet it's impossible to simulate with our own classes, which is bullshit.) The horrifying part is that ternary() will evaluate both lhs and rhs, unlike ?: I converted some of the functions to test ? uint(x) : uint(y), and others to ternary(test, x, y) ... I don't have a strong preference either way yet. But the part where things may have gotten broken is in the changes to where ternary() was placed. Some cases like in the GBA PPU renderer, it was rather unclear the order of evaluations, so I may have made a mistake somewhere. So again, please please test this if you can. Or even better, look over the diff. Longer-term, I'd really like the enable nall/primitives/operators.hpp, but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help would be appreciated, but ... it's gonna be really complex and difficult to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
#include <nall/primitives/bit-range.hpp>
#include <nall/primitives/boolean.hpp>
#include <nall/primitives/natural.hpp>
#include <nall/primitives/integer.hpp>
#include <nall/primitives/real.hpp>
#include <nall/primitives/types.hpp>
//#include <nall/primitives/operators.hpp>
Update to v106r77 release. byuu says: So this turned out to be a rather unproductive ten-hour rabbit hole, but ... I reworked nall/primitives.hpp a lot. And because the changes are massive, testing of this WIP for regressions is critically important. I really can't stress that enough, we're almost certainly going to have some hidden regressions here ... We now have a nall/primitives/ subfolder that splits up the classes into manageable components. The bit-field support is now shared between both Natural and Integer. All of the assignment operator overloads are now templated and take references instead of values. Things like the GSU::Register class are non-copyable on account of the function<> object inside of it, and previously only operator= would work with classes like that. The big change is nall/primitives/operators.hpp, which is a really elaborate system to compute the minimum number of bits needed for any operation, and to return a Natural<T> or Integer<T> when one or both of the arguments are such a type. Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3 breaks if we include operators.hpp. Zelda 3 runs fine with this, but I had to make a huge amount of core changes, including introducing a new ternary(bool, lhs, rhs) function to nall/algorithm to get past Natural<X> and Natural<Y> not being equivalent (is_integral types get a special exemption to ternary ?: type equivalence, yet it's impossible to simulate with our own classes, which is bullshit.) The horrifying part is that ternary() will evaluate both lhs and rhs, unlike ?: I converted some of the functions to test ? uint(x) : uint(y), and others to ternary(test, x, y) ... I don't have a strong preference either way yet. But the part where things may have gotten broken is in the changes to where ternary() was placed. Some cases like in the GBA PPU renderer, it was rather unclear the order of evaluations, so I may have made a mistake somewhere. So again, please please test this if you can. Or even better, look over the diff. Longer-term, I'd really like the enable nall/primitives/operators.hpp, but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help would be appreciated, but ... it's gonna be really complex and difficult to debug, so I'm probably gonna be on my own here ... sigh.
2019-01-13 06:25:14 +00:00
namespace nall {
template<int Bits> auto Natural<Bits>::integer() const -> Integer<Bits> { return Integer<Bits>(*this); }
template<int Bits> auto Integer<Bits>::natural() const -> Natural<Bits> { return Natural<Bits>(*this); }
}