psxinterpreter: tons of new exceptions
[pcsx_rearmed.git] / libpcsxcore / psxinterpreter.c
1 /***************************************************************************
2  *   Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team              *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA.           *
18  ***************************************************************************/
19
20 /*
21  * PSX assembly interpreter.
22  */
23
24 #include "psxcommon.h"
25 #include "r3000a.h"
26 #include "gte.h"
27 #include "psxhle.h"
28 #include "psxinterpreter.h"
29 #include <stddef.h>
30 #include <assert.h>
31 #include "../include/compiler_features.h"
32
33 // these may cause issues: because of poor timing we may step
34 // on instructions that real hardware would never reach
35 #define DO_EXCEPTION_RESERVEDI
36 #define DO_EXCEPTION_ADDR_ERR
37
38 static int branch = 0;
39 static int branch2 = 0;
40 static u32 branchPC;
41
42 #ifdef __i386__
43 #define INT_ATTR __attribute__((regparm(2)))
44 #else
45 #define INT_ATTR
46 #endif
47 #ifndef INVALID_PTR
48 #define INVALID_PTR NULL
49 #endif
50
51 // Subsets
52 static void (INT_ATTR *psxBSC[64])(psxRegisters *regs_, u32 code);
53 static void (INT_ATTR *psxSPC[64])(psxRegisters *regs_, u32 code);
54
55 // get an opcode without triggering exceptions or affecting cache
56 u32 intFakeFetch(u32 pc)
57 {
58         u8 *base = psxMemRLUT[pc >> 16];
59         u32 *code;
60         if (unlikely(base == INVALID_PTR))
61                 return 0; // nop
62         code = (u32 *)(base + (pc & 0xfffc));
63         return SWAP32(*code);
64
65 }
66
67 static u32 INT_ATTR fetchNoCache(psxRegisters *regs, u8 **memRLUT, u32 pc)
68 {
69         u8 *base = memRLUT[pc >> 16];
70         u32 *code;
71         if (unlikely(base == INVALID_PTR)) {
72                 SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
73                 regs->pc = pc;
74                 psxException(R3000E_IBE << 2, branch, &regs->CP0);
75                 return 0; // execute as nop
76         }
77         code = (u32 *)(base + (pc & 0xfffc));
78         return SWAP32(*code);
79 }
80
81 /*
82 Formula One 2001 :
83 Use old CPU cache code when the RAM location is updated with new code (affects in-game racing)
84 */
85 static struct cache_entry {
86         u32 tag;
87         u32 data[4];
88 } ICache[256];
89
90 static u32 INT_ATTR fetchICache(psxRegisters *regs, u8 **memRLUT, u32 pc)
91 {
92         // cached?
93         if (pc < 0xa0000000)
94         {
95                 // this is not how the hardware works but whatever
96                 struct cache_entry *entry = &ICache[(pc & 0xff0) >> 4];
97
98                 if (((entry->tag ^ pc) & 0xfffffff0) != 0 || pc < entry->tag)
99                 {
100                         const u8 *base = memRLUT[pc >> 16];
101                         const u32 *code;
102                         if (unlikely(base == INVALID_PTR)) {
103                                 SysPrintf("game crash @%08x, ra=%08x\n", pc, regs->GPR.n.ra);
104                                 regs->pc = pc;
105                                 psxException(R3000E_IBE << 2, branch, &regs->CP0);
106                                 return 0; // execute as nop
107                         }
108                         code = (u32 *)(base + (pc & 0xfff0));
109
110                         entry->tag = pc;
111                         // treat as 4 words, although other configurations are said to be possible
112                         switch (pc & 0x0c)
113                         {
114                                 case 0x00: entry->data[0] = SWAP32(code[0]);
115                                 case 0x04: entry->data[1] = SWAP32(code[1]);
116                                 case 0x08: entry->data[2] = SWAP32(code[2]);
117                                 case 0x0c: entry->data[3] = SWAP32(code[3]);
118                         }
119                 }
120                 return entry->data[(pc & 0x0f) >> 2];
121         }
122
123         return fetchNoCache(regs, memRLUT, pc);
124 }
125
126 static u32 (INT_ATTR *fetch)(psxRegisters *regs_, u8 **memRLUT, u32 pc) = fetchNoCache;
127
128 // Make the timing events trigger faster as we are currently assuming everything
129 // takes one cycle, which is not the case on real hardware.
130 // FIXME: count cache misses, memory latencies, stalls to get rid of this
131 static inline void addCycle(void)
132 {
133         assert(psxRegs.subCycleStep >= 0x10000);
134         psxRegs.subCycle += psxRegs.subCycleStep;
135         psxRegs.cycle += psxRegs.subCycle >> 16;
136         psxRegs.subCycle &= 0xffff;
137 }
138
139 static void delayRead(int reg, u32 bpc) {
140         u32 rold, rnew;
141
142 //      SysPrintf("delayRead at %x!\n", psxRegs.pc);
143
144         rold = psxRegs.GPR.r[reg];
145         psxBSC[psxRegs.code >> 26](&psxRegs, psxRegs.code); // branch delay load
146         rnew = psxRegs.GPR.r[reg];
147
148         psxRegs.pc = bpc;
149
150         branch = 0;
151
152         psxRegs.GPR.r[reg] = rold;
153         execI(); // first branch opcode
154         psxRegs.GPR.r[reg] = rnew;
155
156         psxBranchTest();
157 }
158
159 static void delayWrite(int reg, u32 bpc) {
160
161 /*      SysPrintf("delayWrite at %x!\n", psxRegs.pc);
162
163         SysPrintf("%s\n", disR3000AF(psxRegs.code, psxRegs.pc-4));
164         SysPrintf("%s\n", disR3000AF(PSXMu32(bpc), bpc));*/
165
166         // no changes from normal behavior
167
168         psxBSC[psxRegs.code >> 26](&psxRegs, psxRegs.code);
169
170         branch = 0;
171         psxRegs.pc = bpc;
172
173         psxBranchTest();
174 }
175
176 static void delayReadWrite(int reg, u32 bpc) {
177
178 //      SysPrintf("delayReadWrite at %x!\n", psxRegs.pc);
179
180         // the branch delay load is skipped
181
182         branch = 0;
183         psxRegs.pc = bpc;
184
185         psxBranchTest();
186 }
187
188 /**** R3000A Instruction Macros ****/
189 #define _PC_            regs_->pc       // The next PC to be executed
190
191 #define _fOp_(code)     ((code >> 26)       )  // The opcode part of the instruction register
192 #define _fFunct_(code)  ((code      ) & 0x3F)  // The funct part of the instruction register
193 #define _fRd_(code)     ((code >> 11) & 0x1F)  // The rd part of the instruction register
194 #define _fRt_(code)     ((code >> 16) & 0x1F)  // The rt part of the instruction register
195 #define _fRs_(code)     ((code >> 21) & 0x1F)  // The rs part of the instruction register
196 #define _fSa_(code)     ((code >>  6) & 0x1F)  // The sa part of the instruction register
197 #define _fIm_(code)     ((u16)code)            // The immediate part of the instruction register
198 #define _fTarget_(code) (code & 0x03ffffff)    // The target part of the instruction register
199
200 #define _fImm_(code)    ((s16)code)            // sign-extended immediate
201 #define _fImmU_(code)   (code&0xffff)          // zero-extended immediate
202
203 #define _Op_     _fOp_(code)
204 #define _Funct_  _fFunct_(code)
205 #define _Rd_     _fRd_(code)
206 #define _Rt_     _fRt_(code)
207 #define _Rs_     _fRs_(code)
208 #define _Sa_     _fSa_(code)
209 #define _Im_     _fIm_(code)
210 #define _Target_ _fTarget_(code)
211
212 #define _Imm_    _fImm_(code)
213 #define _ImmU_   _fImmU_(code)
214
215 #define _rRs_   regs_->GPR.r[_Rs_]   // Rs register
216 #define _rRt_   regs_->GPR.r[_Rt_]   // Rt register
217 #define _rRd_   regs_->GPR.r[_Rd_]   // Rd register
218 #define _rSa_   regs_->GPR.r[_Sa_]   // Sa register
219 #define _rFs_   regs_->CP0.r[_Rd_]   // Fs register
220
221 #define _rHi_   regs_->GPR.n.hi   // The HI register
222 #define _rLo_   regs_->GPR.n.lo   // The LO register
223
224 #define _JumpTarget_    ((_Target_ * 4) + (_PC_ & 0xf0000000))   // Calculates the target during a jump instruction
225 #define _BranchTarget_  ((s16)_Im_ * 4 + _PC_)                 // Calculates the target during a branch instruction
226
227 #define _SetLink(x)     regs_->GPR.r[x] = _PC_ + 4;       // Sets the return address in the link register
228
229 #define OP(name) \
230         static inline INT_ATTR void name(psxRegisters *regs_, u32 code)
231
232 // this defines shall be used with the tmp 
233 // of the next func (instead of _Funct_...)
234 #define _tFunct_  ((tmp      ) & 0x3F)  // The funct part of the instruction register 
235 #define _tRd_     ((tmp >> 11) & 0x1F)  // The rd part of the instruction register 
236 #define _tRt_     ((tmp >> 16) & 0x1F)  // The rt part of the instruction register 
237 #define _tRs_     ((tmp >> 21) & 0x1F)  // The rs part of the instruction register 
238 #define _tSa_     ((tmp >>  6) & 0x1F)  // The sa part of the instruction register
239
240 #define _i32(x) (s32)(x)
241 #define _u32(x) (u32)(x)
242
243 static int psxTestLoadDelay(int reg, u32 tmp) {
244         if (tmp == 0) return 0; // NOP
245         switch (tmp >> 26) {
246                 case 0x00: // SPECIAL
247                         switch (_tFunct_) {
248                                 case 0x00: // SLL
249                                 case 0x02: case 0x03: // SRL/SRA
250                                         if (_tRd_ == reg && _tRt_ == reg) return 1; else
251                                         if (_tRt_ == reg) return 2; else
252                                         if (_tRd_ == reg) return 3;
253                                         break;
254
255                                 case 0x08: // JR
256                                         if (_tRs_ == reg) return 2;
257                                         break;
258                                 case 0x09: // JALR
259                                         if (_tRd_ == reg && _tRs_ == reg) return 1; else
260                                         if (_tRs_ == reg) return 2; else
261                                         if (_tRd_ == reg) return 3;
262                                         break;
263
264                                 // SYSCALL/BREAK just a break;
265
266                                 case 0x20: case 0x21: case 0x22: case 0x23:
267                                 case 0x24: case 0x25: case 0x26: case 0x27: 
268                                 case 0x2a: case 0x2b: // ADD/ADDU...
269                                 case 0x04: case 0x06: case 0x07: // SLLV...
270                                         if (_tRd_ == reg && (_tRt_ == reg || _tRs_ == reg)) return 1; else
271                                         if (_tRt_ == reg || _tRs_ == reg) return 2; else
272                                         if (_tRd_ == reg) return 3;
273                                         break;
274
275                                 case 0x10: case 0x12: // MFHI/MFLO
276                                         if (_tRd_ == reg) return 3;
277                                         break;
278                                 case 0x11: case 0x13: // MTHI/MTLO
279                                         if (_tRs_ == reg) return 2;
280                                         break;
281
282                                 case 0x18: case 0x19:
283                                 case 0x1a: case 0x1b: // MULT/DIV...
284                                         if (_tRt_ == reg || _tRs_ == reg) return 2;
285                                         break;
286                         }
287                         break;
288
289                 case 0x01: // REGIMM - BLTZ/BGEZ...
290                         // Xenogears - lbu v0 / beq v0
291                         // - no load delay (fixes battle loading)
292                         break;
293
294                 // J would be just a break;
295                 case 0x03: // JAL
296                         if (31 == reg) return 3;
297                         break;
298
299                 case 0x06: case 0x07: // BLEZ/BGTZ
300                 case 0x04: case 0x05: // BEQ/BNE
301                         // Xenogears - lbu v0 / beq v0
302                         // - no load delay (fixes battle loading)
303                         break;
304
305                 case 0x08: case 0x09: case 0x0a: case 0x0b:
306                 case 0x0c: case 0x0d: case 0x0e: // ADDI/ADDIU...
307                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
308                         if (_tRs_ == reg) return 2; else
309                         if (_tRt_ == reg) return 3;
310                         break;
311
312                 case 0x0f: // LUI
313                         if (_tRt_ == reg) return 3;
314                         break;
315
316                 case 0x10: // COP0
317                         switch (_tFunct_) {
318                                 case 0x00: // MFC0
319                                         if (_tRt_ == reg) return 3;
320                                         break;
321                                 case 0x02: // CFC0
322                                         if (_tRt_ == reg) return 3;
323                                         break;
324                                 case 0x04: // MTC0
325                                         if (_tRt_ == reg) return 2;
326                                         break;
327                                 case 0x06: // CTC0
328                                         if (_tRt_ == reg) return 2;
329                                         break;
330                                 // RFE just a break;
331                         }
332                         break;
333
334                 case 0x12: // COP2
335                         switch (_tFunct_) {
336                                 case 0x00: 
337                                         switch (_tRs_) {
338                                                 case 0x00: // MFC2
339                                                         if (_tRt_ == reg) return 3;
340                                                         break;
341                                                 case 0x02: // CFC2
342                                                         if (_tRt_ == reg) return 3;
343                                                         break;
344                                                 case 0x04: // MTC2
345                                                         if (_tRt_ == reg) return 2;
346                                                         break;
347                                                 case 0x06: // CTC2
348                                                         if (_tRt_ == reg) return 2;
349                                                         break;
350                                         }
351                                         break;
352                                 // RTPS... break;
353                         }
354                         break;
355
356                 case 0x22: case 0x26: // LWL/LWR
357                         if (_tRt_ == reg) return 3; else
358                         if (_tRs_ == reg) return 2;
359                         break;
360
361                 case 0x20: case 0x21: case 0x23:
362                 case 0x24: case 0x25: // LB/LH/LW/LBU/LHU
363                         if (_tRt_ == reg && _tRs_ == reg) return 1; else
364                         if (_tRs_ == reg) return 2; else
365                         if (_tRt_ == reg) return 3;
366                         break;
367
368                 case 0x28: case 0x29: case 0x2a:
369                 case 0x2b: case 0x2e: // SB/SH/SWL/SW/SWR
370                         if (_tRt_ == reg || _tRs_ == reg) return 2;
371                         break;
372
373                 case 0x32: case 0x3a: // LWC2/SWC2
374                         if (_tRs_ == reg) return 2;
375                         break;
376         }
377
378         return 0;
379 }
380
381 static void psxDelayTest(int reg, u32 bpc) {
382         u32 tmp = intFakeFetch(bpc);
383         branch = 1;
384
385         switch (psxTestLoadDelay(reg, tmp)) {
386                 case 1:
387                         delayReadWrite(reg, bpc); return;
388                 case 2:
389                         delayRead(reg, bpc); return;
390                 case 3:
391                         delayWrite(reg, bpc); return;
392         }
393         // DS
394         psxBSC[psxRegs.code >> 26](&psxRegs, psxRegs.code);
395
396         branch = 0;
397         psxRegs.pc = bpc;
398
399         psxBranchTest();
400 }
401
402 static u32 psxBranchNoDelay(psxRegisters *regs_) {
403         u32 temp, code;
404
405         regs_->code = code = intFakeFetch(regs_->pc);
406         switch (_Op_) {
407                 case 0x00: // SPECIAL
408                         switch (_Funct_) {
409                                 case 0x08: // JR
410                                         return _u32(_rRs_);
411                                 case 0x09: // JALR
412                                         temp = _u32(_rRs_);
413                                         if (_Rd_) { _SetLink(_Rd_); }
414                                         return temp;
415                         }
416                         break;
417                 case 0x01: // REGIMM
418                         switch (_Rt_) {
419                                 case 0x00: // BLTZ
420                                         if (_i32(_rRs_) < 0)
421                                                 return _BranchTarget_;
422                                         break;
423                                 case 0x01: // BGEZ
424                                         if (_i32(_rRs_) >= 0)
425                                                 return _BranchTarget_;
426                                         break;
427                                 case 0x08: // BLTZAL
428                                         if (_i32(_rRs_) < 0) {
429                                                 _SetLink(31);
430                                                 return _BranchTarget_;
431                                         }
432                                         break;
433                                 case 0x09: // BGEZAL
434                                         if (_i32(_rRs_) >= 0) {
435                                                 _SetLink(31);
436                                                 return _BranchTarget_;
437                                         }
438                                         break;
439                         }
440                         break;
441                 case 0x02: // J
442                         return _JumpTarget_;
443                 case 0x03: // JAL
444                         _SetLink(31);
445                         return _JumpTarget_;
446                 case 0x04: // BEQ
447                         if (_i32(_rRs_) == _i32(_rRt_))
448                                 return _BranchTarget_;
449                         break;
450                 case 0x05: // BNE
451                         if (_i32(_rRs_) != _i32(_rRt_))
452                                 return _BranchTarget_;
453                         break;
454                 case 0x06: // BLEZ
455                         if (_i32(_rRs_) <= 0)
456                                 return _BranchTarget_;
457                         break;
458                 case 0x07: // BGTZ
459                         if (_i32(_rRs_) > 0)
460                                 return _BranchTarget_;
461                         break;
462         }
463
464         return (u32)-1;
465 }
466
467 static int psxDelayBranchExec(u32 tar) {
468         execI();
469
470         branch = 0;
471         psxRegs.pc = tar;
472         addCycle();
473         psxBranchTest();
474         return 1;
475 }
476
477 static int psxDelayBranchTest(u32 tar1) {
478         u32 tar2, tmp1, tmp2;
479
480         tar2 = psxBranchNoDelay(&psxRegs);
481         if (tar2 == (u32)-1)
482                 return 0;
483
484         /*
485          * Branch in delay slot:
486          * - execute 1 instruction at tar1
487          * - jump to tar2 (target of branch in delay slot; this branch
488          *   has no normal delay slot, instruction at tar1 was fetched instead)
489          */
490         psxRegs.pc = tar1;
491         tmp1 = psxBranchNoDelay(&psxRegs);
492         if (tmp1 == (u32)-1) {
493                 return psxDelayBranchExec(tar2);
494         }
495         addCycle();
496
497         /*
498          * Got a branch at tar1:
499          * - execute 1 instruction at tar2
500          * - jump to target of that branch (tmp1)
501          */
502         psxRegs.pc = tar2;
503         tmp2 = psxBranchNoDelay(&psxRegs);
504         if (tmp2 == (u32)-1) {
505                 return psxDelayBranchExec(tmp1);
506         }
507         addCycle();
508
509         /*
510          * Got a branch at tar2:
511          * - execute 1 instruction at tmp1
512          * - jump to target of that branch (tmp2)
513          */
514         psxRegs.pc = tmp1;
515         return psxDelayBranchExec(tmp2);
516 }
517
518 static void doBranch(u32 tar) {
519         u32 tmp, code, pc;
520
521         branch2 = branch = 1;
522         branchPC = tar;
523
524         // check for branch in delay slot
525         if (psxDelayBranchTest(tar))
526                 return;
527
528         pc = psxRegs.pc;
529         psxRegs.pc += 4;
530         psxRegs.code = code = fetch(&psxRegs, psxMemRLUT, pc);
531
532         addCycle();
533
534         // check for load delay
535         tmp = code >> 26;
536         switch (tmp) {
537                 case 0x10: // COP0
538                         switch (_Rs_) {
539                                 case 0x00: // MFC0
540                                 case 0x02: // CFC0
541                                         psxDelayTest(_Rt_, branchPC);
542                                         return;
543                         }
544                         break;
545                 case 0x12: // COP2
546                         switch (_Funct_) {
547                                 case 0x00:
548                                         switch (_Rs_) {
549                                                 case 0x00: // MFC2
550                                                 case 0x02: // CFC2
551                                                         psxDelayTest(_Rt_, branchPC);
552                                                         return;
553                                         }
554                                         break;
555                         }
556                         break;
557                 case 0x32: // LWC2
558                         psxDelayTest(_Rt_, branchPC);
559                         return;
560                 default:
561                         if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR
562                                 psxDelayTest(_Rt_, branchPC);
563                                 return;
564                         }
565                         break;
566         }
567
568         psxBSC[code >> 26](&psxRegs, code);
569
570         branch = 0;
571         psxRegs.pc = branchPC;
572
573         psxBranchTest();
574 }
575
576 static void doBranchReg(u32 tar) {
577 #ifdef DO_EXCEPTION_ADDR_ERR
578         if (unlikely(tar & 3)) {
579                 psxRegs.pc = psxRegs.CP0.n.BadVAddr = tar;
580                 psxException(R3000E_AdEL << 2, branch, &psxRegs.CP0);
581                 return;
582         }
583 #else
584         tar &= ~3;
585 #endif
586         doBranch(tar);
587 }
588
589 #if __has_builtin(__builtin_add_overflow) || (defined(__GNUC__) && __GNUC__ >= 5)
590 #define add_overflow(a, b, r) __builtin_add_overflow(a, b, &(r))
591 #define sub_overflow(a, b, r) __builtin_sub_overflow(a, b, &(r))
592 #else
593 #define add_overflow(a, b, r) ({r = (u32)a + (u32)b; (a ^ ~b) & (a ^ r) & (1u<<31);})
594 #define sub_overflow(a, b, r) ({r = (u32)a - (u32)b; (a ^  b) & (a ^ r) & (1u<<31);})
595 #endif
596
597 static void addExc(psxRegisters *regs, u32 rt, s32 a1, s32 a2) {
598         s32 r;
599         if (add_overflow(a1, a2, r)) {
600                 //printf("ov %08x + %08x = %08x\n", a1, a2, r);
601                 regs->pc -= 4;
602                 psxException(R3000E_Ov << 2, branch, &regs->CP0);
603                 return;
604         }
605         if (rt)
606                 regs->GPR.r[rt] = r;
607 }
608
609 static void subExc(psxRegisters *regs, u32 rt, s32 a1, s32 a2) {
610         s32 r;
611         if (sub_overflow(a1, a2, r)) {
612                 regs->pc -= 4;
613                 psxException(R3000E_Ov << 2, branch, &regs->CP0);
614                 return;
615         }
616         if (rt)
617                 regs->GPR.r[rt] = r;
618 }
619
620 /*********************************************************
621 * Arithmetic with immediate operand                      *
622 * Format:  OP rt, rs, immediate                          *
623 *********************************************************/
624 OP(psxADDI)  { addExc(regs_, _Rt_, _i32(_rRs_), _Imm_); } // Rt = Rs + Im (Exception on Integer Overflow)
625 OP(psxADDIU) { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; }  // Rt = Rs + Im
626 OP(psxANDI)  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; }  // Rt = Rs And Im
627 OP(psxORI)   { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; }  // Rt = Rs Or  Im
628 OP(psxXORI)  { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; }  // Rt = Rs Xor Im
629 OP(psxSLTI)  { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; }  // Rt = Rs < Im              (Signed)
630 OP(psxSLTIU) { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < ((u32)_Imm_); } // Rt = Rs < Im         (Unsigned)
631
632 /*********************************************************
633 * Register arithmetic                                    *
634 * Format:  OP rd, rs, rt                                 *
635 *********************************************************/
636 OP(psxADD)   { addExc(regs_, _Rd_, _i32(_rRs_), _i32(_rRt_)); } // Rd = Rs + Rt (Exception on Integer Overflow)
637 OP(psxSUB)   { subExc(regs_, _Rd_, _i32(_rRs_), _i32(_rRt_)); } // Rd = Rs - Rt (Exception on Integer Overflow)
638 OP(psxADDU)  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); }  // Rd = Rs + Rt
639 OP(psxSUBU)  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); }  // Rd = Rs - Rt
640 OP(psxAND)   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); }  // Rd = Rs And Rt
641 OP(psxOR)    { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); }  // Rd = Rs Or  Rt
642 OP(psxXOR)   { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); }  // Rd = Rs Xor Rt
643 OP(psxNOR)   { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt
644 OP(psxSLT)   { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); }  // Rd = Rs < Rt         (Signed)
645 OP(psxSLTU)  { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); }  // Rd = Rs < Rt         (Unsigned)
646
647 /*********************************************************
648 * Register mult/div & Register trap logic                *
649 * Format:  OP rs, rt                                     *
650 *********************************************************/
651 OP(psxDIV) {
652         if (!_rRt_) {
653                 _rHi_ = _rRs_;
654                 if (_rRs_ & 0x80000000) {
655                         _rLo_ = 1;
656                 } else {
657                         _rLo_ = 0xFFFFFFFF;
658                 }
659         }
660 #if !defined(__arm__) && !defined(__aarch64__)
661         else if (_rRs_ == 0x80000000 && _rRt_ == 0xFFFFFFFF) {
662                 _rLo_ = 0x80000000;
663                 _rHi_ = 0;
664         }
665 #endif
666         else {
667                 _rLo_ = _i32(_rRs_) / _i32(_rRt_);
668                 _rHi_ = _i32(_rRs_) % _i32(_rRt_);
669         }
670 }
671
672 OP(psxDIV_stall) {
673         regs_->muldivBusyCycle = regs_->cycle + 37;
674         psxDIV(regs_, code);
675 }
676
677 OP(psxDIVU) {
678         if (_rRt_ != 0) {
679                 _rLo_ = _rRs_ / _rRt_;
680                 _rHi_ = _rRs_ % _rRt_;
681         }
682         else {
683                 _rLo_ = 0xffffffff;
684                 _rHi_ = _rRs_;
685         }
686 }
687
688 OP(psxDIVU_stall) {
689         regs_->muldivBusyCycle = regs_->cycle + 37;
690         psxDIVU(regs_, code);
691 }
692
693 OP(psxMULT) {
694         u64 res = (s64)_i32(_rRs_) * _i32(_rRt_);
695
696         regs_->GPR.n.lo = (u32)res;
697         regs_->GPR.n.hi = (u32)(res >> 32);
698 }
699
700 OP(psxMULT_stall) {
701         // approximate, but maybe good enough
702         u32 rs = _rRs_;
703         u32 lz = __builtin_clz(((rs ^ ((s32)rs >> 21)) | 1));
704         u32 c = 7 + (2 - (lz / 11)) * 4;
705         regs_->muldivBusyCycle = regs_->cycle + c;
706         psxMULT(regs_, code);
707 }
708
709 OP(psxMULTU) {
710         u64 res = (u64)_u32(_rRs_) * _u32(_rRt_);
711
712         regs_->GPR.n.lo = (u32)(res & 0xffffffff);
713         regs_->GPR.n.hi = (u32)((res >> 32) & 0xffffffff);
714 }
715
716 OP(psxMULTU_stall) {
717         // approximate, but maybe good enough
718         u32 lz = __builtin_clz(_rRs_ | 1);
719         u32 c = 7 + (2 - (lz / 11)) * 4;
720         regs_->muldivBusyCycle = regs_->cycle + c;
721         psxMULTU(regs_, code);
722 }
723
724 /*********************************************************
725 * Register branch logic                                  *
726 * Format:  OP rs, offset                                 *
727 *********************************************************/
728 #define RepZBranchi32(op) \
729         if(_i32(_rRs_) op 0) \
730                 doBranch(_BranchTarget_);
731 #define RepZBranchLinki32(op)  { \
732         s32 temp = _i32(_rRs_); \
733         _SetLink(31); \
734         if(temp op 0) \
735                 doBranch(_BranchTarget_); \
736 }
737
738 OP(psxBGEZ)   { RepZBranchi32(>=) }      // Branch if Rs >= 0
739 OP(psxBGEZAL) { RepZBranchLinki32(>=) }  // Branch if Rs >= 0 and link
740 OP(psxBGTZ)   { RepZBranchi32(>) }       // Branch if Rs >  0
741 OP(psxBLEZ)   { RepZBranchi32(<=) }      // Branch if Rs <= 0
742 OP(psxBLTZ)   { RepZBranchi32(<) }       // Branch if Rs <  0
743 OP(psxBLTZAL) { RepZBranchLinki32(<) }   // Branch if Rs <  0 and link
744
745 /*********************************************************
746 * Shift arithmetic with constant shift                   *
747 * Format:  OP rd, rt, sa                                 *
748 *********************************************************/
749 OP(psxSLL) { if (!_Rd_) return; _rRd_ = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa
750 OP(psxSRA) { if (!_Rd_) return; _rRd_ = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic)
751 OP(psxSRL) { if (!_Rd_) return; _rRd_ = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical)
752
753 /*********************************************************
754 * Shift arithmetic with variant register shift           *
755 * Format:  OP rd, rt, rs                                 *
756 *********************************************************/
757 OP(psxSLLV) { if (!_Rd_) return; _rRd_ = _u32(_rRt_) << (_u32(_rRs_) & 0x1F); } // Rd = Rt << rs
758 OP(psxSRAV) { if (!_Rd_) return; _rRd_ = _i32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (arithmetic)
759 OP(psxSRLV) { if (!_Rd_) return; _rRd_ = _u32(_rRt_) >> (_u32(_rRs_) & 0x1F); } // Rd = Rt >> rs (logical)
760
761 /*********************************************************
762 * Load higher 16 bits of the first word in GPR with imm  *
763 * Format:  OP rt, immediate                              *
764 *********************************************************/
765 OP(psxLUI) { if (!_Rt_) return; _rRt_ = code << 16; } // Upper halfword of Rt = Im
766
767 /*********************************************************
768 * Move from HI/LO to GPR                                 *
769 * Format:  OP rd                                         *
770 *********************************************************/
771 OP(psxMFHI) { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi
772 OP(psxMFLO) { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo
773
774 static void mflohiCheckStall(psxRegisters *regs_)
775 {
776         u32 left = regs_->muldivBusyCycle - regs_->cycle;
777         if (left <= 37) {
778                 //printf("muldiv stall %u\n", left);
779                 regs_->cycle = regs_->muldivBusyCycle;
780         }
781 }
782
783 OP(psxMFHI_stall) { mflohiCheckStall(regs_); psxMFHI(regs_, code); }
784 OP(psxMFLO_stall) { mflohiCheckStall(regs_); psxMFLO(regs_, code); }
785
786 /*********************************************************
787 * Move to GPR to HI/LO & Register jump                   *
788 * Format:  OP rs                                         *
789 *********************************************************/
790 OP(psxMTHI) { _rHi_ = _rRs_; } // Hi = Rs
791 OP(psxMTLO) { _rLo_ = _rRs_; } // Lo = Rs
792
793 /*********************************************************
794 * Special purpose instructions                           *
795 * Format:  OP                                            *
796 *********************************************************/
797 OP(psxBREAK) {
798         regs_->pc -= 4;
799         psxException(R3000E_Bp << 2, branch, &regs_->CP0);
800 }
801
802 OP(psxSYSCALL) {
803         regs_->pc -= 4;
804         psxException(R3000E_Syscall << 2, branch, &regs_->CP0);
805 }
806
807 static inline void execI_(u8 **memRLUT, psxRegisters *regs_);
808
809 static inline void psxTestSWInts(psxRegisters *regs_, int step) {
810         if (regs_->CP0.n.Cause & regs_->CP0.n.Status & 0x0300 &&
811            regs_->CP0.n.Status & 0x1) {
812                 if (step)
813                         execI_(psxMemRLUT, regs_);
814                 regs_->CP0.n.Cause &= ~0x7c;
815                 psxException(regs_->CP0.n.Cause, branch, &regs_->CP0);
816         }
817 }
818
819 OP(psxRFE) {
820 //      SysPrintf("psxRFE\n");
821         regs_->CP0.n.Status = (regs_->CP0.n.Status & 0xfffffff0) |
822                               ((regs_->CP0.n.Status & 0x3c) >> 2);
823         psxTestSWInts(regs_, 0);
824 }
825
826 /*********************************************************
827 * Register branch logic                                  *
828 * Format:  OP rs, rt, offset                             *
829 *********************************************************/
830 #define RepBranchi32(op)      if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_);
831
832 OP(psxBEQ) { RepBranchi32(==) }  // Branch if Rs == Rt
833 OP(psxBNE) { RepBranchi32(!=) }  // Branch if Rs != Rt
834
835 /*********************************************************
836 * Jump to target                                         *
837 * Format:  OP target                                     *
838 *********************************************************/
839 OP(psxJ)   {               doBranch(_JumpTarget_); }
840 OP(psxJAL) { _SetLink(31); doBranch(_JumpTarget_); }
841
842 /*********************************************************
843 * Register jump                                          *
844 * Format:  OP rs, rd                                     *
845 *********************************************************/
846 OP(psxJR) {
847         doBranchReg(_rRs_);
848         psxJumpTest();
849 }
850
851 OP(psxJALR) {
852         u32 temp = _u32(_rRs_);
853         if (_Rd_) { _SetLink(_Rd_); }
854         doBranchReg(temp);
855 }
856
857 /*********************************************************
858 * Load and store for GPR                                 *
859 * Format:  OP rt, offset(base)                           *
860 *********************************************************/
861
862 #define _oB_ (regs_->GPR.r[_Rs_] + _Imm_)
863
864 OP(psxLB)  { u32 v =  (s8)psxMemRead8(_oB_);  if (_Rt_) _rRt_ = v; }
865 OP(psxLBU) { u32 v =      psxMemRead8(_oB_);  if (_Rt_) _rRt_ = v; }
866 OP(psxLH)  { u32 v = (s16)psxMemRead16(_oB_); if (_Rt_) _rRt_ = v; }
867 OP(psxLHU) { u32 v =      psxMemRead16(_oB_); if (_Rt_) _rRt_ = v; }
868 OP(psxLW)  { u32 v =      psxMemRead32(_oB_); if (_Rt_) _rRt_ = v; }
869
870 OP(psxLWL) {
871         static const u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
872         static const u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
873         u32 addr = _oB_;
874         u32 shift = addr & 3;
875         u32 mem = psxMemRead32(addr & ~3);
876
877         if (!_Rt_) return;
878         _rRt_ = (_u32(_rRt_) & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift]);
879
880         /*
881         Mem = 1234.  Reg = abcd
882
883         0   4bcd   (mem << 24) | (reg & 0x00ffffff)
884         1   34cd   (mem << 16) | (reg & 0x0000ffff)
885         2   234d   (mem <<  8) | (reg & 0x000000ff)
886         3   1234   (mem      ) | (reg & 0x00000000)
887         */
888 }
889
890 OP(psxLWR) {
891         static const u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
892         static const u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
893         u32 addr = _oB_;
894         u32 shift = addr & 3;
895         u32 mem = psxMemRead32(addr & ~3);
896
897         if (!_Rt_) return;
898         _rRt_ = (_u32(_rRt_) & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]);
899
900         /*
901         Mem = 1234.  Reg = abcd
902
903         0   1234   (mem      ) | (reg & 0x00000000)
904         1   a123   (mem >>  8) | (reg & 0xff000000)
905         2   ab12   (mem >> 16) | (reg & 0xffff0000)
906         3   abc1   (mem >> 24) | (reg & 0xffffff00)
907         */
908 }
909
910 OP(psxSB) { psxMemWrite8 (_oB_, _rRt_ &   0xff); }
911 OP(psxSH) { psxMemWrite16(_oB_, _rRt_ & 0xffff); }
912 OP(psxSW) { psxMemWrite32(_oB_, _rRt_); }
913
914 OP(psxSWL) {
915         static const u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0 };
916         static const u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
917         u32 addr = _oB_;
918         u32 shift = addr & 3;
919         u32 mem = psxMemRead32(addr & ~3);
920
921         psxMemWrite32(addr & ~3,  (_u32(_rRt_) >> SWL_SHIFT[shift]) |
922                              (  mem & SWL_MASK[shift]) );
923         /*
924         Mem = 1234.  Reg = abcd
925
926         0   123a   (reg >> 24) | (mem & 0xffffff00)
927         1   12ab   (reg >> 16) | (mem & 0xffff0000)
928         2   1abc   (reg >>  8) | (mem & 0xff000000)
929         3   abcd   (reg      ) | (mem & 0x00000000)
930         */
931 }
932
933 OP(psxSWR) {
934         static const u32 SWR_MASK[4] = { 0, 0xff, 0xffff, 0xffffff };
935         static const u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
936         u32 addr = _oB_;
937         u32 shift = addr & 3;
938         u32 mem = psxMemRead32(addr & ~3);
939
940         psxMemWrite32(addr & ~3,  (_u32(_rRt_) << SWR_SHIFT[shift]) |
941                              (  mem & SWR_MASK[shift]) );
942
943         /*
944         Mem = 1234.  Reg = abcd
945
946         0   abcd   (reg      ) | (mem & 0x00000000)
947         1   bcd4   (reg <<  8) | (mem & 0x000000ff)
948         2   cd34   (reg << 16) | (mem & 0x0000ffff)
949         3   d234   (reg << 24) | (mem & 0x00ffffff)
950         */
951 }
952
953 /*********************************************************
954 * Moves between GPR and COPx                             *
955 * Format:  OP rt, fs                                     *
956 *********************************************************/
957 OP(psxMFC0) {
958         u32 r = _Rd_;
959 #ifdef DO_EXCEPTION_RESERVEDI
960         if (unlikely(r == 0)) {
961                 regs_->pc -= 4;
962                 psxException(R3000E_RI << 2, branch, &regs_->CP0);
963         }
964 #endif
965         if (_Rt_)
966                 _rRt_ = regs_->CP0.r[r];
967 }
968
969 OP(psxCFC0) { if (!_Rt_) return; _rRt_ = _rFs_; }
970
971 static void setupCop(u32 sr);
972
973 void MTC0(psxRegisters *regs_, int reg, u32 val) {
974 //      SysPrintf("MTC0 %d: %x\n", reg, val);
975         switch (reg) {
976                 case 12: // Status
977                         if (unlikely((regs_->CP0.n.Status ^ val) & (1 << 16)))
978                                 psxMemOnIsolate((val >> 16) & 1);
979                         if (unlikely((regs_->CP0.n.Status ^ val) & (7 << 29)))
980                                 setupCop(val);
981                         regs_->CP0.n.Status = val;
982                         psxTestSWInts(regs_, 1);
983                         break;
984
985                 case 13: // Cause
986                         regs_->CP0.n.Cause &= ~0x0300;
987                         regs_->CP0.n.Cause |= val & 0x0300;
988                         psxTestSWInts(regs_, 0);
989                         break;
990
991                 default:
992                         regs_->CP0.r[reg] = val;
993                         break;
994         }
995 }
996
997 OP(psxMTC0) { MTC0(regs_, _Rd_, _u32(_rRt_)); }
998 OP(psxCTC0) { MTC0(regs_, _Rd_, _u32(_rRt_)); }
999
1000 /*********************************************************
1001 * Unknown instruction (would generate an exception)      *
1002 * Format:  ?                                             *
1003 *********************************************************/
1004 static inline void psxNULL_(void) {
1005         //printf("op %08x @%08x\n", psxRegs.code, psxRegs.pc);
1006 }
1007
1008 OP(psxNULL) {
1009         psxNULL_();
1010 #ifdef DO_EXCEPTION_RESERVEDI
1011         regs_->pc -= 4;
1012         psxException(R3000E_RI << 2, branch, &regs_->CP0);
1013 #endif
1014 }
1015
1016 void gteNULL(struct psxCP2Regs *regs) {
1017         psxNULL_();
1018 }
1019
1020 OP(psxSPECIAL) {
1021         psxSPC[_Funct_](regs_, code);
1022 }
1023
1024 OP(psxCOP0) {
1025         switch (_Rs_) {
1026                 case 0x00: psxMFC0(regs_, code); break;
1027                 case 0x02: psxCFC0(regs_, code); break;
1028                 case 0x04: psxMTC0(regs_, code); break;
1029                 case 0x06: psxCTC0(regs_, code); break;
1030                 case 0x10: psxRFE(regs_, code);  break;
1031                 default:   psxNULL_();           break;
1032         }
1033 }
1034
1035 OP(psxLWC0) {
1036         // MTC0(regs_, _Rt_, psxMemRead32(_oB_)); // ?
1037         log_unhandled("LWC0 %08x\n", code);
1038 }
1039
1040 OP(psxCOP1) {
1041         // ??? what actually happens here?
1042 }
1043
1044 OP(psxCOP1d) {
1045 #ifdef DO_EXCEPTION_RESERVEDI
1046         regs_->pc -= 4;
1047         psxException((1<<28) | (R3000E_RI << 2), branch, &regs_->CP0);
1048 #endif
1049 }
1050
1051 OP(psxCOP2) {
1052         psxCP2[_Funct_](&regs_->CP2);
1053 }
1054
1055 OP(psxCOP2_stall) {
1056         u32 f = _Funct_;
1057         gteCheckStall(f);
1058         psxCP2[f](&regs_->CP2);
1059 }
1060
1061 OP(psxCOP2d) {
1062 #ifdef DO_EXCEPTION_RESERVEDI
1063         regs_->pc -= 4;
1064         psxException((2<<28) | (R3000E_RI << 2), branch, &regs_->CP0);
1065 #endif
1066 }
1067
1068 OP(gteMFC2) {
1069         if (!_Rt_) return;
1070         regs_->GPR.r[_Rt_] = MFC2(&regs_->CP2, _Rd_);
1071 }
1072
1073 OP(gteCFC2) {
1074         if (!_Rt_) return;
1075         regs_->GPR.r[_Rt_] = regs_->CP2C.r[_Rd_];
1076 }
1077
1078 OP(gteMTC2) {
1079         MTC2(&regs_->CP2, regs_->GPR.r[_Rt_], _Rd_);
1080 }
1081
1082 OP(gteCTC2) {
1083         CTC2(&regs_->CP2, regs_->GPR.r[_Rt_], _Rd_);
1084 }
1085
1086 OP(gteLWC2) {
1087         MTC2(&regs_->CP2, psxMemRead32(_oB_), _Rt_);
1088 }
1089
1090 OP(gteSWC2) {
1091         psxMemWrite32(_oB_, MFC2(&regs_->CP2, _Rt_));
1092 }
1093
1094 OP(gteLWC2_stall) {
1095         gteCheckStall(0);
1096         gteLWC2(regs_, code);
1097 }
1098
1099 OP(gteSWC2_stall) {
1100         gteCheckStall(0);
1101         gteSWC2(regs_, code);
1102 }
1103
1104 OP(psxCOP3) {
1105         // ??? what actually happens here?
1106 }
1107
1108 OP(psxCOP3d) {
1109 #ifdef DO_EXCEPTION_RESERVEDI
1110         regs_->pc -= 4;
1111         psxException((3<<28) | (R3000E_RI << 2), branch, &regs_->CP0);
1112 #endif
1113 }
1114
1115 OP(psxLWCx) {
1116         // does this read memory?
1117         log_unhandled("LWCx %08x\n", code);
1118 }
1119
1120 OP(psxSWCx) {
1121         // does this write something to memory?
1122         log_unhandled("SWCx %08x\n", code);
1123 }
1124
1125 static void psxBASIC(struct psxCP2Regs *cp2regs) {
1126         psxRegisters *regs_ = (void *)((char *)cp2regs - offsetof(psxRegisters, CP2));
1127         u32 code = regs_->code;
1128         assert(regs_ == &psxRegs);
1129         switch (_Rs_) {
1130                 case 0x00: gteMFC2(regs_, code); break;
1131                 case 0x02: gteCFC2(regs_, code); break;
1132                 case 0x04: gteMTC2(regs_, code); break;
1133                 case 0x06: gteCTC2(regs_, code); break;
1134                 default:   psxNULL_();           break;
1135         }
1136 }
1137
1138 OP(psxREGIMM) {
1139         u32 rt = _Rt_;
1140         switch (rt) {
1141                 case 0x10: psxBLTZAL(regs_, code); break;
1142                 case 0x11: psxBGEZAL(regs_, code); break;
1143                 default:
1144                         if (rt & 1)
1145                                 psxBGEZ(regs_, code);
1146                         else
1147                                 psxBLTZ(regs_, code);
1148         }
1149 }
1150
1151 OP(psxHLE) {
1152         u32 hleCode;
1153         if (unlikely(!Config.HLE)) {
1154                 psxSWCx(regs_, code);
1155                 return;
1156         }
1157         hleCode = code & 0x03ffffff;
1158         if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0]))) {
1159                 psxSWCx(regs_, code);
1160                 return;
1161         }
1162         psxHLEt[hleCode]();
1163 }
1164
1165 static void (INT_ATTR *psxBSC[64])(psxRegisters *regs_, u32 code) = {
1166         psxSPECIAL, psxREGIMM, psxJ   , psxJAL  , psxBEQ , psxBNE , psxBLEZ, psxBGTZ,
1167         psxADDI   , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI ,
1168         psxCOP0   , psxCOP1d , psxCOP2, psxCOP3d, psxNULL, psxCOP1d,psxCOP2d,psxCOP3d,
1169         psxNULL   , psxCOP1d , psxCOP2d,psxCOP3d, psxNULL, psxCOP1d,psxCOP2d,psxCOP3d,
1170         psxLB     , psxLH    , psxLWL , psxLW   , psxLBU , psxLHU , psxLWR , psxCOP3d,
1171         psxSB     , psxSH    , psxSWL , psxSW   , psxNULL, psxCOP1d,psxSWR , psxCOP3d,
1172         psxLWC0   , psxLWCx  , gteLWC2, psxLWCx , psxNULL, psxCOP1d,psxCOP2d,psxCOP3d,
1173         psxSWCx   , psxSWCx  , gteSWC2, psxHLE  , psxNULL, psxCOP1d,psxCOP2d,psxCOP3d,
1174 };
1175
1176 static void (INT_ATTR *psxSPC[64])(psxRegisters *regs_, u32 code) = {
1177         psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV   , psxNULL , psxSRLV, psxSRAV,
1178         psxJR  , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL,
1179         psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL   , psxNULL , psxNULL, psxNULL,
1180         psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL   , psxNULL , psxNULL, psxNULL,
1181         psxADD , psxADDU , psxSUB , psxSUBU, psxAND    , psxOR   , psxXOR , psxNOR ,
1182         psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL   , psxNULL , psxNULL, psxNULL,
1183         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL,
1184         psxNULL, psxNULL , psxNULL, psxNULL, psxNULL   , psxNULL , psxNULL, psxNULL
1185 };
1186
1187 void (*psxCP2[64])(struct psxCP2Regs *regs) = {
1188         psxBASIC, gteRTPS , gteNULL , gteNULL, gteNULL, gteNULL , gteNCLIP, gteNULL, // 00
1189         gteNULL , gteNULL , gteNULL , gteNULL, gteOP  , gteNULL , gteNULL , gteNULL, // 08
1190         gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , gteNULL , gteNCDT , gteNULL, // 10
1191         gteNULL , gteNULL , gteNULL , gteNCCS, gteCC  , gteNULL , gteNCS  , gteNULL, // 18
1192         gteNCT  , gteNULL , gteNULL , gteNULL, gteNULL, gteNULL , gteNULL , gteNULL, // 20
1193         gteSQR  , gteDCPL , gteDPCT , gteNULL, gteNULL, gteAVSZ3, gteAVSZ4, gteNULL, // 28
1194         gteRTPT , gteNULL , gteNULL , gteNULL, gteNULL, gteNULL , gteNULL , gteNULL, // 30
1195         gteNULL , gteNULL , gteNULL , gteNULL, gteNULL, gteGPF  , gteGPL  , gteNCCT  // 38
1196 };
1197
1198 ///////////////////////////////////////////
1199
1200 static int intInit() {
1201         return 0;
1202 }
1203
1204 static void intReset() {
1205 }
1206
1207 static inline void execI_(u8 **memRLUT, psxRegisters *regs_) {
1208         u32 pc = regs_->pc;
1209         regs_->pc += 4;
1210         regs_->code = fetch(regs_, memRLUT, pc);
1211
1212         addCycle();
1213
1214         psxBSC[regs_->code >> 26](regs_, regs_->code);
1215 }
1216
1217 static void intExecute() {
1218         psxRegisters *regs_ = &psxRegs;
1219         u8 **memRLUT = psxMemRLUT;
1220         extern int stop;
1221
1222         while (!stop)
1223                 execI_(memRLUT, regs_);
1224 }
1225
1226 void intExecuteBlock(enum blockExecCaller caller) {
1227         psxRegisters *regs_ = &psxRegs;
1228         u8 **memRLUT = psxMemRLUT;
1229
1230         branch2 = 0;
1231         while (!branch2)
1232                 execI_(memRLUT, regs_);
1233 }
1234
1235 static void intClear(u32 Addr, u32 Size) {
1236 }
1237
1238 static void intNotify(enum R3000Anote note, void *data) {
1239         switch (note) {
1240         case R3000ACPU_NOTIFY_AFTER_LOAD:
1241                 setupCop(psxRegs.CP0.n.Status);
1242                 // fallthrough
1243         case R3000ACPU_NOTIFY_CACHE_ISOLATED: // Armored Core?
1244                 memset(&ICache, 0xff, sizeof(ICache));
1245                 break;
1246         case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
1247         case R3000ACPU_NOTIFY_BEFORE_SAVE:
1248                 break;
1249         }
1250 }
1251
1252 static void setupCop(u32 sr)
1253 {
1254         if (sr & (1u << 29))
1255                 psxBSC[17] = psxCOP1;
1256         else
1257                 psxBSC[17] = psxCOP1d;
1258         if (sr & (1u << 30))
1259                 psxBSC[18] = Config.DisableStalls ? psxCOP2 : psxCOP2_stall;
1260         else
1261                 psxBSC[18] = psxCOP2d;
1262         if (sr & (1u << 31))
1263                 psxBSC[19] = psxCOP3;
1264         else
1265                 psxBSC[19] = psxCOP3d;
1266 }
1267
1268 void intApplyConfig() {
1269         int cycle_mult;
1270
1271         assert(psxBSC[50] == gteLWC2  || psxBSC[50] == gteLWC2_stall);
1272         assert(psxBSC[58] == gteSWC2  || psxBSC[58] == gteSWC2_stall);
1273         assert(psxSPC[16] == psxMFHI  || psxSPC[16] == psxMFHI_stall);
1274         assert(psxSPC[18] == psxMFLO  || psxSPC[18] == psxMFLO_stall);
1275         assert(psxSPC[24] == psxMULT  || psxSPC[24] == psxMULT_stall);
1276         assert(psxSPC[25] == psxMULTU || psxSPC[25] == psxMULTU_stall);
1277         assert(psxSPC[26] == psxDIV   || psxSPC[26] == psxDIV_stall);
1278         assert(psxSPC[27] == psxDIVU  || psxSPC[27] == psxDIVU_stall);
1279
1280         if (Config.DisableStalls) {
1281                 psxBSC[18] = psxCOP2;
1282                 psxBSC[50] = gteLWC2;
1283                 psxBSC[58] = gteSWC2;
1284                 psxSPC[16] = psxMFHI;
1285                 psxSPC[18] = psxMFLO;
1286                 psxSPC[24] = psxMULT;
1287                 psxSPC[25] = psxMULTU;
1288                 psxSPC[26] = psxDIV;
1289                 psxSPC[27] = psxDIVU;
1290         } else {
1291                 psxBSC[18] = psxCOP2_stall;
1292                 psxBSC[50] = gteLWC2_stall;
1293                 psxBSC[58] = gteSWC2_stall;
1294                 psxSPC[16] = psxMFHI_stall;
1295                 psxSPC[18] = psxMFLO_stall;
1296                 psxSPC[24] = psxMULT_stall;
1297                 psxSPC[25] = psxMULTU_stall;
1298                 psxSPC[26] = psxDIV_stall;
1299                 psxSPC[27] = psxDIVU_stall;
1300         }
1301         setupCop(psxRegs.CP0.n.Status);
1302
1303         // dynarec may occasionally call the interpreter, in such a case the
1304         // cache won't work (cache only works right if all fetches go through it)
1305         if (!Config.icache_emulation || psxCpu != &psxInt)
1306                 fetch = fetchNoCache;
1307         else
1308                 fetch = fetchICache;
1309
1310         cycle_mult = Config.cycle_multiplier_override && Config.cycle_multiplier == CYCLE_MULT_DEFAULT
1311                 ? Config.cycle_multiplier_override : Config.cycle_multiplier;
1312         psxRegs.subCycleStep = 0x10000 * cycle_mult / 100;
1313 }
1314
1315 static void intShutdown() {
1316 }
1317
1318 // single step (may do several ops in case of a branch)
1319 void execI() {
1320         execI_(psxMemRLUT, &psxRegs);
1321 }
1322
1323 R3000Acpu psxInt = {
1324         intInit,
1325         intReset,
1326         intExecute,
1327         intExecuteBlock,
1328         intClear,
1329         intNotify,
1330         intApplyConfig,
1331         intShutdown
1332 };