Create Xref-Html Frames Remove All Frames
file:/home/jivera/wd/pcsx/sh4/sR3000A.c (Tue Nov 25 22:46:15 2003
)
1: /* Pcsx - Pc Psx Emulator
2: * Copyright (C) 1999-2002 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 Free Software
16: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17: */
18:
19: #include <stdlib.h>
20: #include <string.h>
21: #include <time.h>
22:
23: #include "R3000A.h"
24: #include "PsxCommon.h"
25: #include "sh4.h"
26:
27: u32 *recLUT;
28:
29: #define PC_REC(x) (recLUT[x >> 16] + (x & 0xffff))
30: #define PC_REC8(x) (*(u8 *)PC_REC(x))
31: #define PC_REC16(x) (*(u16*)PC_REC(x))
32: #define PC_REC32(x) (*(u32*)PC_REC(x))
33:
34: #define CLEAR_REC32(x) (*(u32*)(recLUT[(x) >> 16] + ((x) & 0xfffc)))
35:
36: #define RECMEM_SIZE (2*1024*1024)
37:
38: #define CalcDispL(rx) (((u32)&(psxRegs.rx) - (u32)&psxRegs)>>2)
39:
40: static char *recMem; /* the recompiled blocks will be here */
41: static char *recRAM; /* and the ptr to the blocks here */
42: static char *recROM; /* and here */
43:
44: static u32 pc; /* recompiler pc */
45: static int count; /* recompiler intruction count */
46: static int branch; /* set for branch */
47: static u32 target; /* branch target */
48:
49: static void (*recBSC[64])();
50: static void (*recSPC[64])();
51: static void (*recREG[32])();
52: static void (*recCP0[32])();
53: static void (*recCP2[64])();
54: static void (*recCP2BSC[32])();
55:
56:
57: /* set a pending branch (target stored in R8) */
58: #define SetBranch() { \
59: branch = 1; \
60: psxRegs.code = PSXMu32(pc); \
61: pc+=4; count++; \
62: recBSC[psxRegs.code>>26](); \
63: \
64: MOV(R8, R0); \
65: MOVLSG(CalcDispL(pc)); \
66: CALLFunc((u32)psxBranchTest); \
67: }
68:
69: #define REC_FUNC(f) \
70: void psx##f(); \
71: void rec##f() { \
72: LoadImmediate32(psxRegs.code, R0); \
73: MOVLSG(CalcDispL(code)); \
74: LoadImmediate32(pc, R0); \
75: MOVLSG(CalcDispL(pc)); \
76: CALLFunc((u32)psx##f); \
77: }
78:
79: static void recRecompile();
80:
81: static int recInit() {
82: int i;
83:
84: recLUT = (u32*) malloc(0x010000 * 4);
85:
86: recMem = (char*) malloc(RECMEM_SIZE);
87: recRAM = (char*) malloc(0x200000);
88: recROM = (char*) malloc(0x080000);
89: if (recRAM == NULL || recROM == NULL || recMem == NULL || recLUT == NULL) {
90: SysMessage("Error allocating memory"); return -1;
91: }
92:
93: for (i=0; i<0x80; i++) recLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16];
94: memcpy(recLUT + 0x8000, recLUT, 0x80 * 4);
95: memcpy(recLUT + 0xa000, recLUT, 0x80 * 4);
96:
97: for (i=0; i<0x08; i++) recLUT[i + 0xbfc0] = (u32)&recROM[i << 16];
98:
99: return 0;
100: }
101:
102: static void recReset() {
103: memset(recRAM, 0, 0x200000);
104: memset(recROM, 0, 0x080000);
105:
106: x86Init((char*)((u32)recMem|0xa0000000));
107: // x86Init(recMem);
108: branch = 0;
109: }
110:
111: static void recShutdown() {
112: if (recMem == NULL) return;
113: free(recLUT);
114: free(recMem);
115: free(recRAM);
116: free(recROM);
117: }
118:
119: static void recError() {
120: SysReset();
121: ClosePlugins();
122: SysMessage("Unrecoverable error while running recompiler\n");
123: SysRunGui();
124: }
125:
126: #define execute() { \
127: void (**recFunc)(); \
128: char *p; \
129: \
130: p = (char*)PC_REC(psxRegs.pc); \
131: if (p != NULL) recFunc = (void (**)()) (u32)p; \
132: else { recError(); return; } \
133: \
134: if (*recFunc == 0) { \
135: recRecompile(); \
136: } \
137: (*recFunc)(); \
138: }
139:
140: static void DumpRegs() {
141: int i, j;
142:
143: printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle);
144: for (i=0; i<4; i++) {
145: for (j=0; j<8; j++)
146: printf("%lx ", psxRegs.GPR.r[j*i]);
147: printf("\n");
148: }
149: }
150:
151: static void recExecuteBios() {
152: while (psxRegs.pc != 0x80030000) {
153: execute();
154: }
155: }
156:
157: static void recExecute() {
158: for (;;) execute();
159: }
160:
161: static void recExecuteBlock() {
162: execute();
163: }
164:
165: static void recClear(u32 Addr, u32 Size) {
166: if (Size == 1) { CLEAR_REC32(Addr) = 0; CLEAR_REC32(Addr+4) = 0; } else
167: memset((void*)PC_REC(Addr), 0, Size * 4);
168: }
169:
170: static void recNULL() {
171: // SysMessage("recUNK: %8.8x\n", psxRegs.code);
172: }
173:
174: /*********************************************************
175: * goes to opcodes tables... *
176: * Format: table[something....] *
177: *********************************************************/
178:
179: //REC_SYS(SPECIAL);
180: static void recSPECIAL() {
181: recSPC[_Funct_]();
182: }
183:
184: static void recREGIMM() {
185: recREG[_Rt_]();
186: }
187:
188: static void recCOP0() {
189: recCP0[_Rs_]();
190: }
191:
192: //REC_SYS(COP2);
193: static void recCOP2() {
194: recCP2[_Funct_]();
195: }
196:
197: static void recBASIC() {
198: recCP2BSC[_Rs_]();
199: }
200:
201: //end of Tables opcodes...
202:
203: /*********************************************************
204: * Arithmetic with immediate operand *
205: * Format: OP rt, rs, immediate *
206: *********************************************************/
207:
208: //REC_FUNC(ADDI);
209: //REC_FUNC(ADDIU);
210: //REC_FUNC(ANDI);
211: //REC_FUNC(ORI);
212: //REC_FUNC(XORI);
213: //REC_FUNC(SLTI);
214: //REC_FUNC(SLTIU);
215:
216: void recADDIU() {
217: // Rt = Rs + Im
218: if (!_Rt_) return;
219:
220: if (_Imm_) {
221: if (_Rs_) {
222: LoadImmediate32(_Imm_, R1);
223: MOVLLG(CalcDispL(GPR.r[_Rs_]));
224: ADD(R1, R0);
225: } else {
226: LoadImmediate32(_Imm_, R0);
227: }
228: } else {
229: if (_Rs_)
230: MOVLLG(CalcDispL(GPR.r[_Rs_]));
231: else
232: XOR(R0, R0);
233: }
234: MOVLSG(CalcDispL(GPR.r[_Rt_]));
235: }
236:
237: void recADDI() {
238: // Rt = Rs + Im
239: recADDIU();
240: }
241:
242: void recSLTI() {
243: // Rt = Rs < Im (signed)
244: if (!_Rt_) return;
245:
246: if (_Imm_) {
247: LoadImmediate32(_Imm_, R1);
248: MOVLLG(CalcDispL(GPR.r[_Rs_]));
249: CMPGT(R0, R1);
250: MOVT(R0);
251: MOVLSG(CalcDispL(GPR.r[_Rt_]));
252: } else {
253: XOR(R1, R1);
254: MOVLLG(CalcDispL(GPR.r[_Rs_]));
255: CMPGT(R0, R1);
256: MOVT(R0);
257: MOVLSG(CalcDispL(GPR.r[_Rt_]));
258: }
259: }
260:
261: void recSLTIU() {
262: // Rt = Rs < Im (unsigned)
263: if (!_Rt_) return;
264:
265: if (_ImmU_) {
266: LoadImmediate32(_ImmU_, R1);
267: MOVLLG(CalcDispL(GPR.r[_Rs_]));
268: CMPHI(R0, R1);
269: MOVT(R0);
270: MOVLSG(CalcDispL(GPR.r[_Rt_]));
271: } else {
272: XOR(R1, R1);
273: MOVLLG(CalcDispL(GPR.r[_Rs_]));
274: CMPHI(R0, R1);
275: MOVT(R0);
276: MOVLSG(CalcDispL(GPR.r[_Rt_]));
277: }
278: }
279:
280: void recANDI() {
281: // Rt = Rs And Im
282: if (!_Rt_) return;
283:
284: if (_Rs_ && _ImmU_) {
285: LoadImmediate32(_ImmU_, R1);
286: MOVLLG(CalcDispL(GPR.r[_Rs_]));
287: AND(R1, R0);
288: } else {
289: XOR(R0, R0);
290: }
291: MOVLSG(CalcDispL(GPR.r[_Rt_]));
292: }
293:
294: void recORI() {
295: // Rt = Rs Or Im
296: if (!_Rt_) return;
297:
298: if (_ImmU_) {
299: if (_Rs_) {
300: LoadImmediate32(_ImmU_, R1);
301: MOVLLG(CalcDispL(GPR.r[_Rs_]));
302: OR(R1, R0);
303: } else {
304: LoadImmediate32(_ImmU_, R0);
305: }
306: } else {
307: if (_Rs_)
308: MOVLLG(CalcDispL(GPR.r[_Rs_]));
309: else
310: XOR(R0, R0);
311: }
312: MOVLSG(CalcDispL(GPR.r[_Rt_]));
313: }
314:
315: void recXORI() {
316: // Rt = Rs Xor Im
317: if (!_Rt_) return;
318:
319: if (_ImmU_) {
320: if (_Rs_) {
321: LoadImmediate32(_ImmU_, R1);
322: MOVLLG(CalcDispL(GPR.r[_Rs_]));
323: XOR(R1, R0);
324: } else {
325: LoadImmediate32((_ImmU_ ^ 0), R0);
326: }
327: } else {
328: if (_Rs_) {
329: MOVLLG(CalcDispL(GPR.r[_Rs_]));
330: XORI(0);
331: } else
332: XOR(R0, R0);
333: }
334: MOVLSG(CalcDispL(GPR.r[_Rt_]));
335: }
336: //end of * Arithmetic with immediate operand
337:
338: /*********************************************************
339: * Load higher 16 bits of the first word in GPR with imm *
340: * Format: OP rt, immediate *
341: *********************************************************/
342: //REC_FUNC(LUI);
343:
344: void recLUI() {
345: // Rt = Imm << 16
346: if (!_Rt_) return;
347:
348: LoadImmediate32(psxRegs.code << 16, R0);
349: MOVLSG(CalcDispL(GPR.r[_Rt_]));
350: }
351: //End of Load Higher .....
352:
353: /*********************************************************
354: * Register arithmetic *
355: * Format: OP rd, rs, rt *
356: *********************************************************/
357:
358: //REC_FUNC(ADD);
359: //REC_FUNC(ADDU);
360: //REC_FUNC(SUB);
361: //REC_FUNC(SUBU);
362: //REC_FUNC(AND);
363: //REC_FUNC(OR);
364: //REC_FUNC(XOR);
365: //REC_FUNC(NOR);
366: //REC_FUNC(SLT);
367: //REC_FUNC(SLTU);
368:
369: void recADDU() {
370: // Rd = Rs + Rt
371: if (!_Rd_) return;
372:
373: if (_Rs_ && _Rt_) {
374: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
375: MOV(R0, R1);
376: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
377: ADD(R1, R0);
378: } else if (_Rs_) {
379: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
380: } else if (_Rt_) {
381: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
382: } else {
383: XOR(R0, R0);
384: }
385: MOVLSG(CalcDispL(GPR.r[_Rd_]));
386: }
387:
388: void recADD() {
389: recADDU();
390: }
391:
392: void recSUBU() {
393: // Rd = Rs - Rt
394: if (!_Rd_) return;
395:
396: if (_Rs_ || _Rt_) {
397: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
398: MOV(R0, R1);
399: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
400: SUB(R1, R0);
401: } else {
402: XOR(R0, R0);
403: }
404: MOVLSG(CalcDispL(GPR.r[_Rd_]));
405: }
406:
407: void recSUB() {
408: recSUBU();
409: }
410:
411: void recAND() {
412: // Rd = Rs And Rt
413: if (!_Rd_) return;
414:
415: if (_Rs_ && _Rt_) {
416: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
417: MOV(R0, R1);
418: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
419: AND(R1, R0);
420: } else {
421: XOR(R0, R0);
422: }
423: MOVLSG(CalcDispL(GPR.r[_Rd_]));
424: }
425:
426: void recOR() {
427: // Rd = Rs Or Rt
428: if (!_Rd_) return;
429:
430: if (_Rs_ && _Rt_) {
431: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
432: MOV(R0, R1);
433: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
434: OR(R1, R0);
435: } else if (_Rs_) {
436: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
437: } else if (_Rt_) {
438: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
439: } else {
440: XOR(R0, R0);
441: }
442: MOVLSG(CalcDispL(GPR.r[_Rd_]));
443: }
444:
445: void recXOR() {
446: // Rd = Rs Xor Rt
447: if (!_Rd_) return;
448:
449: if (_Rs_ && _Rt_) {
450: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
451: MOV(R0, R1);
452: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
453: XOR(R1, R0);
454: } else if (_Rs_) {
455: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
456: XORI(0);
457: } else if (_Rt_) {
458: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
459: XORI(0);
460: } else {
461: XOR(R0, R0);
462: }
463: MOVLSG(CalcDispL(GPR.r[_Rd_]));
464: }
465:
466: void recNOR() {
467: // Rd = Rs Nor Rt
468: if (!_Rd_) return;
469:
470: if (_Rs_ && _Rt_) {
471: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
472: MOV(R0, R1);
473: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
474: OR(R1, R0);
475: NOT(R0, R0);
476: } else if (_Rs_) {
477: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
478: NOT(R0, R0);
479: } else if (_Rt_) {
480: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
481: NOT(R0, R0);
482: } else {
483: MOVI(0xff, R0);
484: }
485: MOVLSG(CalcDispL(GPR.r[_Rd_]));
486: }
487:
488: void recSLT() {
489: // Rd = Rs < Rt (signed)
490: if (!_Rd_) return;
491:
492: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
493: MOV(R0, R1);
494: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
495: CMPGT(R1, R0);
496: MOVT(R0);
497: MOVLSG(CalcDispL(GPR.r[_Rd_]));
498: }
499:
500: void recSLTU() {
501: // Rd = Rs < Rt (unsigned)
502: if (!_Rd_) return;
503:
504: MOVLLG(CalcDispL(GPR.r[_Rs_])); // Load reg into R0
505: MOV(R0, R1);
506: MOVLLG(CalcDispL(GPR.r[_Rt_])); // Load reg into R0
507: CMPHI(R1, R0);
508: MOVT(R0);
509: MOVLSG(CalcDispL(GPR.r[_Rd_]));
510: }
511: //End of * Register arithmetic
512:
513: /*********************************************************
514: * Register mult/div & Register trap logic *
515: * Format: OP rs, rt *
516: *********************************************************/
517:
518: //REC_FUNC(MULT);
519: //REC_FUNC(MULTU);
520: REC_FUNC(DIV);
521: REC_FUNC(DIVU);
522:
523: void recMULT() {
524: // Lo/Hi = Rs * Rt (signed)
525:
526: MOVLLG(CalcDispL(GPR.r[_Rs_]));
527: MOV(R0, R1);
528: MOVLLG(CalcDispL(GPR.r[_Rt_]));
529: DMULS(R1, R0);
530: STSMACL(R0);
531: MOVLSG(CalcDispL(GPR.n.lo));
532: STSMACH(R0);
533: MOVLSG(CalcDispL(GPR.n.hi));
534: }
535:
536: void recMULTU() {
537: // Lo/Hi = Rs * Rt (unsigned)
538:
539: MOVLLG(CalcDispL(GPR.r[_Rs_]));
540: MOV(R0, R1);
541: MOVLLG(CalcDispL(GPR.r[_Rt_]));
542: DMULU(R1, R0);
543: STSMACL(R0);
544: MOVLSG(CalcDispL(GPR.n.lo));
545: STSMACH(R0);
546: MOVLSG(CalcDispL(GPR.n.hi));
547: }
548:
549: //End of * Register mult/div & Register trap logic
550:
551: //REC_FUNC(LB);
552: //REC_FUNC(LBU);
553: //REC_FUNC(LH);
554: //REC_FUNC(LHU);
555: //REC_FUNC(LW);
556:
557: //REC_FUNC(SB);
558: //REC_FUNC(SH);
559: //REC_FUNC(SW);
560:
561: REC_FUNC(LWL);
562: REC_FUNC(LWR);
563: REC_FUNC(SWL);
564: REC_FUNC(SWR);
565:
566: void recLB() {
567: // Rt = mem[Rs + Im] (signed)
568:
569: LoadImmediate32(_Imm_, R4);
570: MOVLLG(CalcDispL(GPR.r[_Rs_]));
571: ADD(R0, R4);
572:
573: CALLFunc((u32)psxMemRead8);
574: if (_Rt_) {
575: EXTSB(R0, R0);
576: MOVLSG(CalcDispL(GPR.r[_Rt_]));
577: }
578: }
579:
580: void recLBU() {
581: // Rt = mem[Rs + Im] (unsigned)
582:
583: LoadImmediate32(_Imm_, R4);
584: MOVLLG(CalcDispL(GPR.r[_Rs_]));
585: ADD(R0, R4);
586:
587: CALLFunc((u32)psxMemRead8);
588: if (_Rt_) {
589: EXTUB(R0, R0);
590: MOVLSG(CalcDispL(GPR.r[_Rt_]));
591: }
592: }
593:
594: void recLH() {
595: // Rt = mem[Rs + Im] (signed)
596:
597: LoadImmediate32(_Imm_, R4);
598: MOVLLG(CalcDispL(GPR.r[_Rs_]));
599: ADD(R0, R4);
600:
601: CALLFunc((u32)psxMemRead16);
602: if (_Rt_) {
603: EXTSW(R0, R0);
604: MOVLSG(CalcDispL(GPR.r[_Rt_]));
605: }
606: }
607:
608: void recLHU() {
609: // Rt = mem[Rs + Im] (unsigned)
610:
611: LoadImmediate32(_Imm_, R4);
612: MOVLLG(CalcDispL(GPR.r[_Rs_]));
613: ADD(R0, R4);
614:
615: CALLFunc((u32)psxMemRead16);
616: if (_Rt_) {
617: EXTUW(R0, R0);
618: MOVLSG(CalcDispL(GPR.r[_Rt_]));
619: }
620: }
621:
622: void recLW() {
623: // Rt = mem[Rs + Im] (unsigned)
624:
625: LoadImmediate32(_Imm_, R4);
626: MOVLLG(CalcDispL(GPR.r[_Rs_]));
627: ADD(R0, R4);
628:
629: CALLFunc((u32)psxMemRead32);
630: if (_Rt_)
631: MOVLSG(CalcDispL(GPR.r[_Rt_]));
632: }
633:
634: /*
635: void recLWL() {
636: }
637:
638: void recLWR() {
639: }
640: */
641: void recSB() {
642: // mem[Rs + Im] = Rt
643:
644: LoadImmediate32(_Imm_, R4);
645: MOVLLG(CalcDispL(GPR.r[_Rs_]));
646: ADD(R0, R4);
647: if (_Rt_) {
648: MOVLLG(CalcDispL(GPR.r[_Rt_]));
649: EXTUB(R0, R5);
650: } else
651: MOVI(0, R5);
652: CALLFunc((u32)psxMemWrite8);
653: }
654:
655: void recSH() {
656: // mem[Rs + Im] = Rt
657:
658: LoadImmediate32(_Imm_, R4);
659: MOVLLG(CalcDispL(GPR.r[_Rs_]));
660: ADD(R0, R4);
661: if (_Rt_) {
662: MOVLLG(CalcDispL(GPR.r[_Rt_]));
663: EXTUW(R0, R5);
664: } else
665: MOVI(0, R5);
666: CALLFunc((u32)psxMemWrite16);
667: }
668:
669: void recSW() {
670: // mem[Rs + Im] = Rt
671:
672: LoadImmediate32(_Imm_, R4);
673: MOVLLG(CalcDispL(GPR.r[_Rs_]));
674: ADD(R0, R4);
675: if (_Rt_) {
676: MOVLLG(CalcDispL(GPR.r[_Rt_]));
677: MOV(R0, R5);
678: } else
679: MOVI(0, R5);
680: CALLFunc((u32)psxMemWrite32);
681: }
682: /*
683: void recSWL() {
684: }
685:
686: void recSWR() {
687: }
688: */
689: //REC_FUNC(SLL);
690: //REC_FUNC(SRL);
691: //REC_FUNC(SRA);
692:
693: void recSLL() {
694: // Rd = Rt << Sa
695: if (!_Rd_) return;
696:
697: if (_Rt_) {
698: MOVLLG(CalcDispL(GPR.r[_Rt_]));
699: if (_Sa_) {
700: MOVI(_Sa_, R1);
701: SHLD(R1, R0);
702: }
703: } else {
704: XOR(R0, R0);
705: }
706: MOVLSG(CalcDispL(GPR.r[_Rd_]));
707: }
708:
709: void recSRL() {
710: // Rd = Rt >> Sa
711: if (!_Rd_) return;
712:
713: if (_Rt_) {
714: MOVLLG(CalcDispL(GPR.r[_Rt_]));
715: if (_Sa_) {
716: MOVI(-(_Sa_), R1);
717: SHLD(R1, R0);
718: }
719: } else {
720: XOR(R0, R0);
721: }
722: MOVLSG(CalcDispL(GPR.r[_Rd_]));
723: }
724:
725: void recSRA() {
726: // Rd = Rt >> Sa
727: if (!_Rd_) return;
728:
729: if (_Rt_) {
730: MOVLLG(CalcDispL(GPR.r[_Rt_]));
731: if (_Sa_) {
732: MOVI(-(_Sa_), R1);
733: SHAD(R1, R0);
734: }
735: } else {
736: XOR(R0, R0);
737: }
738: MOVLSG(CalcDispL(GPR.r[_Rd_]));
739: }
740:
741: //REC_FUNC(SLLV);
742: //REC_FUNC(SRLV);
743: //REC_FUNC(SRAV);
744:
745: void recSLLV() {
746: // Rd = Rt << Rs
747: if (!_Rd_) return;
748:
749: if (_Rt_) {
750: MOVLLG(CalcDispL(GPR.r[_Rt_]));
751: if (_Rs_) {
752: MOV(R0, R1);
753: MOVLLG(CalcDispL(GPR.r[_Rs_]));
754: ANDI(0x1f);
755: SHLD(R0, R1);
756: MOV(R1, R0);
757: }
758: } else {
759: XOR(R0, R0);
760: }
761: MOVLSG(CalcDispL(GPR.r[_Rd_]));
762: }
763:
764: void recSRLV() {
765: // Rd = Rt >> Rs
766: if (!_Rd_) return;
767:
768: if (_Rt_) {
769: MOVLLG(CalcDispL(GPR.r[_Rt_]));
770: if (_Rs_) {
771: MOV(R0, R1);
772: MOVLLG(CalcDispL(GPR.r[_Rs_]));
773: ANDI(0x1f);
774: NEG(R0, R0);
775: SHLD(R0, R1);
776: MOV(R1, R0);
777: }
778: } else {
779: XOR(R0, R0);
780: }
781: MOVLSG(CalcDispL(GPR.r[_Rd_]));
782: }
783:
784: void recSRAV() {
785: // Rd = Rt >> Rs
786: if (!_Rd_) return;
787:
788: if (_Rt_) {
789: MOVLLG(CalcDispL(GPR.r[_Rt_]));
790: if (_Rs_) {
791: MOV(R0, R1);
792: MOVLLG(CalcDispL(GPR.r[_Rs_]));
793: ANDI(0x1f);
794: NEG(R0, R0);
795: SHAD(R0, R1);
796: MOV(R1, R0);
797: }
798: } else {
799: XOR(R0, R0);
800: }
801: MOVLSG(CalcDispL(GPR.r[_Rd_]));
802: }
803:
804: //REC_SYS(SYSCALL);
805: //REC_SYS(BREAK);
806:
807: void recSYSCALL() {
808: LoadImmediate32(pc - 4, R0);
809: MOVLSG(CalcDispL(pc));
810: LoadImmediate32(branch == 1 ? 1 : 0, R5);
811: MOVI(0x20, R4);
812: CALLFunc ((u32)psxException);
813: if (!branch) branch = 2;
814: }
815:
816: void recBREAK() {
817: LoadImmediate32(pc - 4, R0);
818: MOVLSG(CalcDispL(pc));
819: LoadImmediate32(branch == 1 ? 1 : 0, R5);
820: MOVI(0x40, R4);
821: CALLFunc ((u32)psxException);
822: if (!branch) branch = 2;
823: }
824:
825: /*
826: REC_FUNC(MFHI);
827: REC_FUNC(MTHI);
828: REC_FUNC(MFLO);
829: REC_FUNC(MTLO);
830: */
831: void recMFHI() {
832: // Rd = Hi
833: if (!_Rd_) return;
834:
835: MOVLLG(CalcDispL(GPR.n.hi)); // Load reg into R0
836: MOVLSG(CalcDispL(GPR.r[_Rd_]));
837: }
838:
839: void recMTHI() {
840: // Hi = Rs
841:
842: MOVLLG(CalcDispL(GPR.r[_Rs_]));
843: MOVLSG(CalcDispL(GPR.n.hi));
844: }
845:
846: void recMFLO() {
847: // Rd = Lo
848: if (!_Rd_) return;
849:
850: MOVLLG(CalcDispL(GPR.n.lo)); // Load reg into R0
851: MOVLSG(CalcDispL(GPR.r[_Rd_]));
852: }
853:
854: void recMTLO() {
855: // Lo = Rs
856:
857: MOVLLG(CalcDispL(GPR.r[_Rs_]));
858: MOVLSG(CalcDispL(GPR.n.lo));
859: }
860:
861: //REC_BRANCH(J);
862: //REC_BRANCH(JR);
863: //REC_BRANCH(JAL);
864: //REC_BRANCH(JALR);
865: //REC_BRANCH(BLTZ);
866: //REC_BRANCH(BGTZ);
867: //REC_BRANCH(BLTZAL);
868: //REC_BRANCH(BGEZAL);
869: //REC_BRANCH(BNE);
870: //REC_BRANCH(BEQ);
871: //REC_BRANCH(BLEZ);
872: //REC_BRANCH(BGEZ);
873:
874: void recBLTZ() {
875: // Branch if Rs < 0
876:
877: MOVI(0, R1);
878: MOVLLG(CalcDispL(GPR.r[_Rs_]));
879: CMPGT(R0, R1);
880: j8Ptr[0] = BT(0);
881: LoadImmediate32(pc + 4, R8);
882: j16Ptr[0] = BRA(0);
883: NOP ();
884:
885: shSetBx(j8Ptr[0]);
886: LoadImmediate32((_Imm_ * 4 + pc), R8);
887:
888: shSetBRA(j16Ptr[0]);
889: SetBranch();
890: }
891:
892: void recBGEZ() {
893: // Branch if Rs >= 0
894:
895: MOVI(0, R1);
896: MOVLLG(CalcDispL(GPR.r[_Rs_]));
897: CMPGT(R0, R1);
898: j8Ptr[0] = BF(0);
899: LoadImmediate32(pc + 4, R8);
900: j16Ptr[0] = BRA(0);
901: NOP ();
902:
903: shSetBx(j8Ptr[0]);
904: LoadImmediate32((_Imm_ * 4 + pc), R8);
905:
906: shSetBRA(j16Ptr[0]);
907: SetBranch();
908: }
909:
910: void recBLTZAL() {
911: // Branch if Rs < 0
912:
913: MOVI(0, R1);
914: MOVLLG(CalcDispL(GPR.r[_Rs_]));
915: CMPGT(R0, R1);
916: j8Ptr[0] = BT(0);
917: LoadImmediate32(pc + 4, R8);
918: j16Ptr[0] = BRA(0);
919: NOP ();
920:
921: shSetBx(j8Ptr[0]);
922: LoadImmediate32(pc + 4, R0);
923: LoadImmediate32((_Imm_ * 4 + pc), R8);
924: MOVLSG(CalcDispL(GPR.r[31]));
925:
926: shSetBRA(j16Ptr[0]);
927: SetBranch();
928: }
929:
930: void recBGEZAL() {
931: // Branch if Rs >= 0
932:
933: MOVI(0, R1);
934: MOVLLG(CalcDispL(GPR.r[_Rs_]));
935: CMPGT(R0, R1);
936: j8Ptr[0] = BF(0);
937: LoadImmediate32(pc + 4, R8);
938: j16Ptr[0] = BRA(0);
939: NOP ();
940:
941: shSetBx(j8Ptr[0]);
942: LoadImmediate32(pc + 4, R0);
943: LoadImmediate32((_Imm_ * 4 + pc), R8);
944: MOVLSG(CalcDispL(GPR.r[31]));
945:
946: shSetBRA(j16Ptr[0]);
947: SetBranch();
948: }
949:
950: void recJ() {
951: // j target
952:
953: LoadImmediate32(_Target_ * 4 + (pc & 0xf0000000), R8);
954: SetBranch();
955: }
956:
957: void recJR() {
958: // jr Rs
959:
960: MOVLLG(CalcDispL(GPR.r[_Rs_]));
961: MOV(R0, R8);
962: SetBranch();
963: }
964:
965: void recJALR() {
966: // jalr Rs
967:
968: MOVLLG(CalcDispL(GPR.r[_Rs_]));
969: MOV(R0, R8);
970: if (_Rd_) {
971: LoadImmediate32(pc + 4, R0);
972: MOVLSG(CalcDispL(GPR.r[_Rd_]));
973: }
974: SetBranch();
975: }
976:
977: void recJAL() {
978: // jal target
979:
980: LoadImmediate32(_Target_ * 4 + (pc & 0xf0000000), R8);
981: LoadImmediate32(pc + 4, R0);
982: MOVLSG(CalcDispL(GPR.r[31]));
983: SetBranch();
984: }
985:
986: void recBEQ() {
987: // Branch if Rs == Rt
988:
989: MOVLLG(CalcDispL(GPR.r[_Rs_]));
990: MOV(R0, R1);
991: MOVLLG(CalcDispL(GPR.r[_Rt_]));
992: CMPEQ(R0, R1);
993: j8Ptr[0] = BT(0);
994: LoadImmediate32(pc + 4, R8);
995: j16Ptr[0] = BRA(0);
996: NOP ();
997:
998: shSetBx(j8Ptr[0]);
999: LoadImmediate32((_Imm_ * 4 + pc), R8);
1000:
1001: shSetBRA(j16Ptr[0]);
1002: SetBranch();
1003: }
1004:
1005: void recBNE() {
1006: // Branch if Rs != Rt
1007:
1008: MOVLLG(CalcDispL(GPR.r[_Rs_]));
1009: MOV(R0, R1);
1010: MOVLLG(CalcDispL(GPR.r[_Rt_]));
1011: CMPEQ(R0, R1);
1012: j8Ptr[0] = BF(0);
1013: LoadImmediate32(pc + 4, R8);
1014: j16Ptr[0] = BRA(0);
1015: NOP ();
1016:
1017: shSetBx(j8Ptr[0]);
1018: LoadImmediate32((_Imm_ * 4 + pc), R8);
1019:
1020: shSetBRA(j16Ptr[0]);
1021: SetBranch();
1022: }
1023:
1024: void recBLEZ() {
1025: // Branch if Rs <= 0
1026:
1027: MOVI(0, R1);
1028: MOVLLG(CalcDispL(GPR.r[_Rs_]));
1029: CMPGE(R0, R1);
1030: j8Ptr[0] = BT(0);
1031: LoadImmediate32(pc + 4, R8);
1032: j16Ptr[0] = BRA(0);
1033: NOP ();
1034:
1035: shSetBx(j8Ptr[0]);
1036: LoadImmediate32((_Imm_ * 4 + pc), R8);
1037:
1038: shSetBRA(j16Ptr[0]);
1039: SetBranch();
1040: }
1041:
1042: void recBGTZ() {
1043: // Branch if Rs > 0
1044:
1045: MOVI(0, R1);
1046: MOVLLG(CalcDispL(GPR.r[_Rs_]));
1047: CMPGE(R0, R1);
1048: j8Ptr[0] = BF(0);
1049: LoadImmediate32(pc + 4, R8);
1050: j16Ptr[0] = BRA(0);
1051: NOP ();
1052:
1053: shSetBx(j8Ptr[0]);
1054: LoadImmediate32((_Imm_ * 4 + pc), R8);
1055:
1056: shSetBRA(j16Ptr[0]);
1057: SetBranch();
1058: }
1059:
1060: //REC_FUNC(MFC0);
1061: //REC_FUNC(MTC0);
1062: //REC_FUNC(CFC0);
1063: //REC_FUNC(CTC0);
1064: //REC_FUNC(RFE);
1065:
1066: void recMFC0() {
1067: // Rt = Cop0->Rd
1068: if (!_Rt_) return;
1069:
1070: MOVLLG(CalcDispL(CP0.r[_Rd_])); // Load reg into R0
1071: MOVLSG(CalcDispL(GPR.r[_Rt_]));
1072: }
1073:
1074: void recCFC0() {
1075: // Rt = Cop0->Rd
1076: if (!_Rt_) return;
1077:
1078: MOVLLG(CalcDispL(CP0.r[_Rd_])); // Load reg into R0
1079: MOVLSG(CalcDispL(GPR.r[_Rt_]));
1080: }
1081:
1082: void recMTC0() {
1083: // Cop0->Rd = Rt
1084:
1085: MOVLLG(CalcDispL(GPR.r[_Rt_]));
1086: MOVLSG(CalcDispL(CP0.r[_Rd_]));
1087: }
1088:
1089: void recCTC0() {
1090: // Cop0->Rd = Rt
1091:
1092: MOVLLG(CalcDispL(GPR.r[_Rt_]));
1093: MOVLSG(CalcDispL(CP0.r[_Rd_]));
1094: }
1095:
1096: void recRFE() {
1097: MOVI(0xf0, R2);
1098: MOVLLG(CalcDispL(CP0.n.Status));
1099: AND(R0, R2);
1100: ANDI(0x3c);
1101: SHLR2(R0);
1102: OR(R2, R0);
1103: MOVLSG(CalcDispL(CP0.n.Status));
1104: }
1105:
1106: #define CP2_FUNC(f) \
1107: void gte##f(); \
1108: void rec##f() { \
1109: LoadImmediate32(psxRegs.code, R0); \
1110: MOVLSG(CalcDispL(code)); \
1111: LoadImmediate32(pc, R0); \
1112: MOVLSG(CalcDispL(pc)); \
1113: CALLFunc ((u32)gte##f); \
1114: }
1115:
1116: CP2_FUNC(MFC2);
1117: CP2_FUNC(MTC2);
1118: //CP2_FUNC(CFC2);
1119: //CP2_FUNC(CTC2);
1120: CP2_FUNC(LWC2);
1121: CP2_FUNC(SWC2);
1122:
1123: CP2_FUNC(RTPS);
1124: CP2_FUNC(OP);
1125: //CP2_FUNC(NCLIP);
1126: CP2_FUNC(DPCS);
1127: CP2_FUNC(INTPL);
1128: //CP2_FUNC(MVMVA);
1129: CP2_FUNC(NCDS);
1130: CP2_FUNC(NCDT);
1131: CP2_FUNC(CDP);
1132: CP2_FUNC(NCCS);
1133: CP2_FUNC(CC);
1134: CP2_FUNC(NCS);
1135: CP2_FUNC(NCT);
1136: CP2_FUNC(SQR);
1137: CP2_FUNC(DCPL);
1138: CP2_FUNC(DPCT);
1139: CP2_FUNC(AVSZ3);
1140: CP2_FUNC(AVSZ4);
1141: CP2_FUNC(RTPT);
1142: CP2_FUNC(GPF);
1143: CP2_FUNC(GPL);
1144: CP2_FUNC(NCCT);
1145:
1146: void recNCLIP() {
1147: MOVI(0, R0);
1148: MOVLSG(CalcDispL(CP2C.r[31]));
1149:
1150: LoadImmediate32((u32)psxRegs.CP2D.r, R4);
1151: CALLFunc((u32)asmNCLIP);
1152: }
1153:
1154:
1155: void recMVMVA() {
1156:
1157: switch (psxRegs.code & 0x18000) {
1158: case 0x00000: // VX0
1159: LoadImmediate32((u32)&psxRegs.CP2D.r[0], R4);
1160: LoadImmediate32((u32)ir, R5);
1161: CALLFunc((u32)asmLoadVec);
1162: break;
1163: case 0x08000: // VX1
1164: LoadImmediate32((u32)&psxRegs.CP2D.r[2], R4);
1165: LoadImmediate32((u32)ir, R5);
1166: CALLFunc((u32)asmLoadVec);
1167: break;
1168: case 0x10000: // VX2
1169: LoadImmediate32((u32)&psxRegs.CP2D.r[4], R4);
1170: LoadImmediate32((u32)ir, R5);
1171: CALLFunc((u32)asmLoadVec);
1172: break;
1173: case 0x18000: // IR1
1174: LoadImmediate32((u32)&psxRegs.CP2D.r[9], R4);
1175: LoadImmediate32((u32)ir, R5);
1176: CALLFunc((u32)asmLoad16);
1177: break;
1178: }
1179:
1180: switch (psxRegs.code & 0x60000) {
1181: case 0x00000:
1182: LoadImmediate32((u32)rMatrix, R4);
1183: break;
1184: case 0x20000:
1185: LoadImmediate32((u32)lMatrix, R4);
1186: break;
1187: case 0x40000:
1188: LoadImmediate32((u32)cMatrix, R4);
1189: break;
1190: case 0x60000:
1191: LoadImmediate32((u32)rMatrix, R4);
1192: break;
1193: }
1194:
1195: switch (psxRegs.code & 0x06000) {
1196: case 0x00000:
1197: LoadImmediate32((u32)trVector, R5);
1198: CALLFunc((u32)mat_vec_load);
1199: LoadImmediate32((u32)&ir[3], R4);
1200: LoadImmediate32((u32)0x45800000, R5); // 4096.0
1201: MOVLS(R5, R4);
1202: break;
1203: case 0x02000:
1204: LoadImmediate32((u32)bkVector, R5);
1205: CALLFunc((u32)mat_vec_load);
1206: LoadImmediate32((u32)&ir[3], R4);
1207: LoadImmediate32((u32)0x45800000, R5); // 4096.0
1208: MOVLS(R5, R4);
1209: break;
1210: case 0x04000:
1211: LoadImmediate32((u32)fcVector, R5);
1212: CALLFunc((u32)mat_vec_load);
1213: LoadImmediate32((u32)&ir[3], R4);
1214: LoadImmediate32((u32)0x45800000, R5); // 4096.0
1215: MOVLS(R5, R4);
1216: break;
1217: case 0x06000:
1218: CALLFunc((u32)mat_zero_load);
1219: LoadImmediate32((u32)&ir[3], R4);
1220: LoadImmediate32((u32)0, R5); // 0.0
1221: MOVLS(R5, R4);
1222: break;
1223: }
1224:
1225:
1226: if (!(psxRegs.code & 0x80000)) {
1227: // ir[0] *= 4096.0; ir[1] *= 4096.0; ir[2] *= 4096.0;
1228: LoadImmediate32((u32)ir, R1);
1229: LoadImmediate32(4096, R2);
1230: LDSFPUL(R2);
1231: FLOAT(FR3);
1232: FMOV_RESTORE(R1, FR0);
1233: FMUL(FR3, FR0);
1234: FMOV_RESTORE(R1, FR1);
1235: FMUL(FR3, FR1);
1236: FMOV_RESTORE(R1, FR2);
1237: FMUL(FR3, FR2);
1238: FMOV_SAVE(R1, FR2);
1239: FMOV_SAVE(R1, FR1);
1240: FMOV_SAVE(R1, FR0);
1241: }
1242:
1243: // gteFLAG = asmTransformVector((u32)ir, (u32)mac, psxRegs.code & 0x400);
1244: LoadImmediate32((u32)ir, R4);
1245: LoadImmediate32((u32)mac, R5);
1246: LoadImmediate32((u32)(psxRegs.code & 0x400), R6);
1247: CALLFunc((u32)asmTransformVector);
1248: MOVLSG(CalcDispL(CP2C.r[31])); // gteFLAG
1249:
1250: // asmStore32(ir, >eIR1);
1251: LoadImmediate32((u32)ir, R4);
1252: LoadImmediate32((u32)&psxRegs.CP2D.r[9], R5);
1253: CALLFunc((u32)asmStore32);
1254:
1255: // asmStore32(mac, >eMAC1);
1256: LoadImmediate32((u32)mac, R4);
1257: LoadImmediate32((u32)&psxRegs.CP2D.r[25], R5);
1258: CALLFunc((u32)asmStore32);
1259:
1260: // SUM_FLAG;
1261: }
1262:
1263: void recCFC2() {
1264: if (!_Rt_) return;
1265: MOVLLG(CalcDispL(CP2C.r[_Rd_]));
1266: MOVLSG(CalcDispL(GPR.r[_Rt_]));
1267: // psxRegs.GPR.r[_Rt_] = psxRegs.CP2C.r[_Rd_];
1268: }
1269:
1270: /* Loads an element into matrix mx: lower word at pos _p1, upper word at pos _p2 */
1271: #define _LOAD_MATRIX(mx, _p1, _p2) { \
1272: LoadImmediate32((u32)mx##Matrix, R5); \
1273: MOVI(_p1*4, R6); \
1274: LoadImmediate32((u32)LoadMatrixElement, R1); \
1275: JSR(R1); \
1276: MOVI(_p2*4, R7); \
1277: }
1278:
1279: void recCTC2() {
1280: MOVLLG(CalcDispL(GPR.r[_Rt_]));
1281: MOVLSG(CalcDispL(CP2C.r[_Rd_]));
1282: // psxRegs.CP2C.r[_Rd_] = psxRegs.GPR.r[_Rt_];
1283: // printf("Store to CP2C %d at %08x\n", _Rd_, (u32)x86Ptr);
1284: switch(_Rd_) {
1285: case 0:
1286: MOV(R0, R4); _LOAD_MATRIX(r, 0, 4); break;
1287: case 1:
1288: MOV(R0, R4); _LOAD_MATRIX(r, 8, 1); break;
1289: case 2:
1290: MOV(R0, R4); _LOAD_MATRIX(r, 5, 9); break;
1291: case 3:
1292: MOV(R0, R4); _LOAD_MATRIX(r, 2, 6); break;
1293: case 4: // clear upper 16 Bit
1294: EXTUW(R0, R4); _LOAD_MATRIX(r, 10, 3); break;
1295:
1296: case 5: {
1297: LoadImmediate32((u32)&(trVector[0]), R1);
1298: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1299: } break;
1300:
1301: case 6: {
1302: LoadImmediate32((u32)&(trVector[1]), R1);
1303: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1304: } break;
1305:
1306: case 7: {
1307: LoadImmediate32((u32)&(trVector[2]), R1);
1308: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1309: } break;
1310:
1311: case 8:
1312: MOV(R0, R4); _LOAD_MATRIX(l, 0, 4); break;
1313: case 9:
1314: MOV(R0, R4); _LOAD_MATRIX(l, 8, 1); break;
1315: case 10:
1316: MOV(R0, R4); _LOAD_MATRIX(l, 5, 9); break;
1317: case 11:
1318: MOV(R0, R4); _LOAD_MATRIX(l, 2, 6); break;
1319: case 12: // clear upper 16 Bit
1320: EXTUW(R0, R4); _LOAD_MATRIX(l, 10, 3); break;
1321:
1322: case 13: {
1323: LoadImmediate32((u32)&(bkVector[0]), R1);
1324: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1325: } break;
1326:
1327: case 14: {
1328: LoadImmediate32((u32)&(bkVector[1]), R1);
1329: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1330: } break;
1331:
1332: case 15: {
1333: LoadImmediate32((u32)&(bkVector[2]), R1);
1334: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1335: } break;
1336:
1337: case 16:
1338: MOV(R0, R4); _LOAD_MATRIX(c, 0, 4); break;
1339: case 17:
1340: MOV(R0, R4); _LOAD_MATRIX(c, 8, 1); break;
1341: case 18:
1342: MOV(R0, R4); _LOAD_MATRIX(c, 5, 9); break;
1343: case 19:
1344: MOV(R0, R4); _LOAD_MATRIX(c, 2, 6); break;
1345: case 20: // clear upper 16 Bit
1346: EXTUW(R0, R4); _LOAD_MATRIX(c, 10, 3); break;
1347:
1348: case 21: {
1349: LoadImmediate32((u32)&(fcVector[0]), R1);
1350: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1351: } break;
1352: case 22: {
1353: LoadImmediate32((u32)&(fcVector[1]), R1);
1354: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1355: } break;
1356: case 23: {
1357: LoadImmediate32((u32)&(fcVector[2]), R1);
1358: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1359: } break;
1360: case 24: { // OFX
1361: LoadImmediate32((u32)&(control[0]), R1);
1362: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1363: } break;
1364: case 25: { // OFY
1365: LoadImmediate32((u32)&(control[1]), R1);
1366: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1367: } break;
1368: case 26: { // H
1369: LoadImmediate32((u32)&(control[2]), R1);
1370: EXTUW(R0, R0);
1371: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1372: } break;
1373: case 27: { // DQA
1374: LoadImmediate32((u32)&(control[3]), R1);
1375: EXTSW(R0, R0);
1376: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1377: } break;
1378: case 28: { // DQB
1379: LoadImmediate32((u32)&(control[4]), R1);
1380: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1381: } break;
1382: case 29: { // ZSF3
1383: LoadImmediate32((u32)&(control[5]), R1);
1384: EXTSW(R0, R0);
1385: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1386: } break;
1387: case 30: { // ZSF4
1388: LoadImmediate32((u32)&(control[6]), R1);
1389: EXTSW(R0, R0);
1390: LDSFPUL(R0); FLOAT(FR0); FMOV_STORE(FR0, R1);
1391: } break;
1392: }
1393: }
1394:
1395:
1396: static void recHLE() {
1397: CALLFunc((u32)psxHLEt[psxRegs.code & 0xff]);
1398: branch = 2;
1399: }
1400:
1401: //
1402:
1403: static void (*recBSC[64])() = {
1404: recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ,
1405: recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI ,
1406: recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL,
1407: recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL,
1408: recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL,
1409: recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL,
1410: recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL,
1411: recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL
1412: };
1413:
1414: static void (*recSPC[64])() = {
1415: recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV,
1416: recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL,
1417: recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL,
1418: recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL,
1419: recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR ,
1420: recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL,
1421: recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL,
1422: recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL
1423: };
1424:
1425: static void (*recREG[32])() = {
1426: recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1427: recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1428: recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1429: recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
1430: };
1431:
1432: static void (*recCP0[32])() = {
1433: recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL,
1434: recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1435: recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1436: recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
1437: };
1438:
1439: static void (*recCP2[64])() = {
1440: recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00
1441: recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08
1442: recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10
1443: recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18
1444: recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20
1445: recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28
1446: recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30
1447: recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38
1448: };
1449:
1450: static void (*recCP2BSC[32])() = {
1451: recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL,
1452: recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1453: recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
1454: recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL
1455: };
1456:
1457: static void recRecompile() {
1458: /* if x86Ptr reached the mem limit reset whole mem */
1459: if (((u32)x86Ptr - ((u32)recMem|0xa0000000)) >= (RECMEM_SIZE - 0x10000))
1460: recReset();
1461:
1462: PC_REC32(psxRegs.pc) = (u32)x86Ptr & ~0x20000000; // Clear non-cached bit
1463: pc = psxRegs.pc;
1464:
1465: immCount = 0;
1466:
1467: STSMPR(R15); // Save Return Address
1468: STCMGBR(R15);
1469: MOVLM(R8, R15);
1470:
1471: LoadImmediate32((u32)&psxRegs, R1);
1472: LDCGBR(R1); // Load GBR with addr of psxRegs
1473:
1474: for (count=0; count<500;) {
1475: char *p;
1476:
1477: p = (char *)PSXM(pc);
1478: if (p == NULL) recError();
1479: psxRegs.code = *(u32 *)p;
1480:
1481: pc+=4; count++;
1482: recBSC[psxRegs.code>>26]();
1483:
1484: if (branch) {
1485: break;
1486: }
1487: UpdateImmediate32(0);
1488: }
1489:
1490: if (!branch) {
1491: LoadImmediate32(pc, R0);
1492: MOVLSG(CalcDispL(pc));
1493: }
1494:
1495: /* store cycle */
1496: LoadImmediate32(count, R1);
1497: MOVLLG(CalcDispL(cycle));
1498: ADD(R1, R0);
1499: MOVLSG(CalcDispL(cycle));
1500:
1501: branch = 0;
1502:
1503: MOVLP(R15, R8);
1504: LDCMGBR(R15);
1505: LDSMPR(R15);
1506: RET();
1507: NOP();
1508: UpdateImmediate32(1);
1509: Align32();
1510: }
1511:
1512: R3000Acpu psxRec = {
1513: recInit,
1514: recReset,
1515: recExecute,
1516: recExecuteBlock,
1517: recClear,
1518: recShutdown
1519: };
1520: /* arch-tag: Matthew Dempsky Wed Oct 15 10:35:07 CST 2003 (sh4/sR3000A.c)
1521: */
1522:
Html form generated by Xrefactory version 1.6.4 on Fri Dec 12 20:52:56 2003
Trial version.