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() {
166 asm volatile(
"mtc2 $0, $%0" ::
"i"(
static_cast<uint32_t>(reg)));
168 asm volatile(
"ctc2 $0, $%0" ::
"i"(
static_cast<uint32_t>(reg) - 32));
170 if constexpr (safety ==
Safe) {
171 asm volatile(
"nop; nop");
183template <Register reg, Safety safety = Safe>
186 if (__builtin_constant_p(
value) && (
value == 0)) {
187 clear<reg, safety>();
190 asm volatile(
"mtc2 %0, $%1" ::
"r"(
value),
"i"(
static_cast<uint32_t>(reg)));
192 asm volatile(
"ctc2 %0, $%1" ::
"r"(
value),
"i"(
static_cast<uint32_t>(reg) - 32));
194 if constexpr (safety ==
Safe) {
195 asm volatile(
"nop; nop");
208template <Register reg,
bool val
id = false>
209static inline void writeSafe(
Short fp) {
210 static_assert(valid,
"Unable to write single fixed point to register");
220template <Register reg,
bool val
id = false>
221static inline void writeUnsafe(
Short fp) {
222 static_assert(valid,
"Unable to write single fixed point to register");
232template <Register reg,
bool val
id = false>
234 static_assert(valid,
"Unable to write double fixed point to register");
245template <Register reg,
bool val
id = false>
247 static_assert(valid,
"Unable to write double fixed point to register");
273template <PseudoRegister reg,
bool val
id = false>
274static inline void writeSafe(
const Matrix33&
in) {
275 static_assert(valid,
"Unable to write matrix to pseudo register");
285template <PseudoRegister reg,
bool val
id = false>
286static inline void writeUnsafe(
const Matrix33&
in) {
287 static_assert(valid,
"Unable to write matrix to pseudo register");
297template <PseudoRegister reg,
bool val
id = false>
298static inline void writeSafe(
const Vec3&
in) {
299 static_assert(valid,
"Unable to write vector to pseudo register");
309template <PseudoRegister reg,
bool val
id = false>
310static inline void writeSafe(
const Vec2&
in) {
311 static_assert(valid,
"Unable to write vector to pseudo register");
321template <PseudoRegister reg,
bool val
id = false>
322static inline void writeUnsafe(
const Vec3&
in) {
323 static_assert(valid,
"Unable to write vector to pseudo register");
333template <PseudoRegister reg,
bool val
id = false>
334static inline void writeUnsafe(
const Vec2&
in) {
335 static_assert(valid,
"Unable to write vector to pseudo register");
345template <Register reg, Safety safety = Safe>
348 static_assert(reg <
Register::R11R12,
"Unable to write to register from memory directly");
350 asm volatile(
"lwc2 $%1, 0(%0)" ::
"r"(
ptr),
"i"(
static_cast<uint32_t>(reg)));
353 if constexpr (safety ==
Safe) {
354 asm volatile(
"nop; nop");
366template <Register reg, Safety safety = Safe>
371 if constexpr (safety ==
Safe) {
372 asm volatile(
"mfc2 %0, $%1; nop" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg)));
373 }
else if constexpr (safety ==
Unsafe) {
374 asm volatile(
"mfc2 %0, $%1" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg)));
377 if constexpr (safety ==
Safe) {
378 asm volatile(
"cfc2 %0, $%1; nop" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg) - 32));
379 }
else if constexpr (safety ==
Unsafe) {
380 asm volatile(
"cfc2 %0, $%1" :
"=r"(
value) :
"i"(static_cast<
uint32_t>(reg) - 32));
395template <Register reg>
398 static_assert(reg <
Register::R11R12,
"Unable to read from register to memory directly");
400 asm volatile(
"swc2 $%2, 0(%1)" :
"=m"(*ptr) :
"r"(
ptr),
"i"(
static_cast<uint32_t>(reg)));
412template <PseudoRegister reg,
bool val
id = false>
413static inline PackedVec3 readSafe() {
415 static_assert(valid,
"Unable to read pseudo register as vector");
429template <PseudoRegister reg,
bool val
id = false>
430static inline PackedVec3 readUnsafe() {
432 static_assert(valid,
"Unable to read pseudo register as vector");
439template <PseudoRegister reg,
bool val
id = false>
440[[deprecated(
"Use the reference version instead")]]
static inline void read(
Vec3*
ptr) {
442 static_assert(valid,
"Unable to read pseudo register as vector");
447template <PseudoRegister reg,
bool val
id = false>
448static inline void read(
Vec3& vec) {
450 static_assert(valid,
"Unable to read pseudo register as vector");
460 write<Register::VXY0, Safe>(x | (y << 16));
466 write<Register::VZ0, Safe>(z);
473 write<Register::VXY1, Safe>(x | (y << 16));
479 write<Register::VZ1, Safe>(z);
486 write<Register::VXY2, Safe>(x | (y << 16));
492 write<Register::VZ2, Safe>(z);
498 write<Register::OTZ, Safe>(z);
504 write<Register::IR0, Safe>(x);
510 write<Register::IR1, Safe>(x);
516 write<Register::IR2, Safe>(x);
522 write<Register::IR3, Safe>(x);
529 write<Register::R11R12, Safe>(x | (y << 16));
536 write<Register::R13R21, Safe>(x | (y << 16));
543 write<Register::R22R23, Safe>(x | (y << 16));
550 write<Register::R31R32, Safe>(x | (y << 16));
556 write<Register::R33, Safe>(z);
563 write<Register::L11L12, Safe>(x | (y << 16));
570 write<Register::L13L21, Safe>(x | (y << 16));
577 write<Register::L22L23, Safe>(x | (y << 16));
584 write<Register::L31L32, Safe>(x | (y << 16));
590 write<Register::L33, Safe>(z);
597 write<Register::LR1LR2, Safe>(x | (y << 16));
604 write<Register::LR3LG1, Safe>(x | (y << 16));
611 write<Register::LG2LG3, Safe>(x | (y << 16));
618 write<Register::LB1LB2, Safe>(x | (y << 16));
624 write<Register::LB3, Safe>(z);
630 write<Register::ZSF3, Safe>(z);
636 write<Register::ZSF4, Safe>(z);
643 write<Register::VXY0, Unsafe>(x | (y << 16));
649 write<Register::VZ0, Unsafe>(z);
656 write<Register::VXY1, Unsafe>(x | (y << 16));
662 write<Register::VZ1, Unsafe>(z);
669 write<Register::VXY2, Unsafe>(x | (y << 16));
675 write<Register::VZ2, Unsafe>(z);
681 write<Register::OTZ, Unsafe>(z);
687 write<Register::IR0, Unsafe>(x);
693 write<Register::IR1, Unsafe>(x);
699 write<Register::IR2, Unsafe>(x);
705 write<Register::IR3, Unsafe>(x);
712 write<Register::R11R12, Unsafe>(x | (y << 16));
719 write<Register::R13R21, Unsafe>(x | (y << 16));
726 write<Register::R22R23, Unsafe>(x | (y << 16));
733 write<Register::R31R32, Unsafe>(x | (y << 16));
739 write<Register::R33, Unsafe>(z);
746 write<Register::L11L12, Unsafe>(x | (y << 16));
753 write<Register::L13L21, Unsafe>(x | (y << 16));
760 write<Register::L22L23, Unsafe>(x | (y << 16));
767 write<Register::L31L32, Unsafe>(x | (y << 16));
773 write<Register::L33, Unsafe>(z);
780 write<Register::LR1LR2, Unsafe>(x | (y << 16));
787 write<Register::LR3LG1, Unsafe>(x | (y << 16));
794 write<Register::LG2LG3, Unsafe>(x | (y << 16));
801 write<Register::LB1LB2, Unsafe>(x | (y << 16));
807 write<Register::LB3, Unsafe>(z);
813 write<Register::ZSF3, Unsafe>(z);
819 write<Register::ZSF4, Unsafe>(z);
869 write<Register::TRX, Unsafe>(
in.x.raw());
870 write<Register::TRY, Unsafe>(
in.y.raw());
871 write<Register::TRZ, Safe>(
in.z.raw());
876 write<Register::OFX, Unsafe>(
in.x.raw());
877 write<Register::OFY, Safe>(
in.y.raw());
927 write<Register::TRX, Unsafe>(
in.x.raw());
928 write<Register::TRY, Unsafe>(
in.y.raw());
929 write<Register::TRZ, Unsafe>(
in.z.raw());
934 write<Register::OFX, Unsafe>(
in.x.raw());
935 write<Register::OFY, Unsafe>(
in.y.raw());
941 Short(readRaw<Register::IR2, Safe>(), Short::RAW),
942 Short(readRaw<Register::IR3, Safe>(), Short::RAW));
948 Short(readRaw<Register::MAC2, Safe>(), Short::RAW),
949 Short(readRaw<Register::MAC3, Safe>(), Short::RAW));
955 Short(readRaw<Register::IR2, Unsafe>(), Short::RAW),
956 Short(readRaw<Register::IR3, Unsafe>(), Short::RAW));
961 return PackedVec3(
Short(readRaw<Register::MAC1, Unsafe>(), Short::RAW),
962 Short(readRaw<Register::MAC2, Unsafe>(), Short::RAW),
963 Short(readRaw<Register::MAC3, Unsafe>(), Short::RAW));
968 read<Register::MAC1>(
reinterpret_cast<uint32_t*
>(&
ptr->x));
969 read<Register::MAC2>(
reinterpret_cast<uint32_t*
>(&
ptr->y));
970 read<Register::MAC3>(
reinterpret_cast<uint32_t*
>(&
ptr->z));
975 read<Register::MAC1>(
reinterpret_cast<uint32_t*
>(&
ptr.x));
976 read<Register::MAC2>(
reinterpret_cast<uint32_t*
>(&
ptr.y));
977 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:743
void writeUnsafe< Register::L31L32 >(Short x_, Short y_)
Definition gte-registers.hh:764
void writeUnsafe< Register::VXY1 >(Short x_, Short y_)
Definition gte-registers.hh:653
void writeUnsafe< Register::IR0 >(Short x_)
Definition gte-registers.hh:685
void writeUnsafe< Register::LB1LB2 >(Short x_, Short y_)
Definition gte-registers.hh:798
void writeUnsafe< Register::R13R21 >(Short x_, Short y_)
Definition gte-registers.hh:716
void writeUnsafe< PseudoRegister::Color >(const Matrix33 &in)
Definition gte-registers.hh:899
void writeSafe< Register::L33 >(Short z_)
Definition gte-registers.hh:588
void writeSafe< Register::L11L12 >(Short x_, Short y_)
Definition gte-registers.hh:560
void writeUnsafe< Register::IR3 >(Short x_)
Definition gte-registers.hh:703
void writeUnsafe< Register::VZ0 >(Short z_)
Definition gte-registers.hh:647
void writeSafe< Register::LG2LG3 >(Short x_, Short y_)
Definition gte-registers.hh:608
void writeSafe< Register::IR1 >(Short x_)
Definition gte-registers.hh:508
void writeSafe< Register::LR3LG1 >(Short x_, Short y_)
Definition gte-registers.hh:601
void writeSafe< Register::VXY2 >(Short x_, Short y_)
Definition gte-registers.hh:483
void writeUnsafe< PseudoRegister::ScreenOffset >(const Vec2 &in)
Definition gte-registers.hh:933
void writeUnsafe< Register::VXY2 >(Short x_, Short y_)
Definition gte-registers.hh:666
void writeSafe< Register::VXY0 >(Short x_, Short y_)
Definition gte-registers.hh:457
PackedVec3 readSafe< PseudoRegister::SV >()
Definition gte-registers.hh:939
void writeUnsafe< Register::VZ1 >(Short z_)
Definition gte-registers.hh:660
void writeSafe< PseudoRegister::Color >(const Matrix33 &in)
Definition gte-registers.hh:841
void writeSafe< Register::VXY1 >(Short x_, Short y_)
Definition gte-registers.hh:470
void writeUnsafe< Register::R11R12 >(Short x_, Short y_)
Definition gte-registers.hh:709
void writeUnsafe< Register::R31R32 >(Short x_, Short y_)
Definition gte-registers.hh:730
void writeUnsafe< Register::L13L21 >(Short x_, Short y_)
Definition gte-registers.hh:750
void writeUnsafe< Register::R33 >(Short z_)
Definition gte-registers.hh:737
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:771
Register
The list of available GTE registers.
Definition gte-registers.hh:73
void writeSafe< Register::VZ0 >(Short z_)
Definition gte-registers.hh:464
void writeSafe< Register::R22R23 >(Short x_, Short y_)
Definition gte-registers.hh:540
void writeSafe< Register::LB1LB2 >(Short x_, Short y_)
Definition gte-registers.hh:615
void writeUnsafe< Register::ZSF4 >(Short z_)
Definition gte-registers.hh:817
void writeSafe< Register::VZ2 >(Short z_)
Definition gte-registers.hh:490
void writeSafe< Register::ZSF3 >(Short z_)
Definition gte-registers.hh:628
void writeSafe< Register::L13L21 >(Short x_, Short y_)
Definition gte-registers.hh:567
void writeSafe< Register::L31L32 >(Short x_, Short y_)
Definition gte-registers.hh:581
void writeSafe< Register::R31R32 >(Short x_, Short y_)
Definition gte-registers.hh:547
void writeSafe< Register::IR3 >(Short x_)
Definition gte-registers.hh:520
void writeSafe< PseudoRegister::Translation >(const Vec3 &in)
Definition gte-registers.hh:868
void writeSafe< Register::R13R21 >(Short x_, Short y_)
Definition gte-registers.hh:533
void writeUnsafe< PseudoRegister::V2 >(const Vec3 &in)
Definition gte-registers.hh:920
void writeUnsafe< PseudoRegister::Rotation >(const Matrix33 &in)
Definition gte-registers.hh:881
void writeUnsafe< Register::ZSF3 >(Short z_)
Definition gte-registers.hh:811
void writeSafe< Register::VZ1 >(Short z_)
Definition gte-registers.hh:477
void writeSafe< PseudoRegister::V0 >(const Vec3 &in)
Definition gte-registers.hh:850
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:953
void writeSafe< Register::OTZ >(Short z_)
Definition gte-registers.hh:496
void writeSafe< Register::ZSF4 >(Short z_)
Definition gte-registers.hh:634
void writeSafe< PseudoRegister::Rotation >(const Matrix33 &in)
Definition gte-registers.hh:823
void writeUnsafe< Register::R22R23 >(Short x_, Short y_)
Definition gte-registers.hh:723
void writeUnsafe< Register::VZ2 >(Short z_)
Definition gte-registers.hh:673
void read< PseudoRegister::LV >(Vec3 *ptr)
Definition gte-registers.hh:967
void writeUnsafe< Register::LR1LR2 >(Short x_, Short y_)
Definition gte-registers.hh:777
void writeSafe< Register::IR0 >(Short x_)
Definition gte-registers.hh:502
void writeSafe< PseudoRegister::V1 >(const Vec3 &in)
Definition gte-registers.hh:856
void writeUnsafe< Register::L22L23 >(Short x_, Short y_)
Definition gte-registers.hh:757
void writeUnsafe< PseudoRegister::V1 >(const Vec3 &in)
Definition gte-registers.hh:914
void writeUnsafe< PseudoRegister::Light >(const Matrix33 &in)
Definition gte-registers.hh:890
void writeSafe< PseudoRegister::V2 >(const Vec3 &in)
Definition gte-registers.hh:862
void writeUnsafe< Register::VXY0 >(Short x_, Short y_)
Definition gte-registers.hh:640
void writeUnsafe< Register::LB3 >(Short z_)
Definition gte-registers.hh:805
void writeUnsafe< PseudoRegister::Translation >(const Vec3 &in)
Definition gte-registers.hh:926
void writeSafe< Register::LB3 >(Short z_)
Definition gte-registers.hh:622
void writeUnsafe< Register::OTZ >(Short z_)
Definition gte-registers.hh:679
void writeSafe< Register::IR2 >(Short x_)
Definition gte-registers.hh:514
void writeSafe< Register::L22L23 >(Short x_, Short y_)
Definition gte-registers.hh:574
void writeUnsafe< PseudoRegister::V0 >(const Vec3 &in)
Definition gte-registers.hh:908
void writeSafe< Register::R11R12 >(Short x_, Short y_)
Definition gte-registers.hh:526
void writeUnsafe< Register::LG2LG3 >(Short x_, Short y_)
Definition gte-registers.hh:791
PackedVec3 readSafe< PseudoRegister::LV >()
Definition gte-registers.hh:946
void writeSafe< Register::R33 >(Short z_)
Definition gte-registers.hh:554
void writeSafe< Register::LR1LR2 >(Short x_, Short y_)
Definition gte-registers.hh:594
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:691
void writeUnsafe< Register::IR2 >(Short x_)
Definition gte-registers.hh:697
PseudoRegister
The list of available GTE pseudo registers.
Definition gte-registers.hh:253
void writeSafe< PseudoRegister::Light >(const Matrix33 &in)
Definition gte-registers.hh:832
PackedVec3 readUnsafe< PseudoRegister::LV >()
Definition gte-registers.hh:960
void writeSafe< PseudoRegister::ScreenOffset >(const Vec2 &in)
Definition gte-registers.hh:875
void writeUnsafe< Register::LR3LG1 >(Short x_, Short y_)
Definition gte-registers.hh:784
Vector< 3 > Vec3
Definition vector.hh:242
Vector< 2 > Vec2
Definition vector.hh:241
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
FixedPoint< precisionBits, T > x
Definition vector.hh:49
PSYQO_NO_UNIQUE_ADDR std::conditional_t<(N > 2), FixedPoint< precisionBits, T >, EmptyZ > z
Definition vector.hh:51
FixedPoint< precisionBits, T > y
Definition vector.hh:49
static int value
Definition syscalls.h:535
static int ret
Definition syscalls.h:73
void uint32_t(classId, spec)