1 // Copyright 2008 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 // Gekko related unions, structs, ...
6 
7 #pragma once
8 
9 #include "Common/BitField.h"
10 #include "Common/CommonTypes.h"
11 
12 // --- Gekko Instruction ---
13 
14 union UGeckoInstruction
15 {
16   u32 hex = 0;
17 
18   UGeckoInstruction() = default;
UGeckoInstruction(u32 hex_)19   UGeckoInstruction(u32 hex_) : hex(hex_) {}
20   struct
21   {
22     // Record bit
23     // 1, if the condition register should be updated by this instruction
24     u32 Rc : 1;
25     u32 SUBOP10 : 10;
26     // Source GPR
27     u32 RB : 5;
28     // Source or destination GPR
29     u32 RA : 5;
30     // Destination GPR
31     u32 RD : 5;
32     // Primary opcode
33     u32 OPCD : 6;
34   };
35   struct
36   {
37     // Immediate, signed 16-bit
38     signed SIMM_16 : 16;
39     u32 : 5;
40     // Conditions on which to trap
41     u32 TO : 5;
42     u32 OPCD_2 : 6;
43   };
44   struct
45   {
46     u32 Rc_2 : 1;
47     u32 : 10;
48     u32 : 5;
49     u32 : 5;
50     // Source GPR
51     u32 RS : 5;
52     u32 OPCD_3 : 6;
53   };
54   struct
55   {
56     // Immediate, unsigned 16-bit
57     u32 UIMM : 16;
58     u32 : 5;
59     u32 : 5;
60     u32 OPCD_4 : 6;
61   };
62   struct
63   {
64     // Link bit
65     // 1, if branch instructions should put the address of the next instruction into the link
66     // register
67     u32 LK : 1;
68     // Absolute address bit
69     // 1, if the immediate field represents an absolute address
70     u32 AA : 1;
71     // Immediate, signed 24-bit
72     u32 LI : 24;
73     u32 OPCD_5 : 6;
74   };
75   struct
76   {
77     u32 LK_2 : 1;
78     u32 AA_2 : 1;
79     // Branch displacement, signed 14-bit (right-extended by 0b00)
80     u32 BD : 14;
81     // Branch condition
82     u32 BI : 5;
83     // Conditional branch control
84     u32 BO : 5;
85     u32 OPCD_6 : 6;
86   };
87   struct
88   {
89     u32 LK_3 : 1;
90     u32 : 10;
91     u32 : 5;
92     u32 BI_2 : 5;
93     u32 BO_2 : 5;
94     u32 OPCD_7 : 6;
95   };
96   struct
97   {
98     u32 : 11;
99     u32 RB_2 : 5;
100     u32 RA_2 : 5;
101     // ?
102     u32 L : 1;
103     u32 : 1;
104     // Destination field in CR or FPSCR
105     u32 CRFD : 3;
106     u32 OPCD_8 : 6;
107   };
108   struct
109   {
110     signed SIMM_16_2 : 16;
111     u32 RA_3 : 5;
112     u32 L_2 : 1;
113     u32 : 1;
114     u32 CRFD_2 : 3;
115     u32 OPCD_9 : 6;
116   };
117   struct
118   {
119     u32 UIMM_2 : 16;
120     u32 RA_4 : 5;
121     u32 L_3 : 1;
122     u32 : 1;
123     u32 CRFD_3 : 3;
124     u32 OPCD_A : 6;
125   };
126   struct
127   {
128     u32 : 1;
129     u32 SUBOP10_2 : 10;
130     u32 RB_5 : 5;
131     u32 RA_5 : 5;
132     u32 L_4 : 1;
133     u32 : 1;
134     u32 CRFD_4 : 3;
135     u32 OPCD_B : 6;
136   };
137   struct
138   {
139     u32 : 16;
140     // Segment register
141     u32 SR : 4;
142     u32 : 1;
143     u32 RS_2 : 5;
144     u32 OPCD_C : 6;
145   };
146 
147   // Table 59
148   struct
149   {
150     u32 Rc_4 : 1;
151     u32 SUBOP5 : 5;
152     // ?
153     u32 RC : 5;
154     u32 : 5;
155     u32 RA_6 : 5;
156     u32 RD_2 : 5;
157     u32 OPCD_D : 6;
158   };
159 
160   struct
161   {
162     u32 : 10;
163     // Overflow enable
164     u32 OE : 1;
165     // Special-purpose register
166     u32 SPR : 10;
167     u32 : 11;
168   };
169   struct
170   {
171     u32 : 10;
172     u32 OE_3 : 1;
173     // Upper special-purpose register
174     u32 SPRU : 5;
175     // Lower special-purpose register
176     u32 SPRL : 5;
177     u32 : 11;
178   };
179 
180   // rlwinmx
181   struct
182   {
183     u32 Rc_3 : 1;
184     // Mask end
185     u32 ME : 5;
186     // Mask begin
187     u32 MB : 5;
188     // Shift amount
189     u32 SH : 5;
190     u32 : 16;
191   };
192 
193   // crxor
194   struct
195   {
196     u32 : 11;
197     // Source bit in the CR
198     u32 CRBB : 5;
199     // Source bit in the CR
200     u32 CRBA : 5;
201     // Destination bit in the CR
202     u32 CRBD : 5;
203     u32 : 6;
204   };
205 
206   // mftb
207   struct
208   {
209     u32 : 11;
210     // Time base register
211     u32 TBR : 10;
212     u32 : 11;
213   };
214 
215   struct
216   {
217     u32 : 11;
218     // Upper time base register
219     u32 TBRU : 5;
220     // Lower time base register
221     u32 TBRL : 5;
222     u32 : 11;
223   };
224 
225   struct
226   {
227     u32 : 18;
228     // Source field in the CR or FPSCR
229     u32 CRFS : 3;
230     u32 : 2;
231     u32 CRFD_5 : 3;
232     u32 : 6;
233   };
234 
235   struct
236   {
237     u32 : 12;
238     // Field mask, identifies the CR fields to be updated by mtcrf
239     u32 CRM : 8;
240     u32 : 1;
241     // Destination FPR
242     u32 FD : 5;
243     u32 : 6;
244   };
245   struct
246   {
247     u32 : 6;
248     // Source FPR
249     u32 FC : 5;
250     // Source FPR
251     u32 FB : 5;
252     // Source FPR
253     u32 FA : 5;
254     // Source FPR
255     u32 FS : 5;
256     u32 : 6;
257   };
258   struct
259   {
260     u32 : 17;
261     // Field mask, identifies the FPSCR fields to be updated by mtfsf
262     u32 FM : 8;
263     u32 : 7;
264   };
265 
266   // paired single quantized load/store
267   struct
268   {
269     u32 : 1;
270     u32 SUBOP6 : 6;
271     // Graphics quantization register to use
272     u32 Ix : 3;
273     // 0: paired single, 1: scalar
274     u32 Wx : 1;
275     u32 : 1;
276     // Graphics quantization register to use
277     u32 I : 3;
278     // 0: paired single, 1: scalar
279     u32 W : 1;
280     u32 : 16;
281   };
282 
283   struct
284   {
285     signed SIMM_12 : 12;
286     u32 : 20;
287   };
288 
289   struct
290   {
291     u32 : 11;
292     // Number of bytes to use in lswi/stswi (0 means 32 bytes)
293     u32 NB : 5;
294   };
295 };
296 
297 // Used in implementations of rlwimi, rlwinm, and rlwnm
MakeRotationMask(u32 mb,u32 me)298 inline u32 MakeRotationMask(u32 mb, u32 me)
299 {
300   // first make 001111111111111 part
301   const u32 begin = 0xFFFFFFFF >> mb;
302   // then make 000000000001111 part, which is used to flip the bits of the first one
303   const u32 end = 0x7FFFFFFF >> me;
304   // do the bitflip
305   const u32 mask = begin ^ end;
306 
307   // and invert if backwards
308   if (me < mb)
309     return ~mask;
310 
311   return mask;
312 }
313 
314 //
315 // --- Gekko Special Registers ---
316 //
317 
318 // quantize types
319 enum EQuantizeType : u32
320 {
321   QUANTIZE_FLOAT = 0,
322   QUANTIZE_INVALID1 = 1,
323   QUANTIZE_INVALID2 = 2,
324   QUANTIZE_INVALID3 = 3,
325   QUANTIZE_U8 = 4,
326   QUANTIZE_U16 = 5,
327   QUANTIZE_S8 = 6,
328   QUANTIZE_S16 = 7,
329 };
330 
331 // GQR Register
332 union UGQR
333 {
334   BitField<0, 3, EQuantizeType> st_type;
335   BitField<8, 6, u32> st_scale;
336   BitField<16, 3, EQuantizeType> ld_type;
337   BitField<24, 6, u32> ld_scale;
338 
339   u32 Hex = 0;
340 
341   UGQR() = default;
UGQR(u32 hex_)342   explicit UGQR(u32 hex_) : Hex{hex_} {}
343 };
344 
345 #define XER_CA_SHIFT 29
346 #define XER_OV_SHIFT 30
347 #define XER_SO_SHIFT 31
348 #define XER_OV_MASK 1
349 #define XER_SO_MASK 2
350 // XER
351 union UReg_XER
352 {
353   struct
354   {
355     u32 BYTE_COUNT : 7;
356     u32 : 1;
357     u32 BYTE_CMP : 8;
358     u32 : 13;
359     u32 CA : 1;
360     u32 OV : 1;
361     u32 SO : 1;
362   };
363   u32 Hex = 0;
364 
365   UReg_XER() = default;
UReg_XER(u32 hex_)366   explicit UReg_XER(u32 hex_) : Hex{hex_} {}
367 };
368 
369 // Machine State Register
370 union UReg_MSR
371 {
372   struct
373   {
374     u32 LE : 1;
375     u32 RI : 1;
376     u32 PM : 1;
377     u32 : 1;  // res28
378     u32 DR : 1;
379     u32 IR : 1;
380     u32 IP : 1;
381     u32 : 1;  // res24
382     u32 FE1 : 1;
383     u32 BE : 1;
384     u32 SE : 1;
385     u32 FE0 : 1;
386     u32 MCHECK : 1;
387     u32 FP : 1;
388     u32 PR : 1;
389     u32 EE : 1;
390     u32 ILE : 1;
391     u32 : 1;  // res14
392     u32 POW : 1;
393     u32 res : 13;
394   };
395   u32 Hex = 0;
396 
397   UReg_MSR() = default;
UReg_MSR(u32 hex_)398   explicit UReg_MSR(u32 hex_) : Hex{hex_} {}
399 };
400 
401 #define FPRF_SHIFT 12
402 #define FPRF_MASK (0x1F << FPRF_SHIFT)
403 
404 // FPSCR exception flags
405 enum FPSCRExceptionFlag : u32
406 {
407   FPSCR_FX = 1U << (31 - 0),
408   FPSCR_FEX = 1U << (31 - 1),
409   FPSCR_VX = 1U << (31 - 2),
410   FPSCR_OX = 1U << (31 - 3),
411   FPSCR_UX = 1U << (31 - 4),
412   FPSCR_ZX = 1U << (31 - 5),
413   FPSCR_XX = 1U << (31 - 6),
414   FPSCR_VXSNAN = 1U << (31 - 7),
415   FPSCR_VXISI = 1U << (31 - 8),
416   FPSCR_VXIDI = 1U << (31 - 9),
417   FPSCR_VXZDZ = 1U << (31 - 10),
418   FPSCR_VXIMZ = 1U << (31 - 11),
419   FPSCR_VXVC = 1U << (31 - 12),
420   FPSCR_VXSOFT = 1U << (31 - 21),
421   FPSCR_VXSQRT = 1U << (31 - 22),
422   FPSCR_VXCVI = 1U << (31 - 23),
423   FPSCR_VE = 1U << (31 - 24),
424 
425   FPSCR_VX_ANY = FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI | FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
426                  FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI,
427 
428   FPSCR_ANY_X = FPSCR_OX | FPSCR_UX | FPSCR_ZX | FPSCR_XX | FPSCR_VX_ANY,
429 };
430 
431 // Floating Point Status and Control Register
432 union UReg_FPSCR
433 {
434   struct
435   {
436     // Rounding mode (towards: nearest, zero, +inf, -inf)
437     u32 RN : 2;
438     // Non-IEEE mode enable (aka flush-to-zero)
439     u32 NI : 1;
440     // Inexact exception enable
441     u32 XE : 1;
442     // IEEE division by zero exception enable
443     u32 ZE : 1;
444     // IEEE underflow exception enable
445     u32 UE : 1;
446     // IEEE overflow exception enable
447     u32 OE : 1;
448     // Invalid operation exception enable
449     u32 VE : 1;
450     // Invalid operation exception for integer conversion (sticky)
451     u32 VXCVI : 1;
452     // Invalid operation exception for square root (sticky)
453     u32 VXSQRT : 1;
454     // Invalid operation exception for software request (sticky)
455     u32 VXSOFT : 1;
456     // reserved
457     u32 : 1;
458     // Floating point result flags (includes FPCC) (not sticky)
459     // from more to less significand: class, <, >, =, ?
460     u32 FPRF : 5;
461     // Fraction inexact (not sticky)
462     u32 FI : 1;
463     // Fraction rounded (not sticky)
464     u32 FR : 1;
465     // Invalid operation exception for invalid comparison (sticky)
466     u32 VXVC : 1;
467     // Invalid operation exception for inf * 0 (sticky)
468     u32 VXIMZ : 1;
469     // Invalid operation exception for 0 / 0 (sticky)
470     u32 VXZDZ : 1;
471     // Invalid operation exception for inf / inf (sticky)
472     u32 VXIDI : 1;
473     // Invalid operation exception for inf - inf (sticky)
474     u32 VXISI : 1;
475     // Invalid operation exception for SNaN (sticky)
476     u32 VXSNAN : 1;
477     // Inexact exception (sticky)
478     u32 XX : 1;
479     // Division by zero exception (sticky)
480     u32 ZX : 1;
481     // Underflow exception (sticky)
482     u32 UX : 1;
483     // Overflow exception (sticky)
484     u32 OX : 1;
485     // Invalid operation exception summary (not sticky)
486     u32 VX : 1;
487     // Enabled exception summary (not sticky)
488     u32 FEX : 1;
489     // Exception summary (sticky)
490     u32 FX : 1;
491   };
492   u32 Hex = 0;
493 
494   // The FPSCR's 20th bit (11th from a little endian perspective)
495   // is defined as reserved and set to zero. Attempts to modify it
496   // are ignored by hardware, so we do the same.
497   static constexpr u32 mask = 0xFFFFF7FF;
498 
499   UReg_FPSCR() = default;
UReg_FPSCR(u32 hex_)500   explicit UReg_FPSCR(u32 hex_) : Hex{hex_ & mask} {}
501 
502   UReg_FPSCR& operator=(u32 value)
503   {
504     Hex = value & mask;
505     return *this;
506   }
507 
508   UReg_FPSCR& operator|=(u32 value)
509   {
510     Hex |= value & mask;
511     return *this;
512   }
513 
514   UReg_FPSCR& operator&=(u32 value)
515   {
516     Hex &= value;
517     return *this;
518   }
519 
520   UReg_FPSCR& operator^=(u32 value)
521   {
522     Hex ^= value & mask;
523     return *this;
524   }
525 
ClearFIFR()526   void ClearFIFR()
527   {
528     FI = 0;
529     FR = 0;
530   }
531 };
532 
533 // Hardware Implementation-Dependent Register 0
534 union UReg_HID0
535 {
536   struct
537   {
538     u32 NOOPTI : 1;
539     u32 : 1;
540     u32 BHT : 1;
541     u32 ABE : 1;
542     u32 : 1;
543     u32 BTIC : 1;
544     u32 DCFA : 1;
545     u32 SGE : 1;
546     u32 IFEM : 1;
547     u32 SPD : 1;
548     u32 DCFI : 1;
549     u32 ICFI : 1;
550     u32 DLOCK : 1;
551     u32 ILOCK : 1;
552     u32 DCE : 1;
553     u32 ICE : 1;
554     u32 NHR : 1;
555     u32 : 3;
556     u32 DPM : 1;
557     u32 SLEEP : 1;
558     u32 NAP : 1;
559     u32 DOZE : 1;
560     u32 PAR : 1;
561     u32 ECLK : 1;
562     u32 : 1;
563     u32 BCLK : 1;
564     u32 EBD : 1;
565     u32 EBA : 1;
566     u32 DBP : 1;
567     u32 EMCP : 1;
568   };
569   u32 Hex = 0;
570 };
571 
572 // Hardware Implementation-Dependent Register 2
573 union UReg_HID2
574 {
575   struct
576   {
577     u32 : 16;
578     u32 DQOEE : 1;
579     u32 DCMEE : 1;
580     u32 DNCEE : 1;
581     u32 DCHEE : 1;
582     u32 DQOERR : 1;
583     u32 DCMERR : 1;
584     u32 DNCERR : 1;
585     u32 DCHERR : 1;
586     u32 DMAQL : 4;
587     u32 LCE : 1;
588     u32 PSE : 1;
589     u32 WPE : 1;
590     u32 LSQE : 1;
591   };
592   u32 Hex = 0;
593 
594   UReg_HID2() = default;
UReg_HID2(u32 hex_)595   explicit UReg_HID2(u32 hex_) : Hex{hex_} {}
596 };
597 
598 // Hardware Implementation-Dependent Register 4
599 union UReg_HID4
600 {
601   struct
602   {
603     u32 : 20;
604     u32 L2CFI : 1;
605     u32 L2MUM : 1;
606     u32 DBP : 1;
607     u32 LPE : 1;
608     u32 ST0 : 1;
609     u32 SBE : 1;
610     u32 : 1;
611     u32 BPD : 2;
612     u32 L2FM : 2;
613     u32 : 1;
614   };
615   u32 Hex = 0;
616 
617   UReg_HID4() = default;
UReg_HID4(u32 hex_)618   explicit UReg_HID4(u32 hex_) : Hex{hex_} {}
619 };
620 
621 // SPR1 - Page Table format
622 union UReg_SPR1
623 {
624   u32 Hex;
625   struct
626   {
627     u32 htaborg : 16;
628     u32 : 7;
629     u32 htabmask : 9;
630   };
631 };
632 
633 // MMCR0 - Monitor Mode Control Register 0 format
634 union UReg_MMCR0
635 {
636   u32 Hex;
637   struct
638   {
639     u32 PMC2SELECT : 6;
640     u32 PMC1SELECT : 7;
641     u32 PMCTRIGGER : 1;
642     u32 PMCINTCONTROL : 1;
643     u32 PMC1INTCONTROL : 1;
644     u32 THRESHOLD : 6;
645     u32 INTONBITTRANS : 1;
646     u32 RTCSELECT : 2;
647     u32 DISCOUNT : 1;
648     u32 ENINT : 1;
649     u32 DMR : 1;
650     u32 DMS : 1;
651     u32 DU : 1;
652     u32 DP : 1;
653     u32 DIS : 1;
654   };
655 };
656 
657 // MMCR1 - Monitor Mode Control Register 1 format
658 union UReg_MMCR1
659 {
660   u32 Hex;
661   struct
662   {
663     u32 : 22;
664     u32 PMC4SELECT : 5;
665     u32 PMC3SELECT : 5;
666   };
667 };
668 
669 // Write Pipe Address Register
670 union UReg_WPAR
671 {
672   struct
673   {
674     u32 BNE : 1;
675     u32 : 4;
676     u32 GB_ADDR : 27;
677   };
678   u32 Hex = 0;
679 
680   UReg_WPAR() = default;
UReg_WPAR(u32 hex_)681   explicit UReg_WPAR(u32 hex_) : Hex{hex_} {}
682 };
683 
684 // Direct Memory Access Upper register
685 union UReg_DMAU
686 {
687   struct
688   {
689     u32 DMA_LEN_U : 5;
690     u32 MEM_ADDR : 27;
691   };
692   u32 Hex = 0;
693 
694   UReg_DMAU() = default;
UReg_DMAU(u32 hex_)695   explicit UReg_DMAU(u32 hex_) : Hex{hex_} {}
696 };
697 
698 // Direct Memory Access Lower (DMAL) register
699 union UReg_DMAL
700 {
701   struct
702   {
703     u32 DMA_F : 1;
704     u32 DMA_T : 1;
705     u32 DMA_LEN_L : 2;
706     u32 DMA_LD : 1;
707     u32 LC_ADDR : 27;
708   };
709   u32 Hex = 0;
710 
711   UReg_DMAL() = default;
UReg_DMAL(u32 hex_)712   explicit UReg_DMAL(u32 hex_) : Hex{hex_} {}
713 };
714 
715 union UReg_BAT_Up
716 {
717   struct
718   {
719     u32 VP : 1;
720     u32 VS : 1;
721     u32 BL : 11;  // Block length (aka block size mask)
722     u32 : 4;
723     u32 BEPI : 15;
724   };
725   u32 Hex = 0;
726 
727   UReg_BAT_Up() = default;
UReg_BAT_Up(u32 hex_)728   explicit UReg_BAT_Up(u32 hex_) : Hex{hex_} {}
729 };
730 
731 union UReg_BAT_Lo
732 {
733   struct
734   {
735     u32 PP : 2;
736     u32 : 1;
737     u32 WIMG : 4;
738     u32 : 10;
739     u32 BRPN : 15;  // Physical Block Number
740   };
741   u32 Hex = 0;
742 
743   UReg_BAT_Lo() = default;
UReg_BAT_Lo(u32 hex_)744   explicit UReg_BAT_Lo(u32 hex_) : Hex{hex_} {}
745 };
746 
747 union UReg_THRM12
748 {
749   struct
750   {
751     u32 V : 1;    // Valid
752     u32 TIE : 1;  // Thermal Interrupt Enable
753     u32 TID : 1;  // Thermal Interrupt Direction
754     u32 : 20;
755     u32 THRESHOLD : 7;  // Temperature Threshold, 0-127°C
756     u32 TIV : 1;        // Thermal Interrupt Valid
757     u32 TIN : 1;        // Thermal Interrupt
758   };
759   u32 Hex = 0;
760 
761   UReg_THRM12() = default;
UReg_THRM12(u32 hex_)762   explicit UReg_THRM12(u32 hex_) : Hex{hex_} {}
763 };
764 
765 union UReg_THRM3
766 {
767   struct
768   {
769     u32 E : 1;      // Enable
770     u32 SITV : 13;  // Sample Interval Timer Value
771     u32 : 18;
772   };
773   u32 Hex = 0;
774 
775   UReg_THRM3() = default;
UReg_THRM3(u32 hex_)776   explicit UReg_THRM3(u32 hex_) : Hex{hex_} {}
777 };
778 
779 union UReg_PTE
780 {
781   struct
782   {
783     u64 API : 6;
784     u64 H : 1;
785     u64 VSID : 24;
786     u64 V : 1;
787     u64 PP : 2;
788     u64 : 1;
789     u64 WIMG : 4;
790     u64 C : 1;
791     u64 R : 1;
792     u64 : 3;
793     u64 RPN : 20;
794   };
795 
796   u64 Hex = 0;
797   u32 Hex32[2];
798 };
799 
800 //
801 // --- Gekko Types and Defs ---
802 //
803 
804 // branches
805 enum
806 {
807   BO_BRANCH_IF_CTR_0 = 2,        // 3
808   BO_DONT_DECREMENT_FLAG = 4,    // 2
809   BO_BRANCH_IF_TRUE = 8,         // 1
810   BO_DONT_CHECK_CONDITION = 16,  // 0
811 };
812 
813 // Special purpose register indices
814 enum
815 {
816   SPR_XER = 1,
817   SPR_LR = 8,
818   SPR_CTR = 9,
819   SPR_DSISR = 18,
820   SPR_DAR = 19,
821   SPR_DEC = 22,
822   SPR_SDR = 25,
823   SPR_SRR0 = 26,
824   SPR_SRR1 = 27,
825   SPR_TL = 268,
826   SPR_TU = 269,
827   SPR_TL_W = 284,
828   SPR_TU_W = 285,
829   SPR_PVR = 287,
830   SPR_SPRG0 = 272,
831   SPR_SPRG1 = 273,
832   SPR_SPRG2 = 274,
833   SPR_SPRG3 = 275,
834   SPR_EAR = 282,
835   SPR_IBAT0U = 528,
836   SPR_IBAT0L = 529,
837   SPR_IBAT1U = 530,
838   SPR_IBAT1L = 531,
839   SPR_IBAT2U = 532,
840   SPR_IBAT2L = 533,
841   SPR_IBAT3U = 534,
842   SPR_IBAT3L = 535,
843   SPR_DBAT0U = 536,
844   SPR_DBAT0L = 537,
845   SPR_DBAT1U = 538,
846   SPR_DBAT1L = 539,
847   SPR_DBAT2U = 540,
848   SPR_DBAT2L = 541,
849   SPR_DBAT3U = 542,
850   SPR_DBAT3L = 543,
851   SPR_IBAT4U = 560,
852   SPR_IBAT4L = 561,
853   SPR_IBAT5U = 562,
854   SPR_IBAT5L = 563,
855   SPR_IBAT6U = 564,
856   SPR_IBAT6L = 565,
857   SPR_IBAT7U = 566,
858   SPR_IBAT7L = 567,
859   SPR_DBAT4U = 568,
860   SPR_DBAT4L = 569,
861   SPR_DBAT5U = 570,
862   SPR_DBAT5L = 571,
863   SPR_DBAT6U = 572,
864   SPR_DBAT6L = 573,
865   SPR_DBAT7U = 574,
866   SPR_DBAT7L = 575,
867   SPR_GQR0 = 912,
868   SPR_HID0 = 1008,
869   SPR_HID1 = 1009,
870   SPR_HID2 = 920,
871   SPR_HID4 = 1011,
872   SPR_WPAR = 921,
873   SPR_DMAU = 922,
874   SPR_DMAL = 923,
875   SPR_ECID_U = 924,
876   SPR_ECID_M = 925,
877   SPR_ECID_L = 926,
878   SPR_L2CR = 1017,
879 
880   SPR_UMMCR0 = 936,
881   SPR_MMCR0 = 952,
882   SPR_PMC1 = 953,
883   SPR_PMC2 = 954,
884 
885   SPR_UMMCR1 = 940,
886   SPR_MMCR1 = 956,
887   SPR_PMC3 = 957,
888   SPR_PMC4 = 958,
889 
890   SPR_THRM1 = 1020,
891   SPR_THRM2 = 1021,
892   SPR_THRM3 = 1022,
893 };
894 
895 // Exceptions
896 enum
897 {
898   EXCEPTION_DECREMENTER = 0x00000001,
899   EXCEPTION_SYSCALL = 0x00000002,
900   EXCEPTION_EXTERNAL_INT = 0x00000004,
901   EXCEPTION_DSI = 0x00000008,
902   EXCEPTION_ISI = 0x00000010,
903   EXCEPTION_ALIGNMENT = 0x00000020,
904   EXCEPTION_FPU_UNAVAILABLE = 0x00000040,
905   EXCEPTION_PROGRAM = 0x00000080,
906   EXCEPTION_PERFORMANCE_MONITOR = 0x00000100,
907 
908   EXCEPTION_FAKE_MEMCHECK_HIT = 0x00000200,
909 };
910 
SignExt16(s16 x)911 constexpr s32 SignExt16(s16 x)
912 {
913   return (s32)x;
914 }
SignExt26(u32 x)915 constexpr s32 SignExt26(u32 x)
916 {
917   return x & 0x2000000 ? (s32)(x | 0xFC000000) : (s32)(x);
918 }
919