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