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 if constexpr (reg < Register::R11R12) {
165 asm volatile("mtc2 $0, $%0" ::"i"(static_cast<uint32_t>(reg)));
166 } else if constexpr (reg >= Register::R11R12) {
167 asm volatile("ctc2 $0, $%0" ::"i"(static_cast<uint32_t>(reg) - 32));
168 }
169 if constexpr (safety == Safe) {
170 asm volatile("nop; nop");
171 }
172}
173
181template <Register reg, Safety safety = Safe>
182static inline void write(uint32_t value) {
183 if (__builtin_constant_p(value) && (value == 0)) {
184 clear<reg, safety>();
185 } else {
186 if constexpr (reg < Register::R11R12) {
187 asm volatile("mtc2 %0, $%1" ::"r"(value), "i"(static_cast<uint32_t>(reg)));
188 } else if constexpr (reg >= Register::R11R12) {
189 asm volatile("ctc2 %0, $%1" ::"r"(value), "i"(static_cast<uint32_t>(reg) - 32));
190 }
191 if constexpr (safety == Safe) {
192 asm volatile("nop; nop");
193 }
194 }
195}
196
204template <Register reg, bool valid = false>
205static inline void writeSafe(Short fp) {
206 static_assert(valid, "Unable to write single fixed point to register");
207}
208
216template <Register reg, bool valid = false>
217static inline void writeUnsafe(Short fp) {
218 static_assert(valid, "Unable to write single fixed point to register");
219}
220
228template <Register reg, bool valid = false>
229static inline void writeSafe(Short low, Short hi) {
230 static_assert(valid, "Unable to write double fixed point to register");
231}
232
241template <Register reg, bool valid = false>
242static inline void writeUnsafe(Short low, Short hi) {
243 static_assert(valid, "Unable to write double fixed point to register");
244}
245
249enum class PseudoRegister {
250 Rotation, /* pseudo register for full rotation matrix, mapped to registers R11R12-R33 */
251 Light, /* pseudo register for full light matrix, mapped to registers L11L12-L33 */
252 Color, /* pseudo register for full light color matrix, mapped to registers LR1LR2-LB3 */
253 V0, /* pseudo register for full Vector 0, mapped to registers VXY0 and VZ0 */
254 V1, /* pseudo register for full Vector 1, mapped to registers VXY1 and VZ1 */
255 V2, /* pseudo register for full Vector 2, mapped to registers VXY2 and VZ2 */
256 SV, /* pseudo register for full 16bit Accumulator Vector, mapped to registers IR1-IR3 */
257 LV, /* pseudo register for full 32bit Maths Accumulator Vector, mapped to registers MAC1-MAC3 */
258 Translation, /* pseudo register for full Translation vector, mapped to registers TRX-TRZ */
259 ScreenOffset, /* pseudo register for full Screen offset, mapped to registers OFX and OFY */
260};
261
269template <PseudoRegister reg, bool valid = false>
270static inline void writeSafe(const Matrix33& in) {
271 static_assert(valid, "Unable to write matrix to pseudo register");
272}
273
281template <PseudoRegister reg, bool valid = false>
282static inline void writeUnsafe(const Matrix33& in) {
283 static_assert(valid, "Unable to write matrix to pseudo register");
284}
285
293template <PseudoRegister reg, bool valid = false>
294static inline void writeSafe(const Vec3& in) {
295 static_assert(valid, "Unable to write vector to pseudo register");
296}
297
305template <PseudoRegister reg, bool valid = false>
306static inline void writeSafe(const Vec2& in) {
307 static_assert(valid, "Unable to write vector to pseudo register");
308}
309
317template <PseudoRegister reg, bool valid = false>
318static inline void writeUnsafe(const Vec3& in) {
319 static_assert(valid, "Unable to write vector to pseudo register");
320}
321
329template <PseudoRegister reg, bool valid = false>
330static inline void writeUnsafe(const Vec2& in) {
331 static_assert(valid, "Unable to write vector to pseudo register");
332}
333
341template <Register reg, Safety safety = Safe>
342static inline void write(const uint32_t* ptr) {
343 static_assert(reg < Register::R11R12, "Unable to write to register from memory directly");
344 if constexpr (reg < Register::R11R12) {
345 asm volatile("lwc2 $%1, 0(%0)" ::"r"(ptr), "i"(static_cast<uint32_t>(reg)));
346 }
347
348 if constexpr (safety == Safe) {
349 asm volatile("nop; nop");
350 }
351}
352
360template <Register reg, Safety safety = Safe>
361static inline uint32_t readRaw() {
363 if constexpr (reg < Register::R11R12) {
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)));
368 }
369 } else if constexpr (reg >= Register::R11R12) {
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));
374 }
375 }
376 return value;
377}
378
385template <Register reg>
386static inline void read(uint32_t* ptr) {
387 static_assert(reg < Register::R11R12, "Unable to read from register to memory directly");
388 if constexpr (reg < Register::R11R12) {
389 asm volatile("swc2 $%2, 0(%1)" : "=m"(*ptr) : "r"(ptr), "i"(static_cast<uint32_t>(reg)));
390 }
391}
392
400template <PseudoRegister reg, bool valid = false>
401static inline PackedVec3 readSafe() {
402 static_assert(valid, "Unable to read pseudo register as vector");
404}
405
413template <PseudoRegister reg, bool valid = false>
414static inline PackedVec3 readUnsafe() {
415 static_assert(valid, "Unable to read pseudo register as vector");
417}
418
419template <PseudoRegister reg, bool valid = 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");
423}
424
425template <PseudoRegister reg, bool valid = false>
426static inline void read(Vec3& vec) {
427 static_assert(valid, "Unable to read pseudo register as vector");
429}
430
431// The following are template specializations for the various GTE registers.
432template <>
434 uint32_t x = uint16_t(x_.raw());
435 uint32_t y = uint16_t(y_.raw());
436 write<Register::VXY0, Safe>(x | (y << 16));
437}
438
439template <>
441 uint32_t z = uint16_t(z_.raw());
442 write<Register::VZ0, Safe>(z);
443}
444
445template <>
447 uint32_t x = uint16_t(x_.raw());
448 uint32_t y = uint16_t(y_.raw());
449 write<Register::VXY1, Safe>(x | (y << 16));
450}
451
452template <>
454 uint32_t z = uint16_t(z_.raw());
455 write<Register::VZ1, Safe>(z);
456}
457
458template <>
460 uint32_t x = uint16_t(x_.raw());
461 uint32_t y = uint16_t(y_.raw());
462 write<Register::VXY2, Safe>(x | (y << 16));
463}
464
465template <>
467 uint32_t z = uint16_t(z_.raw());
468 write<Register::VZ2, Safe>(z);
469}
470
471template <>
473 uint32_t z = uint16_t(z_.raw());
474 write<Register::OTZ, Safe>(z);
475}
476
477template <>
479 uint32_t x = uint16_t(x_.raw());
480 write<Register::IR0, Safe>(x);
481}
482
483template <>
485 uint32_t x = uint16_t(x_.raw());
486 write<Register::IR1, Safe>(x);
487}
488
489template <>
491 uint32_t x = uint16_t(x_.raw());
492 write<Register::IR2, Safe>(x);
493}
494
495template <>
497 uint32_t x = uint16_t(x_.raw());
498 write<Register::IR3, Safe>(x);
499}
500
501template <>
503 uint32_t x = uint16_t(x_.raw());
504 uint32_t y = uint16_t(y_.raw());
505 write<Register::R11R12, Safe>(x | (y << 16));
506}
507
508template <>
510 uint32_t x = uint16_t(x_.raw());
511 uint32_t y = uint16_t(y_.raw());
512 write<Register::R13R21, Safe>(x | (y << 16));
513}
514
515template <>
517 uint32_t x = uint16_t(x_.raw());
518 uint32_t y = uint16_t(y_.raw());
519 write<Register::R22R23, Safe>(x | (y << 16));
520}
521
522template <>
524 uint32_t x = uint16_t(x_.raw());
525 uint32_t y = uint16_t(y_.raw());
526 write<Register::R31R32, Safe>(x | (y << 16));
527}
528
529template <>
531 uint32_t z = uint16_t(z_.raw());
532 write<Register::R33, Safe>(z);
533}
534
535template <>
537 uint32_t x = uint16_t(x_.raw());
538 uint32_t y = uint16_t(y_.raw());
539 write<Register::L11L12, Safe>(x | (y << 16));
540}
541
542template <>
544 uint32_t x = uint16_t(x_.raw());
545 uint32_t y = uint16_t(y_.raw());
546 write<Register::L13L21, Safe>(x | (y << 16));
547}
548
549template <>
551 uint32_t x = uint16_t(x_.raw());
552 uint32_t y = uint16_t(y_.raw());
553 write<Register::L22L23, Safe>(x | (y << 16));
554}
555
556template <>
558 uint32_t x = uint16_t(x_.raw());
559 uint32_t y = uint16_t(y_.raw());
560 write<Register::L31L32, Safe>(x | (y << 16));
561}
562
563template <>
565 uint32_t z = uint16_t(z_.raw());
566 write<Register::L33, Safe>(z);
567}
568
569template <>
571 uint32_t x = uint16_t(x_.raw());
572 uint32_t y = uint16_t(y_.raw());
573 write<Register::LR1LR2, Safe>(x | (y << 16));
574}
575
576template <>
578 uint32_t x = uint16_t(x_.raw());
579 uint32_t y = uint16_t(y_.raw());
580 write<Register::LR3LG1, Safe>(x | (y << 16));
581}
582
583template <>
585 uint32_t x = uint16_t(x_.raw());
586 uint32_t y = uint16_t(y_.raw());
587 write<Register::LG2LG3, Safe>(x | (y << 16));
588}
589
590template <>
592 uint32_t x = uint16_t(x_.raw());
593 uint32_t y = uint16_t(y_.raw());
594 write<Register::LB1LB2, Safe>(x | (y << 16));
595}
596
597template <>
599 uint32_t z = uint16_t(z_.raw());
600 write<Register::LB3, Safe>(z);
601}
602
603template <>
605 uint32_t z = uint16_t(z_.raw());
606 write<Register::ZSF3, Safe>(z);
607}
608
609template <>
611 uint32_t z = uint16_t(z_.raw());
612 write<Register::ZSF4, Safe>(z);
613}
614
615template <>
617 uint32_t x = uint16_t(x_.raw());
618 uint32_t y = uint16_t(y_.raw());
619 write<Register::VXY0, Unsafe>(x | (y << 16));
620}
621
622template <>
624 uint32_t z = uint16_t(z_.raw());
625 write<Register::VZ0, Unsafe>(z);
626}
627
628template <>
630 uint32_t x = uint16_t(x_.raw());
631 uint32_t y = uint16_t(y_.raw());
632 write<Register::VXY1, Unsafe>(x | (y << 16));
633}
634
635template <>
637 uint32_t z = uint16_t(z_.raw());
638 write<Register::VZ1, Unsafe>(z);
639}
640
641template <>
643 uint32_t x = uint16_t(x_.raw());
644 uint32_t y = uint16_t(y_.raw());
645 write<Register::VXY2, Unsafe>(x | (y << 16));
646}
647
648template <>
650 uint32_t z = uint16_t(z_.raw());
651 write<Register::VZ2, Unsafe>(z);
652}
653
654template <>
656 uint32_t z = uint16_t(z_.raw());
657 write<Register::OTZ, Unsafe>(z);
658}
659
660template <>
662 uint32_t x = uint16_t(x_.raw());
663 write<Register::IR0, Unsafe>(x);
664}
665
666template <>
668 uint32_t x = uint16_t(x_.raw());
669 write<Register::IR1, Unsafe>(x);
670}
671
672template <>
674 uint32_t x = uint16_t(x_.raw());
675 write<Register::IR2, Unsafe>(x);
676}
677
678template <>
680 uint32_t x = uint16_t(x_.raw());
681 write<Register::IR3, Unsafe>(x);
682}
683
684template <>
686 uint32_t x = uint16_t(x_.raw());
687 uint32_t y = uint16_t(y_.raw());
688 write<Register::R11R12, Unsafe>(x | (y << 16));
689}
690
691template <>
693 uint32_t x = uint16_t(x_.raw());
694 uint32_t y = uint16_t(y_.raw());
695 write<Register::R13R21, Unsafe>(x | (y << 16));
696}
697
698template <>
700 uint32_t x = uint16_t(x_.raw());
701 uint32_t y = uint16_t(y_.raw());
702 write<Register::R22R23, Unsafe>(x | (y << 16));
703}
704
705template <>
707 uint32_t x = uint16_t(x_.raw());
708 uint32_t y = uint16_t(y_.raw());
709 write<Register::R31R32, Unsafe>(x | (y << 16));
710}
711
712template <>
714 uint32_t z = uint16_t(z_.raw());
715 write<Register::R33, Unsafe>(z);
716}
717
718template <>
720 uint32_t x = uint16_t(x_.raw());
721 uint32_t y = uint16_t(y_.raw());
722 write<Register::L11L12, Unsafe>(x | (y << 16));
723}
724
725template <>
727 uint32_t x = uint16_t(x_.raw());
728 uint32_t y = uint16_t(y_.raw());
729 write<Register::L13L21, Unsafe>(x | (y << 16));
730}
731
732template <>
734 uint32_t x = uint16_t(x_.raw());
735 uint32_t y = uint16_t(y_.raw());
736 write<Register::L22L23, Unsafe>(x | (y << 16));
737}
738
739template <>
741 uint32_t x = uint16_t(x_.raw());
742 uint32_t y = uint16_t(y_.raw());
743 write<Register::L31L32, Unsafe>(x | (y << 16));
744}
745
746template <>
748 uint32_t z = uint16_t(z_.raw());
749 write<Register::L33, Unsafe>(z);
750}
751
752template <>
754 uint32_t x = uint16_t(x_.raw());
755 uint32_t y = uint16_t(y_.raw());
756 write<Register::LR1LR2, Unsafe>(x | (y << 16));
757}
758
759template <>
761 uint32_t x = uint16_t(x_.raw());
762 uint32_t y = uint16_t(y_.raw());
763 write<Register::LR3LG1, Unsafe>(x | (y << 16));
764}
765
766template <>
768 uint32_t x = uint16_t(x_.raw());
769 uint32_t y = uint16_t(y_.raw());
770 write<Register::LG2LG3, Unsafe>(x | (y << 16));
771}
772
773template <>
775 uint32_t x = uint16_t(x_.raw());
776 uint32_t y = uint16_t(y_.raw());
777 write<Register::LB1LB2, Unsafe>(x | (y << 16));
778}
779
780template <>
782 uint32_t z = uint16_t(z_.raw());
783 write<Register::LB3, Unsafe>(z);
784}
785
786template <>
788 uint32_t z = uint16_t(z_.raw());
789 write<Register::ZSF3, Unsafe>(z);
790}
791
792template <>
794 uint32_t z = uint16_t(z_.raw());
795 write<Register::ZSF4, Unsafe>(z);
796}
797
798template <>
800 writeUnsafe<Register::R11R12>(Short(in.vs[0].x), Short(in.vs[0].y));
801 writeUnsafe<Register::R13R21>(Short(in.vs[0].z), Short(in.vs[1].x));
802 writeUnsafe<Register::R22R23>(Short(in.vs[1].y), Short(in.vs[1].z));
803 writeUnsafe<Register::R31R32>(Short(in.vs[2].x), Short(in.vs[2].y));
805}
806
807template <>
809 writeUnsafe<Register::L11L12>(Short(in.vs[0].x), Short(in.vs[0].y));
810 writeUnsafe<Register::L13L21>(Short(in.vs[0].z), Short(in.vs[1].x));
811 writeUnsafe<Register::L22L23>(Short(in.vs[1].y), Short(in.vs[1].z));
812 writeUnsafe<Register::L31L32>(Short(in.vs[2].x), Short(in.vs[2].y));
814}
815
816template <>
818 writeUnsafe<Register::LR1LR2>(Short(in.vs[0].x), Short(in.vs[0].y));
819 writeUnsafe<Register::LR3LG1>(Short(in.vs[0].z), Short(in.vs[1].x));
820 writeUnsafe<Register::LG2LG3>(Short(in.vs[1].y), Short(in.vs[1].z));
821 writeUnsafe<Register::LB1LB2>(Short(in.vs[2].x), Short(in.vs[2].y));
823}
824
825template <>
830
831template <>
836
837template <>
842
843template <>
845 write<Register::TRX, Unsafe>(in.x.raw());
846 write<Register::TRY, Unsafe>(in.y.raw());
847 write<Register::TRZ, Safe>(in.z.raw());
848}
849
850template <>
852 write<Register::OFX, Unsafe>(in.x.raw());
853 write<Register::OFY, Safe>(in.y.raw());
854}
855
856template <>
864
865template <>
873
874template <>
882
883template <>
888
889template <>
894
895template <>
900
901template <>
903 write<Register::TRX, Unsafe>(in.x.raw());
904 write<Register::TRY, Unsafe>(in.y.raw());
905 write<Register::TRZ, Unsafe>(in.z.raw());
906}
907
908template <>
910 write<Register::OFX, Unsafe>(in.x.raw());
911 write<Register::OFY, Unsafe>(in.y.raw());
912}
913
914template <>
916 return PackedVec3(Short(readRaw<Register::IR1, Safe>(), Short::RAW),
917 Short(readRaw<Register::IR2, Safe>(), Short::RAW),
918 Short(readRaw<Register::IR3, Safe>(), Short::RAW));
919}
920
921template <>
923 return PackedVec3(Short(readRaw<Register::MAC1, Safe>(), Short::RAW),
924 Short(readRaw<Register::MAC2, Safe>(), Short::RAW),
925 Short(readRaw<Register::MAC3, Safe>(), Short::RAW));
926}
927
928template <>
930 return PackedVec3(Short(readRaw<Register::IR1, Unsafe>(), Short::RAW),
931 Short(readRaw<Register::IR2, Unsafe>(), Short::RAW),
932 Short(readRaw<Register::IR3, Unsafe>(), Short::RAW));
933}
934
935template <>
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));
940}
941
942template <>
943[[deprecated("Use the reference version instead")]] inline void read<PseudoRegister::LV>(Vec3* ptr) {
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));
947}
948
949template <>
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));
954}
955
956} // namespace GTE
957
958} // 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: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
Definition matrix.hh:33
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
__builtin_unreachable()
static int ret
Definition syscalls.h:72
void uint32_t(classId, spec)