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