42typedef FixedPoint<12>
Long;
47typedef FixedPoint<12, int16_t>
Short;
63 ret.
x = FixedPoint<>(
x);
64 ret.y = FixedPoint<>(
y);
65 ret.z = FixedPoint<>(
z);
162template <Register reg, Safety safety = Safe>
163static inline void clear() {
165 asm volatile(
"mtc2 $0, $%0" ::
"i"(
static_cast<uint32_t>(reg)));
167 asm volatile(
"ctc2 $0, $%0" ::
"i"(
static_cast<uint32_t>(reg) - 32));
169 if constexpr (safety ==
Safe) {
170 asm volatile(
"nop; nop");
181template <Register reg, Safety safety = Safe>
183 if (__builtin_constant_p(
value) && (
value == 0)) {
184 clear<reg, safety>();
187 asm volatile(
"mtc2 %0, $%1" ::
"r"(
value),
"i"(
static_cast<uint32_t>(reg)));
189 asm volatile(
"ctc2 %0, $%1" ::
"r"(
value),
"i"(
static_cast<uint32_t>(reg) - 32));
191 if constexpr (safety ==
Safe) {
192 asm volatile(
"nop; nop");
204template <Register reg,
bool val
id = false>
205static inline void writeSafe(
Short fp) {
206 static_assert(valid,
"Unable to write single fixed point to register");
216template <Register reg,
bool val
id = false>
217static inline void writeUnsafe(
Short fp) {
218 static_assert(valid,
"Unable to write single fixed point to register");
228template <Register reg,
bool val
id = false>
230 static_assert(valid,
"Unable to write double fixed point to register");
241template <Register reg,
bool val
id = false>
243 static_assert(valid,
"Unable to write double fixed point to register");
269template <PseudoRegister reg,
bool val
id = false>
270static inline void writeSafe(
const Matrix33&
in) {
271 static_assert(valid,
"Unable to write matrix to pseudo register");
281template <PseudoRegister reg,
bool val
id = false>
282static inline void writeUnsafe(
const Matrix33&
in) {
283 static_assert(valid,
"Unable to write matrix to pseudo register");
293template <PseudoRegister reg,
bool val
id = false>
294static inline void writeSafe(
const Vec3&
in) {
295 static_assert(valid,
"Unable to write vector to pseudo register");
305template <PseudoRegister reg,
bool val
id = false>
306static inline void writeSafe(
const Vec2&
in) {
307 static_assert(valid,
"Unable to write vector to pseudo register");
317template <PseudoRegister reg,
bool val
id = false>
318static inline void writeUnsafe(
const Vec3&
in) {
319 static_assert(valid,
"Unable to write vector to pseudo register");
329template <PseudoRegister reg,
bool val
id = false>
330static inline void writeUnsafe(
const Vec2&
in) {
331 static_assert(valid,
"Unable to write vector to pseudo register");
341template <Register reg, Safety safety = Safe>
343 static_assert(reg <
Register::R11R12,
"Unable to write to register from memory directly");
345 asm volatile(
"lwc2 $%1, 0(%0)" ::
"r"(
ptr),
"i"(
static_cast<uint32_t>(reg)));
348 if constexpr (safety ==
Safe) {
349 asm volatile(
"nop; nop");
360template <Register reg, Safety safety = Safe>
364 if constexpr (safety ==
Safe) {
365 asm volatile(
"mfc2 %0, $%1; nop" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg)));
366 }
else if constexpr (safety ==
Unsafe) {
367 asm volatile(
"mfc2 %0, $%1" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg)));
370 if constexpr (safety ==
Safe) {
371 asm volatile(
"cfc2 %0, $%1; nop" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg) - 32));
372 }
else if constexpr (safety ==
Unsafe) {
373 asm volatile(
"cfc2 %0, $%1" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg) - 32));
385template <Register reg>
387 static_assert(reg <
Register::R11R12,
"Unable to read from register to memory directly");
389 asm volatile(
"swc2 $%2, 0(%1)" :
"=m"(*ptr) :
"r"(
ptr),
"i"(
static_cast<uint32_t>(reg)));
400template <PseudoRegister reg,
bool val
id = false>
401static inline PackedVec3 readSafe() {
402 static_assert(valid,
"Unable to read pseudo register as vector");
413template <PseudoRegister reg,
bool val
id = false>
414static inline PackedVec3 readUnsafe() {
415 static_assert(valid,
"Unable to read pseudo register as vector");
419template <PseudoRegister reg,
bool val
id = false>
420[[deprecated(
"Use the reference version instead")]]
static inline void read(
Vec3*
ptr) {
421 static_assert(valid,
"Unable to read pseudo register as vector");
425template <PseudoRegister reg,
bool val
id = false>
426static inline void read(
Vec3& vec) {
427 static_assert(valid,
"Unable to read pseudo register as vector");
436 write<Register::VXY0, Safe>(x | (y << 16));
442 write<Register::VZ0, Safe>(z);
449 write<Register::VXY1, Safe>(x | (y << 16));
455 write<Register::VZ1, Safe>(z);
462 write<Register::VXY2, Safe>(x | (y << 16));
468 write<Register::VZ2, Safe>(z);
474 write<Register::OTZ, Safe>(z);
480 write<Register::IR0, Safe>(x);
486 write<Register::IR1, Safe>(x);
492 write<Register::IR2, Safe>(x);
498 write<Register::IR3, Safe>(x);
505 write<Register::R11R12, Safe>(x | (y << 16));
512 write<Register::R13R21, Safe>(x | (y << 16));
519 write<Register::R22R23, Safe>(x | (y << 16));
526 write<Register::R31R32, Safe>(x | (y << 16));
532 write<Register::R33, Safe>(z);
539 write<Register::L11L12, Safe>(x | (y << 16));
546 write<Register::L13L21, Safe>(x | (y << 16));
553 write<Register::L22L23, Safe>(x | (y << 16));
560 write<Register::L31L32, Safe>(x | (y << 16));
566 write<Register::L33, Safe>(z);
573 write<Register::LR1LR2, Safe>(x | (y << 16));
580 write<Register::LR3LG1, Safe>(x | (y << 16));
587 write<Register::LG2LG3, Safe>(x | (y << 16));
594 write<Register::LB1LB2, Safe>(x | (y << 16));
600 write<Register::LB3, Safe>(z);
606 write<Register::ZSF3, Safe>(z);
612 write<Register::ZSF4, Safe>(z);
619 write<Register::VXY0, Unsafe>(x | (y << 16));
625 write<Register::VZ0, Unsafe>(z);
632 write<Register::VXY1, Unsafe>(x | (y << 16));
638 write<Register::VZ1, Unsafe>(z);
645 write<Register::VXY2, Unsafe>(x | (y << 16));
651 write<Register::VZ2, Unsafe>(z);
657 write<Register::OTZ, Unsafe>(z);
663 write<Register::IR0, Unsafe>(x);
669 write<Register::IR1, Unsafe>(x);
675 write<Register::IR2, Unsafe>(x);
681 write<Register::IR3, Unsafe>(x);
688 write<Register::R11R12, Unsafe>(x | (y << 16));
695 write<Register::R13R21, Unsafe>(x | (y << 16));
702 write<Register::R22R23, Unsafe>(x | (y << 16));
709 write<Register::R31R32, Unsafe>(x | (y << 16));
715 write<Register::R33, Unsafe>(z);
722 write<Register::L11L12, Unsafe>(x | (y << 16));
729 write<Register::L13L21, Unsafe>(x | (y << 16));
736 write<Register::L22L23, Unsafe>(x | (y << 16));
743 write<Register::L31L32, Unsafe>(x | (y << 16));
749 write<Register::L33, Unsafe>(z);
756 write<Register::LR1LR2, Unsafe>(x | (y << 16));
763 write<Register::LR3LG1, Unsafe>(x | (y << 16));
770 write<Register::LG2LG3, Unsafe>(x | (y << 16));
777 write<Register::LB1LB2, Unsafe>(x | (y << 16));
783 write<Register::LB3, Unsafe>(z);
789 write<Register::ZSF3, Unsafe>(z);
795 write<Register::ZSF4, Unsafe>(z);
845 write<Register::TRX, Unsafe>(
in.x.raw());
846 write<Register::TRY, Unsafe>(
in.y.raw());
847 write<Register::TRZ, Safe>(
in.z.raw());
852 write<Register::OFX, Unsafe>(
in.x.raw());
853 write<Register::OFY, Safe>(
in.y.raw());
903 write<Register::TRX, Unsafe>(
in.x.raw());
904 write<Register::TRY, Unsafe>(
in.y.raw());
905 write<Register::TRZ, Unsafe>(
in.z.raw());
910 write<Register::OFX, Unsafe>(
in.x.raw());
911 write<Register::OFY, Unsafe>(
in.y.raw());
917 Short(readRaw<Register::IR2, Safe>(), Short::RAW),
918 Short(readRaw<Register::IR3, Safe>(), Short::RAW));
924 Short(readRaw<Register::MAC2, Safe>(), Short::RAW),
925 Short(readRaw<Register::MAC3, Safe>(), Short::RAW));
931 Short(readRaw<Register::IR2, Unsafe>(), Short::RAW),
932 Short(readRaw<Register::IR3, Unsafe>(), Short::RAW));
937 return PackedVec3(
Short(readRaw<Register::MAC1, Unsafe>(), Short::RAW),
938 Short(readRaw<Register::MAC2, Unsafe>(), Short::RAW),
939 Short(readRaw<Register::MAC3, Unsafe>(), Short::RAW));
944 read<Register::MAC1>(
reinterpret_cast<uint32_t*
>(&
ptr->x));
945 read<Register::MAC2>(
reinterpret_cast<uint32_t*
>(&
ptr->y));
946 read<Register::MAC3>(
reinterpret_cast<uint32_t*
>(&
ptr->z));
951 read<Register::MAC1>(
reinterpret_cast<uint32_t*
>(&
ptr.x));
952 read<Register::MAC2>(
reinterpret_cast<uint32_t*
>(&
ptr.y));
953 read<Register::MAC3>(
reinterpret_cast<uint32_t*
>(&
ptr.z));
volatile uint32_t * ptr
Definition cop0.c:80
int32_t hi
Definition cpu.c:154
char in[50]
Definition memcpy.c:74
void writeUnsafe< Register::L11L12 >(Short x_, Short y_)
Definition gte-registers.hh:719
void writeUnsafe< Register::L31L32 >(Short x_, Short y_)
Definition gte-registers.hh:740
void writeUnsafe< Register::VXY1 >(Short x_, Short y_)
Definition gte-registers.hh:629
void writeUnsafe< Register::IR0 >(Short x_)
Definition gte-registers.hh:661
void writeUnsafe< Register::LB1LB2 >(Short x_, Short y_)
Definition gte-registers.hh:774
void writeUnsafe< Register::R13R21 >(Short x_, Short y_)
Definition gte-registers.hh:692
void writeUnsafe< PseudoRegister::Color >(const Matrix33 &in)
Definition gte-registers.hh:875
void writeSafe< Register::L33 >(Short z_)
Definition gte-registers.hh:564
void writeSafe< Register::L11L12 >(Short x_, Short y_)
Definition gte-registers.hh:536
void writeUnsafe< Register::IR3 >(Short x_)
Definition gte-registers.hh:679
void writeUnsafe< Register::VZ0 >(Short z_)
Definition gte-registers.hh:623
void writeSafe< Register::LG2LG3 >(Short x_, Short y_)
Definition gte-registers.hh:584
void writeSafe< Register::IR1 >(Short x_)
Definition gte-registers.hh:484
void writeSafe< Register::LR3LG1 >(Short x_, Short y_)
Definition gte-registers.hh:577
void writeSafe< Register::VXY2 >(Short x_, Short y_)
Definition gte-registers.hh:459
void writeUnsafe< PseudoRegister::ScreenOffset >(const Vec2 &in)
Definition gte-registers.hh:909
void writeUnsafe< Register::VXY2 >(Short x_, Short y_)
Definition gte-registers.hh:642
void writeSafe< Register::VXY0 >(Short x_, Short y_)
Definition gte-registers.hh:433
PackedVec3 readSafe< PseudoRegister::SV >()
Definition gte-registers.hh:915
void writeUnsafe< Register::VZ1 >(Short z_)
Definition gte-registers.hh:636
void writeSafe< PseudoRegister::Color >(const Matrix33 &in)
Definition gte-registers.hh:817
void writeSafe< Register::VXY1 >(Short x_, Short y_)
Definition gte-registers.hh:446
void writeUnsafe< Register::R11R12 >(Short x_, Short y_)
Definition gte-registers.hh:685
void writeUnsafe< Register::R31R32 >(Short x_, Short y_)
Definition gte-registers.hh:706
void writeUnsafe< Register::L13L21 >(Short x_, Short y_)
Definition gte-registers.hh:726
void writeUnsafe< Register::R33 >(Short z_)
Definition gte-registers.hh:713
Safety
Whether to insert nops after register operations.
Definition gte-registers.hh:151
@ Safe
Definition gte-registers.hh:153
@ Unsafe
Definition gte-registers.hh:152
void writeUnsafe< Register::L33 >(Short z_)
Definition gte-registers.hh:747
Register
The list of available GTE registers.
Definition gte-registers.hh:73
void writeSafe< Register::VZ0 >(Short z_)
Definition gte-registers.hh:440
void writeSafe< Register::R22R23 >(Short x_, Short y_)
Definition gte-registers.hh:516
void writeSafe< Register::LB1LB2 >(Short x_, Short y_)
Definition gte-registers.hh:591
void writeUnsafe< Register::ZSF4 >(Short z_)
Definition gte-registers.hh:793
void writeSafe< Register::VZ2 >(Short z_)
Definition gte-registers.hh:466
void writeSafe< Register::ZSF3 >(Short z_)
Definition gte-registers.hh:604
void writeSafe< Register::L13L21 >(Short x_, Short y_)
Definition gte-registers.hh:543
void writeSafe< Register::L31L32 >(Short x_, Short y_)
Definition gte-registers.hh:557
void writeSafe< Register::R31R32 >(Short x_, Short y_)
Definition gte-registers.hh:523
void writeSafe< Register::IR3 >(Short x_)
Definition gte-registers.hh:496
void writeSafe< PseudoRegister::Translation >(const Vec3 &in)
Definition gte-registers.hh:844
void writeSafe< Register::R13R21 >(Short x_, Short y_)
Definition gte-registers.hh:509
void writeUnsafe< PseudoRegister::V2 >(const Vec3 &in)
Definition gte-registers.hh:896
void writeUnsafe< PseudoRegister::Rotation >(const Matrix33 &in)
Definition gte-registers.hh:857
void writeUnsafe< Register::ZSF3 >(Short z_)
Definition gte-registers.hh:787
void writeSafe< Register::VZ1 >(Short z_)
Definition gte-registers.hh:453
void writeSafe< PseudoRegister::V0 >(const Vec3 &in)
Definition gte-registers.hh:826
FixedPoint< 12, int16_t > Short
A GTE-compatible 16-bits fixed point number.
Definition gte-registers.hh:47
PackedVec3 readUnsafe< PseudoRegister::SV >()
Definition gte-registers.hh:929
void writeSafe< Register::OTZ >(Short z_)
Definition gte-registers.hh:472
void writeSafe< Register::ZSF4 >(Short z_)
Definition gte-registers.hh:610
void writeSafe< PseudoRegister::Rotation >(const Matrix33 &in)
Definition gte-registers.hh:799
void writeUnsafe< Register::R22R23 >(Short x_, Short y_)
Definition gte-registers.hh:699
void writeUnsafe< Register::VZ2 >(Short z_)
Definition gte-registers.hh:649
void read< PseudoRegister::LV >(Vec3 *ptr)
Definition gte-registers.hh:943
void writeUnsafe< Register::LR1LR2 >(Short x_, Short y_)
Definition gte-registers.hh:753
void writeSafe< Register::IR0 >(Short x_)
Definition gte-registers.hh:478
void writeSafe< PseudoRegister::V1 >(const Vec3 &in)
Definition gte-registers.hh:832
void writeUnsafe< Register::L22L23 >(Short x_, Short y_)
Definition gte-registers.hh:733
void writeUnsafe< PseudoRegister::V1 >(const Vec3 &in)
Definition gte-registers.hh:890
void writeUnsafe< PseudoRegister::Light >(const Matrix33 &in)
Definition gte-registers.hh:866
void writeSafe< PseudoRegister::V2 >(const Vec3 &in)
Definition gte-registers.hh:838
void writeUnsafe< Register::VXY0 >(Short x_, Short y_)
Definition gte-registers.hh:616
void writeUnsafe< Register::LB3 >(Short z_)
Definition gte-registers.hh:781
void writeUnsafe< PseudoRegister::Translation >(const Vec3 &in)
Definition gte-registers.hh:902
void writeSafe< Register::LB3 >(Short z_)
Definition gte-registers.hh:598
void writeUnsafe< Register::OTZ >(Short z_)
Definition gte-registers.hh:655
void writeSafe< Register::IR2 >(Short x_)
Definition gte-registers.hh:490
void writeSafe< Register::L22L23 >(Short x_, Short y_)
Definition gte-registers.hh:550
void writeUnsafe< PseudoRegister::V0 >(const Vec3 &in)
Definition gte-registers.hh:884
void writeSafe< Register::R11R12 >(Short x_, Short y_)
Definition gte-registers.hh:502
void writeUnsafe< Register::LG2LG3 >(Short x_, Short y_)
Definition gte-registers.hh:767
PackedVec3 readSafe< PseudoRegister::LV >()
Definition gte-registers.hh:922
void writeSafe< Register::R33 >(Short z_)
Definition gte-registers.hh:530
void writeSafe< Register::LR1LR2 >(Short x_, Short y_)
Definition gte-registers.hh:570
FixedPoint< 12 > Long
A GTE-compatible 32-bits fixed point number.
Definition gte-registers.hh:42
void writeUnsafe< Register::IR1 >(Short x_)
Definition gte-registers.hh:667
void writeUnsafe< Register::IR2 >(Short x_)
Definition gte-registers.hh:673
PseudoRegister
The list of available GTE pseudo registers.
Definition gte-registers.hh:249
void writeSafe< PseudoRegister::Light >(const Matrix33 &in)
Definition gte-registers.hh:808
PackedVec3 readUnsafe< PseudoRegister::LV >()
Definition gte-registers.hh:936
void writeSafe< PseudoRegister::ScreenOffset >(const Vec2 &in)
Definition gte-registers.hh:851
void writeUnsafe< Register::LR3LG1 >(Short x_, Short y_)
Definition gte-registers.hh:760
Definition cdrom-loader.hh:39
Vector< 3 > Vec3
Definition vector.hh:234
Vector< 2 > Vec2
Definition vector.hh:233
A GTE-compatible short vector.
Definition gte-registers.hh:52
Short x
Definition gte-registers.hh:53
Short z
Definition gte-registers.hh:53
Short y
Definition gte-registers.hh:53
PackedVec3(Short x_, Short y_, Short z_)
Definition gte-registers.hh:55
PackedVec3(const Vec3 &v)
Definition gte-registers.hh:56
std::conditional_t<(N > 2), FixedPoint< precisionBits, T >, EmptyZ > z
Definition vector.hh:43
FixedPoint< precisionBits, T > x
Definition vector.hh:41
FixedPoint< precisionBits, T > y
Definition vector.hh:41
static int value
Definition syscalls.h:534
static int ret
Definition syscalls.h:72
void uint32_t(classId, spec)