Nugget
Loading...
Searching...
No Matches
gte-registers.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2023 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <stdint.h>
30
31#include "psyqo/fixed-point.hh"
32#include "psyqo/matrix.hh"
33#include "psyqo/vector.hh"
34
35namespace psyqo {
36
37namespace GTE {
38
42typedef FixedPoint<12> Long;
43
47typedef FixedPoint<12, int16_t> Short;
48
52struct PackedVec3 {
54 PackedVec3() = default;
55 explicit PackedVec3(Short x_, Short y_, Short z_) : x(x_), y(y_), z(z_) {}
56 explicit PackedVec3(const Vec3& v) {
57 x = Short(v.x);
58 y = Short(v.y);
59 z = Short(v.z);
60 }
61 operator Vec3() const {
62 Vec3 ret;
63 ret.x = FixedPoint<>(x);
64 ret.y = FixedPoint<>(y);
65 ret.z = FixedPoint<>(z);
66 return ret;
67 }
68};
69
73enum class Register {
74 VXY0, /* Vector 0 (X,Y) */
75 VZ0, /* Vector 0 (Z) */
76 VXY1, /* Vector 1 (X,Y) */
77 VZ1, /* Vector 1 (Z) */
78 VXY2, /* Vector 2 (X,Y) */
79 VZ2, /* Vector 2 (Z) */
80 RGB, /* Color/code value */
81 OTZ, /* Average Z value (for Ordering Table) */
82 IR0, /* 16bit Accumulator 0 (Interpolate) */
83 IR1, /* 16bit Accumulator 1 (Vector) */
84 IR2, /* 16bit Accumulator 2 (Vector) */
85 IR3, /* 16bit Accumulator 3 (Vector) */
86 SXY0, /* Screen XY-coordinate 0 FIFO */
87 SXY1, /* Screen XY-coordinate 1 FIFO */
88 SXY2, /* Screen XY-coordinate 2 FIFO */
89 SXYP, /* Screen XY-coordinate P FIFO */
90 SZ0, /* Screen Z-coordinate 0 FIFO */
91 SZ1, /* Screen Z-coordinate 1 FIFO */
92 SZ2, /* Screen Z-coordinate 2 FIFO */
93 SZ3, /* Screen Z-coordinate 3 FIFO */
94 RGB0, /* Color CRGB-code/color 0 FIFO */
95 RGB1, /* Color CRGB-code/color 1 FIFO */
96 RGB2, /* Color CRGB-code/color 2 FIFO */
97 RES1, /* Prohibited */
98 MAC0, /* 32bit Maths Accumulators 0 (Value) */
99 MAC1, /* 32bit Maths Accumulators 1 (Vector) */
100 MAC2, /* 32bit Maths Accumulators 2 (Vector) */
101 MAC3, /* 32bit Maths Accumulators 3 (Vector) */
102 IRGB, /* Convert RGB Color (48bit vs 15bit) */
103 ORGB, /* Convert RGB Color (48bit vs 15bit) */
104 LZCS, /* Count Leading-Zeroes/Ones (sign bits) */
105 LZCR, /* Count Leading-Zeroes/Ones (sign bits) */
106 R11R12, /* Rotation matrix (3x3) */
107 R13R21, /* Rotation matrix (3x3) */
108 R22R23, /* Rotation matrix (3x3) */
109 R31R32, /* Rotation matrix (3x3) */
110 R33, /* Rotation matrix (3x3) */
111 TRX, /* Translation vector (X) */
112 TRY, /* Translation vector (Y) */
113 TRZ, /* Translation vector (Z) */
114 L11L12, /* Light source matrix (3x3) */
115 L13L21, /* Light source matrix (3x3) */
116 L22L23, /* Light source matrix (3x3) */
117 L31L32, /* Light source matrix (3x3) */
118 L33, /* Light source matrix (3x3) */
119 RBK, /* Background color(R) */
120 GBK, /* Background color(G) */
121 BBK, /* Background color(B) */
122 LR1LR2, /* Light color matrix source (3x3) */
123 LR3LG1, /* Light color matrix source (3x3) */
124 LG2LG3, /* Light color matrix source (3x3) */
125 LB1LB2, /* Light color matrix source (3x3) */
126 LB3, /* Light color matrix source (3x3) */
127 RFC, /* Far color (R) */
128 GFC, /* Far color (G) */
129 BFC, /* Far color (B) */
130 OFX, /* Screen offset (X) */
131 OFY, /* Screen offset (Y) */
132 H, /* Projection plane distance. */
133 DQA, /* Depth queing parameter A (coeff) */
134 DQB, /* Depth queing parameter B (offset) */
135 ZSF3, /* Average Z scale factors */
136 ZSF4, /* Average Z scale factors */
137 FLAG, /* Returns any calculation errors */
138};
139
151enum Safety {
152 Unsafe, /* avoid nops */
153 Safe, /* insert nops */
154};
155
162template <Register reg, Safety safety = Safe>
163static inline void clear() {
164#ifndef PS1_PC_PORT
165 if constexpr (reg < Register::R11R12) {
166 asm volatile("mtc2 $0, $%0" ::"i"(static_cast<uint32_t>(reg)));
167 } else if constexpr (reg >= Register::R11R12) {
168 asm volatile("ctc2 $0, $%0" ::"i"(static_cast<uint32_t>(reg) - 32));
169 }
170 if constexpr (safety == Safe) {
171 asm volatile("nop; nop");
172 }
173#endif
174}
175
183template <Register reg, Safety safety = Safe>
184static inline void write(uint32_t value) {
185#ifndef PS1_PC_PORT
186 if (__builtin_constant_p(value) && (value == 0)) {
187 clear<reg, safety>();
188 } else {
189 if constexpr (reg < Register::R11R12) {
190 asm volatile("mtc2 %0, $%1" ::"r"(value), "i"(static_cast<uint32_t>(reg)));
191 } else if constexpr (reg >= Register::R11R12) {
192 asm volatile("ctc2 %0, $%1" ::"r"(value), "i"(static_cast<uint32_t>(reg) - 32));
193 }
194 if constexpr (safety == Safe) {
195 asm volatile("nop; nop");
196 }
197 }
198#endif
199}
200
208template <Register reg, bool valid = false>
209static inline void writeSafe(Short fp) {
210 static_assert(valid, "Unable to write single fixed point to register");
211}
212
220template <Register reg, bool valid = false>
221static inline void writeUnsafe(Short fp) {
222 static_assert(valid, "Unable to write single fixed point to register");
223}
224
232template <Register reg, bool valid = false>
233static inline void writeSafe(Short low, Short hi) {
234 static_assert(valid, "Unable to write double fixed point to register");
235}
236
245template <Register reg, bool valid = false>
246static inline void writeUnsafe(Short low, Short hi) {
247 static_assert(valid, "Unable to write double fixed point to register");
248}
249
253enum class PseudoRegister {
254 Rotation, /* pseudo register for full rotation matrix, mapped to registers R11R12-R33 */
255 Light, /* pseudo register for full light matrix, mapped to registers L11L12-L33 */
256 Color, /* pseudo register for full light color matrix, mapped to registers LR1LR2-LB3 */
257 V0, /* pseudo register for full Vector 0, mapped to registers VXY0 and VZ0 */
258 V1, /* pseudo register for full Vector 1, mapped to registers VXY1 and VZ1 */
259 V2, /* pseudo register for full Vector 2, mapped to registers VXY2 and VZ2 */
260 SV, /* pseudo register for full 16bit Accumulator Vector, mapped to registers IR1-IR3 */
261 LV, /* pseudo register for full 32bit Maths Accumulator Vector, mapped to registers MAC1-MAC3 */
262 Translation, /* pseudo register for full Translation vector, mapped to registers TRX-TRZ */
263 ScreenOffset, /* pseudo register for full Screen offset, mapped to registers OFX and OFY */
264};
265
273template <PseudoRegister reg, bool valid = false>
274static inline void writeSafe(const Matrix33& in) {
275 static_assert(valid, "Unable to write matrix to pseudo register");
276}
277
285template <PseudoRegister reg, bool valid = false>
286static inline void writeUnsafe(const Matrix33& in) {
287 static_assert(valid, "Unable to write matrix to pseudo register");
288}
289
297template <PseudoRegister reg, bool valid = false>
298static inline void writeSafe(const Vec3& in) {
299 static_assert(valid, "Unable to write vector to pseudo register");
300}
301
309template <PseudoRegister reg, bool valid = false>
310static inline void writeSafe(const Vec2& in) {
311 static_assert(valid, "Unable to write vector to pseudo register");
312}
313
321template <PseudoRegister reg, bool valid = false>
322static inline void writeUnsafe(const Vec3& in) {
323 static_assert(valid, "Unable to write vector to pseudo register");
324}
325
333template <PseudoRegister reg, bool valid = false>
334static inline void writeUnsafe(const Vec2& in) {
335 static_assert(valid, "Unable to write vector to pseudo register");
336}
337
345template <Register reg, Safety safety = Safe>
346static inline void write(const uint32_t* ptr) {
347#ifndef PS1_PC_PORT
348 static_assert(reg < Register::R11R12, "Unable to write to register from memory directly");
349 if constexpr (reg < Register::R11R12) {
350 asm volatile("lwc2 $%1, 0(%0)" ::"r"(ptr), "i"(static_cast<uint32_t>(reg)));
351 }
352
353 if constexpr (safety == Safe) {
354 asm volatile("nop; nop");
355 }
356#endif
357}
358
366template <Register reg, Safety safety = Safe>
367static inline uint32_t readRaw() {
368#ifndef PS1_PC_PORT
370 if constexpr (reg < Register::R11R12) {
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)));
375 }
376 } else if constexpr (reg >= Register::R11R12) {
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));
381 }
382 }
383 return value;
384#else
385 return 0;
386#endif
387}
388
395template <Register reg>
396static inline void read(uint32_t* ptr) {
397#ifndef PS1_PC_PORT
398 static_assert(reg < Register::R11R12, "Unable to read from register to memory directly");
399 if constexpr (reg < Register::R11R12) {
400 asm volatile("swc2 $%2, 0(%1)" : "=m"(*ptr) : "r"(ptr), "i"(static_cast<uint32_t>(reg)));
401 }
402#endif
403}
404
412template <PseudoRegister reg, bool valid = false>
413static inline PackedVec3 readSafe() {
414#ifndef PS1_PC_PORT
415 static_assert(valid, "Unable to read pseudo register as vector");
417#else
418 return {};
419#endif
420}
421
429template <PseudoRegister reg, bool valid = false>
430static inline PackedVec3 readUnsafe() {
431#ifndef PS1_PC_PORT
432 static_assert(valid, "Unable to read pseudo register as vector");
434#else
435 return {};
436#endif
437}
438
439template <PseudoRegister reg, bool valid = false>
440[[deprecated("Use the reference version instead")]] static inline void read(Vec3* ptr) {
441#ifndef PS1_PC_PORT
442 static_assert(valid, "Unable to read pseudo register as vector");
444#endif
445}
446
447template <PseudoRegister reg, bool valid = false>
448static inline void read(Vec3& vec) {
449#ifndef PS1_PC_PORT
450 static_assert(valid, "Unable to read pseudo register as vector");
452#endif
453}
454
455// The following are template specializations for the various GTE registers.
456template <>
458 uint32_t x = uint16_t(x_.raw());
459 uint32_t y = uint16_t(y_.raw());
460 write<Register::VXY0, Safe>(x | (y << 16));
461}
462
463template <>
465 uint32_t z = uint16_t(z_.raw());
466 write<Register::VZ0, Safe>(z);
467}
468
469template <>
471 uint32_t x = uint16_t(x_.raw());
472 uint32_t y = uint16_t(y_.raw());
473 write<Register::VXY1, Safe>(x | (y << 16));
474}
475
476template <>
478 uint32_t z = uint16_t(z_.raw());
479 write<Register::VZ1, Safe>(z);
480}
481
482template <>
484 uint32_t x = uint16_t(x_.raw());
485 uint32_t y = uint16_t(y_.raw());
486 write<Register::VXY2, Safe>(x | (y << 16));
487}
488
489template <>
491 uint32_t z = uint16_t(z_.raw());
492 write<Register::VZ2, Safe>(z);
493}
494
495template <>
497 uint32_t z = uint16_t(z_.raw());
498 write<Register::OTZ, Safe>(z);
499}
500
501template <>
503 uint32_t x = uint16_t(x_.raw());
504 write<Register::IR0, Safe>(x);
505}
506
507template <>
509 uint32_t x = uint16_t(x_.raw());
510 write<Register::IR1, Safe>(x);
511}
512
513template <>
515 uint32_t x = uint16_t(x_.raw());
516 write<Register::IR2, Safe>(x);
517}
518
519template <>
521 uint32_t x = uint16_t(x_.raw());
522 write<Register::IR3, Safe>(x);
523}
524
525template <>
527 uint32_t x = uint16_t(x_.raw());
528 uint32_t y = uint16_t(y_.raw());
529 write<Register::R11R12, Safe>(x | (y << 16));
530}
531
532template <>
534 uint32_t x = uint16_t(x_.raw());
535 uint32_t y = uint16_t(y_.raw());
536 write<Register::R13R21, Safe>(x | (y << 16));
537}
538
539template <>
541 uint32_t x = uint16_t(x_.raw());
542 uint32_t y = uint16_t(y_.raw());
543 write<Register::R22R23, Safe>(x | (y << 16));
544}
545
546template <>
548 uint32_t x = uint16_t(x_.raw());
549 uint32_t y = uint16_t(y_.raw());
550 write<Register::R31R32, Safe>(x | (y << 16));
551}
552
553template <>
555 uint32_t z = uint16_t(z_.raw());
556 write<Register::R33, Safe>(z);
557}
558
559template <>
561 uint32_t x = uint16_t(x_.raw());
562 uint32_t y = uint16_t(y_.raw());
563 write<Register::L11L12, Safe>(x | (y << 16));
564}
565
566template <>
568 uint32_t x = uint16_t(x_.raw());
569 uint32_t y = uint16_t(y_.raw());
570 write<Register::L13L21, Safe>(x | (y << 16));
571}
572
573template <>
575 uint32_t x = uint16_t(x_.raw());
576 uint32_t y = uint16_t(y_.raw());
577 write<Register::L22L23, Safe>(x | (y << 16));
578}
579
580template <>
582 uint32_t x = uint16_t(x_.raw());
583 uint32_t y = uint16_t(y_.raw());
584 write<Register::L31L32, Safe>(x | (y << 16));
585}
586
587template <>
589 uint32_t z = uint16_t(z_.raw());
590 write<Register::L33, Safe>(z);
591}
592
593template <>
595 uint32_t x = uint16_t(x_.raw());
596 uint32_t y = uint16_t(y_.raw());
597 write<Register::LR1LR2, Safe>(x | (y << 16));
598}
599
600template <>
602 uint32_t x = uint16_t(x_.raw());
603 uint32_t y = uint16_t(y_.raw());
604 write<Register::LR3LG1, Safe>(x | (y << 16));
605}
606
607template <>
609 uint32_t x = uint16_t(x_.raw());
610 uint32_t y = uint16_t(y_.raw());
611 write<Register::LG2LG3, Safe>(x | (y << 16));
612}
613
614template <>
616 uint32_t x = uint16_t(x_.raw());
617 uint32_t y = uint16_t(y_.raw());
618 write<Register::LB1LB2, Safe>(x | (y << 16));
619}
620
621template <>
623 uint32_t z = uint16_t(z_.raw());
624 write<Register::LB3, Safe>(z);
625}
626
627template <>
629 uint32_t z = uint16_t(z_.raw());
630 write<Register::ZSF3, Safe>(z);
631}
632
633template <>
635 uint32_t z = uint16_t(z_.raw());
636 write<Register::ZSF4, Safe>(z);
637}
638
639template <>
641 uint32_t x = uint16_t(x_.raw());
642 uint32_t y = uint16_t(y_.raw());
643 write<Register::VXY0, Unsafe>(x | (y << 16));
644}
645
646template <>
648 uint32_t z = uint16_t(z_.raw());
649 write<Register::VZ0, Unsafe>(z);
650}
651
652template <>
654 uint32_t x = uint16_t(x_.raw());
655 uint32_t y = uint16_t(y_.raw());
656 write<Register::VXY1, Unsafe>(x | (y << 16));
657}
658
659template <>
661 uint32_t z = uint16_t(z_.raw());
662 write<Register::VZ1, Unsafe>(z);
663}
664
665template <>
667 uint32_t x = uint16_t(x_.raw());
668 uint32_t y = uint16_t(y_.raw());
669 write<Register::VXY2, Unsafe>(x | (y << 16));
670}
671
672template <>
674 uint32_t z = uint16_t(z_.raw());
675 write<Register::VZ2, Unsafe>(z);
676}
677
678template <>
680 uint32_t z = uint16_t(z_.raw());
681 write<Register::OTZ, Unsafe>(z);
682}
683
684template <>
686 uint32_t x = uint16_t(x_.raw());
687 write<Register::IR0, Unsafe>(x);
688}
689
690template <>
692 uint32_t x = uint16_t(x_.raw());
693 write<Register::IR1, Unsafe>(x);
694}
695
696template <>
698 uint32_t x = uint16_t(x_.raw());
699 write<Register::IR2, Unsafe>(x);
700}
701
702template <>
704 uint32_t x = uint16_t(x_.raw());
705 write<Register::IR3, Unsafe>(x);
706}
707
708template <>
710 uint32_t x = uint16_t(x_.raw());
711 uint32_t y = uint16_t(y_.raw());
712 write<Register::R11R12, Unsafe>(x | (y << 16));
713}
714
715template <>
717 uint32_t x = uint16_t(x_.raw());
718 uint32_t y = uint16_t(y_.raw());
719 write<Register::R13R21, Unsafe>(x | (y << 16));
720}
721
722template <>
724 uint32_t x = uint16_t(x_.raw());
725 uint32_t y = uint16_t(y_.raw());
726 write<Register::R22R23, Unsafe>(x | (y << 16));
727}
728
729template <>
731 uint32_t x = uint16_t(x_.raw());
732 uint32_t y = uint16_t(y_.raw());
733 write<Register::R31R32, Unsafe>(x | (y << 16));
734}
735
736template <>
738 uint32_t z = uint16_t(z_.raw());
739 write<Register::R33, Unsafe>(z);
740}
741
742template <>
744 uint32_t x = uint16_t(x_.raw());
745 uint32_t y = uint16_t(y_.raw());
746 write<Register::L11L12, Unsafe>(x | (y << 16));
747}
748
749template <>
751 uint32_t x = uint16_t(x_.raw());
752 uint32_t y = uint16_t(y_.raw());
753 write<Register::L13L21, Unsafe>(x | (y << 16));
754}
755
756template <>
758 uint32_t x = uint16_t(x_.raw());
759 uint32_t y = uint16_t(y_.raw());
760 write<Register::L22L23, Unsafe>(x | (y << 16));
761}
762
763template <>
765 uint32_t x = uint16_t(x_.raw());
766 uint32_t y = uint16_t(y_.raw());
767 write<Register::L31L32, Unsafe>(x | (y << 16));
768}
769
770template <>
772 uint32_t z = uint16_t(z_.raw());
773 write<Register::L33, Unsafe>(z);
774}
775
776template <>
778 uint32_t x = uint16_t(x_.raw());
779 uint32_t y = uint16_t(y_.raw());
780 write<Register::LR1LR2, Unsafe>(x | (y << 16));
781}
782
783template <>
785 uint32_t x = uint16_t(x_.raw());
786 uint32_t y = uint16_t(y_.raw());
787 write<Register::LR3LG1, Unsafe>(x | (y << 16));
788}
789
790template <>
792 uint32_t x = uint16_t(x_.raw());
793 uint32_t y = uint16_t(y_.raw());
794 write<Register::LG2LG3, Unsafe>(x | (y << 16));
795}
796
797template <>
799 uint32_t x = uint16_t(x_.raw());
800 uint32_t y = uint16_t(y_.raw());
801 write<Register::LB1LB2, Unsafe>(x | (y << 16));
802}
803
804template <>
806 uint32_t z = uint16_t(z_.raw());
807 write<Register::LB3, Unsafe>(z);
808}
809
810template <>
812 uint32_t z = uint16_t(z_.raw());
813 write<Register::ZSF3, Unsafe>(z);
814}
815
816template <>
818 uint32_t z = uint16_t(z_.raw());
819 write<Register::ZSF4, Unsafe>(z);
820}
821
822template <>
824 writeUnsafe<Register::R11R12>(Short(in.vs[0].x), Short(in.vs[0].y));
825 writeUnsafe<Register::R13R21>(Short(in.vs[0].z), Short(in.vs[1].x));
826 writeUnsafe<Register::R22R23>(Short(in.vs[1].y), Short(in.vs[1].z));
827 writeUnsafe<Register::R31R32>(Short(in.vs[2].x), Short(in.vs[2].y));
829}
830
831template <>
833 writeUnsafe<Register::L11L12>(Short(in.vs[0].x), Short(in.vs[0].y));
834 writeUnsafe<Register::L13L21>(Short(in.vs[0].z), Short(in.vs[1].x));
835 writeUnsafe<Register::L22L23>(Short(in.vs[1].y), Short(in.vs[1].z));
836 writeUnsafe<Register::L31L32>(Short(in.vs[2].x), Short(in.vs[2].y));
838}
839
840template <>
842 writeUnsafe<Register::LR1LR2>(Short(in.vs[0].x), Short(in.vs[0].y));
843 writeUnsafe<Register::LR3LG1>(Short(in.vs[0].z), Short(in.vs[1].x));
844 writeUnsafe<Register::LG2LG3>(Short(in.vs[1].y), Short(in.vs[1].z));
845 writeUnsafe<Register::LB1LB2>(Short(in.vs[2].x), Short(in.vs[2].y));
847}
848
849template <>
854
855template <>
860
861template <>
866
867template <>
869 write<Register::TRX, Unsafe>(in.x.raw());
870 write<Register::TRY, Unsafe>(in.y.raw());
871 write<Register::TRZ, Safe>(in.z.raw());
872}
873
874template <>
876 write<Register::OFX, Unsafe>(in.x.raw());
877 write<Register::OFY, Safe>(in.y.raw());
878}
879
880template <>
888
889template <>
897
898template <>
906
907template <>
912
913template <>
918
919template <>
924
925template <>
927 write<Register::TRX, Unsafe>(in.x.raw());
928 write<Register::TRY, Unsafe>(in.y.raw());
929 write<Register::TRZ, Unsafe>(in.z.raw());
930}
931
932template <>
934 write<Register::OFX, Unsafe>(in.x.raw());
935 write<Register::OFY, Unsafe>(in.y.raw());
936}
937
938template <>
940 return PackedVec3(Short(readRaw<Register::IR1, Safe>(), Short::RAW),
941 Short(readRaw<Register::IR2, Safe>(), Short::RAW),
942 Short(readRaw<Register::IR3, Safe>(), Short::RAW));
943}
944
945template <>
947 return PackedVec3(Short(readRaw<Register::MAC1, Safe>(), Short::RAW),
948 Short(readRaw<Register::MAC2, Safe>(), Short::RAW),
949 Short(readRaw<Register::MAC3, Safe>(), Short::RAW));
950}
951
952template <>
954 return PackedVec3(Short(readRaw<Register::IR1, Unsafe>(), Short::RAW),
955 Short(readRaw<Register::IR2, Unsafe>(), Short::RAW),
956 Short(readRaw<Register::IR3, Unsafe>(), Short::RAW));
957}
958
959template <>
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));
964}
965
966template <>
967[[deprecated("Use the reference version instead")]] inline void read<PseudoRegister::LV>(Vec3* ptr) {
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));
971}
972
973template <>
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));
978}
979
980} // namespace GTE
981
982} // namespace psyqo
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
Definition lua.hh:38
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
Definition matrix.hh:33
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
__builtin_unreachable()
static int ret
Definition syscalls.h:73
void uint32_t(classId, spec)