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