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, &gteIR1);
1251:         LoadImmediate32((u32)ir, R4);
1252:         LoadImmediate32((u32)&psxRegs.CP2D.r[9], R5);
1253:         CALLFunc((u32)asmStore32);
1254: 
1255:         // asmStore32(mac, &gteMAC1); 
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.