From d38e80ee04afe582e70150d3884e56c05f3fd7a8 Mon Sep 17 00:00:00 2001 From: pixel Date: Sat, 27 Nov 2004 21:44:44 +0000 Subject: Large dos2unix commit... --- PcsxSrc/ix86/iR3000A.c | 2472 ++++++++++++++++++++++++------------------------ 1 file changed, 1236 insertions(+), 1236 deletions(-) (limited to 'PcsxSrc/ix86/iR3000A.c') diff --git a/PcsxSrc/ix86/iR3000A.c b/PcsxSrc/ix86/iR3000A.c index c6ff128..2586ca0 100644 --- a/PcsxSrc/ix86/iR3000A.c +++ b/PcsxSrc/ix86/iR3000A.c @@ -1,1236 +1,1236 @@ -/* Pcsx - Pc Psx Emulator - * Copyright (C) 1999-2002 Pcsx Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __WIN32__ -#pragma warning(disable:4244) -#pragma warning(disable:4761) -#endif -#include -#include -#include - -#include "PsxCommon.h" -#include "ix86.h" - -static u32 *recLUT; - -#define PC_REC(x) (recLUT[x >> 16] + (x & 0xffff)) -#define PC_REC8(x) (*(u8 *)PC_REC(x)) -#define PC_REC16(x) (*(u16*)PC_REC(x)) -#define PC_REC32(x) (*(u32*)PC_REC(x)) - -#define RECMEM_SIZE (8*1024*1024) - -static char *recMem; /* the recompiled blocks will be here */ -static char *recRAM; /* and the ptr to the blocks here */ -static char *recROM; /* and here */ - -static u32 pc; /* recompiler pc */ -static int count; /* recompiler intruction count */ -static int branch; /* set for branch */ -static u32 target; /* branch target */ - -static void (*recBSC[64])(); -static void (*recSPC[64])(); -static void (*recREG[32])(); -static void (*recCP0[32])(); -static void (*recCP2[64])(); -static void (*recCP2BSC[32])(); - -/* set a pending branch */ -#define SetBranch() { \ - branch = 1; \ - psxRegs.code = PSXMu32(pc); \ - pc+=4; count++; \ - recBSC[psxRegs.code>>26](); \ - \ - MOV32MtoR(EAX, (u32)&target); \ - MOV32RtoM((u32)&psxRegs.pc, EAX); \ - CALLFunc((u32)psxBranchTest); \ -} - -#define REC_FUNC(f) \ -void psx##f(); \ -static void rec##f() { \ - MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ - MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ - CALLFunc((u32)psx##f); \ -/* branch = 2; */\ -} - -#define REC_SYS(f) \ -void psx##f(); \ -static void rec##f() { \ - MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ - MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ - CALLFunc((u32)psx##f); \ - branch = 2; \ -} - -#define REC_BRANCH(f) \ -void psx##f(); \ -static void rec##f() { \ - MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ - MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ - CALLFunc((u32)psx##f); \ - branch = 2; \ - count++; \ -} - -static void recRecompile(); - -static int recInit() { - int i; - - recLUT = (u32*) malloc(0x010000 * 4); - - recMem = (char*) malloc(RECMEM_SIZE); - recRAM = (char*) malloc(0x200000); - recROM = (char*) malloc(0x080000); - if (recRAM == NULL || recROM == NULL || recMem == NULL || recLUT == NULL) { - SysMessage("Error allocating memory"); return -1; - } - - for (i=0; i<0x80; i++) recLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16]; - memcpy(recLUT + 0x8000, recLUT, 0x80 * 4); - memcpy(recLUT + 0xa000, recLUT, 0x80 * 4); - - for (i=0; i<0x08; i++) recLUT[i + 0xbfc0] = (u32)&recROM[i << 16]; - - return 0; -} - -static void recReset() { - memset(recRAM, 0, 0x200000); - memset(recROM, 0, 0x080000); - - x86Init(recMem); - branch = 0; -} - -static void recShutdown() { - if (recMem == NULL) return; - free(recLUT); - free(recMem); - free(recRAM); - free(recROM); -} - -static void recError() { - SysReset(); - ClosePlugins(); - SysMessage("Unrecoverable error while running recompiler\n"); - SysRunGui(); -} - -#define execute() { \ - void (**recFunc)(); \ - char *p; \ - \ - p = (char*)PC_REC(psxRegs.pc); \ - if (p != NULL) recFunc = (void (**)()) (u32)p; \ - else { recError(); return; } \ - \ - if (*recFunc == 0) { \ - recRecompile(); \ - } \ - (*recFunc)(); \ -} - -static void DumpRegs() { - int i, j; - - printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle); - for (i=0; i<4; i++) { - for (j=0; j<8; j++) - printf("%lx ", psxRegs.GPR.r[j*i]); - printf("\n"); - } -} - -static void recExecuteBios() { - while (psxRegs.pc != 0x80030000) { - execute(); - } -} - -static void recExecute() { - for (;;) execute(); -} - -static void recExecuteBlock() { - execute(); -} - -static void recClear(u32 Addr, u32 Size) { - memset((void*)PC_REC(Addr), 0, Size * 4); -} - -static void recNULL() { -// SysMessage("recUNK: %8.8x\n", psxRegs.code); -} - -/********************************************************* -* goes to opcodes tables... * -* Format: table[something....] * -*********************************************************/ - -//REC_SYS(SPECIAL); -static void recSPECIAL() { - recSPC[_Funct_](); -} - -static void recREGIMM() { - recREG[_Rt_](); -} - -static void recCOP0() { - recCP0[_Rs_](); -} - -//REC_SYS(COP2); -static void recCOP2() { - recCP2[_Funct_](); -} - -static void recBASIC() { - recCP2BSC[_Rs_](); -} - -//end of Tables opcodes... - -/********************************************************* -* Arithmetic with immediate operand * -* Format: OP rt, rs, immediate * -*********************************************************/ -/* -REC_FUNC(ADDI); -REC_FUNC(ADDIU); -REC_FUNC(ANDI); -REC_FUNC(ORI); -REC_FUNC(XORI); -REC_FUNC(SLTI); -REC_FUNC(SLTIU); -#if 0*/ -static void recADDIU() { -// Rt = Rs + Im - if (!_Rt_) return; - - if (_Rs_) { - if (_Rs_ == _Rt_) { - ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); - } else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - } else { - MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); - } -} - -static void recADDI() { -// Rt = Rs + Im - recADDIU(); -} - -static void recSLTI() { -// Rt = Rs < Im (signed) - if (!_Rt_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - CMP32ItoR(EAX, _Imm_); - SETL8R (EAX); - AND32ItoR(EAX, 0xff); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); -} - -static void recSLTIU() { -// Rt = Rs < Im (unsigned) - if (!_Rt_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - CMP32ItoR(EAX, _Imm_); - SETB8R (EAX); - AND32ItoR(EAX, 0xff); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); -} - -static void recANDI() { -// Rt = Rs And Im - if (!_Rt_) return; - - if (_Rs_ && _ImmU_) { - if (_Rs_ == _Rt_) { - AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); - } else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - AND32ItoR(EAX, _ImmU_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - } else { - XOR32RtoR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } -} - -static void recORI() { -// Rt = Rs Or Im - if (!_Rt_) return; - - if (_Rs_) { - if (_Rs_ == _Rt_) { - OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); - } else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_ImmU_) OR32ItoR (EAX, _ImmU_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - } else { - MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); - } -} - -static void recXORI() { -// Rt = Rs Xor Im - if (!_Rt_) return; - - if (_Rs_) { - if (_Rs_ == _Rt_) { - XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); - } else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - XOR32ItoR(EAX, _ImmU_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - } else { - MOV32ItoR(EAX, _ImmU_ ^ 0); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } -} -//#endif -//end of * Arithmetic with immediate operand - -/********************************************************* -* Load higher 16 bits of the first word in GPR with imm * -* Format: OP rt, immediate * -*********************************************************/ -/*REC_FUNC(LUI); -#if 0*/ -static void recLUI() { -// Rt = Imm << 16 - if (!_Rt_) return; - - MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], psxRegs.code << 16); -} -//#endif -//End of Load Higher ..... - - -/********************************************************* -* Register arithmetic * -* Format: OP rd, rs, rt * -*********************************************************/ -/* -REC_FUNC(ADD); -REC_FUNC(ADDU); -REC_FUNC(SUB); -REC_FUNC(SUBU); -REC_FUNC(AND); -REC_FUNC(OR); -REC_FUNC(XOR); -REC_FUNC(NOR); -REC_FUNC(SLT); -REC_FUNC(SLTU); - -#if 0*/ -static void recADDU() { -// Rd = Rs + Rt - if (!_Rd_) return; - - if (_Rs_ && _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - } else if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else { - XOR32RtoR(EAX, EAX); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recADD() { -// Rd = Rs + Rt - recADDU(); -} - -static void recSUBU() { -// Rd = Rs - Rt - if (!_Rd_) return; - - if (_Rs_ || _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else { - XOR32RtoR(EAX, EAX); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recSUB() { -// Rd = Rs - Rt - recSUBU(); -} - -static void recAND() { -// Rd = Rs And Rt - if (!_Rd_) return; - - if (_Rs_ && _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else { - XOR32RtoR(EAX, EAX); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recOR() { -// Rd = Rs Or Rt - if (!_Rd_) return; - - if (_Rs_ && _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - } else if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else { - XOR32RtoR(EAX, EAX); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recXOR() { -// Rd = Rs Xor Rt - if (!_Rd_) return; - - if (_Rs_ && _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - XOR32ItoR(EAX, 0); - } else if (_Rt_) { - XOR32RtoR(EAX, EAX); - XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - } else { - XOR32RtoR(EAX, EAX); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recNOR() { -// Rd = Rs Nor Rt - if (!_Rd_) return; - - if (_Rs_ && _Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); - NOT32R (EAX); - } else if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - NOT32R (EAX); - } else if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - NOT32R (EAX); - } else { - MOV32ItoR(EAX, ~0); - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recSLT() { -// Rd = Rs < Rt (signed) - if (!_Rd_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - SETL8R (EAX); - AND32ItoR(EAX, 0xff); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recSLTU() { -// Rd = Rs < Rt (unsigned) - if (!_Rd_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - SBB32RtoR(EAX, EAX); - NEG32R (EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} -//#endif -//End of * Register arithmetic - -/********************************************************* -* Register mult/div & Register trap logic * -* Format: OP rs, rt * -*********************************************************/ - -/*REC_FUNC(MULT); -REC_FUNC(MULTU); -REC_FUNC(DIV); -REC_FUNC(DIVU); -#if 0*/ -static void recMULT() { -// Lo/Hi = Rs * Rt (signed) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]); - MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); - MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); -} - -static void recMULTU() { -// Lo/Hi = Rs * Rt (unsigned) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - MUL32M ((u32)&psxRegs.GPR.r[_Rt_]); - MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); - MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); -} - -static void recDIV() { -// Lo/Hi = Rs / Rt (signed) - - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - CMP32ItoR(ECX, 0); - j8Ptr[0] = JE8(0); - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - CDQ(); - IDIV32R (ECX); - MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); - MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); - x86SetJ8(j8Ptr[0]); -} - -static void recDIVU() { -// Lo/Hi = Rs / Rt (unsigned) - - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - CMP32ItoR(ECX, 0); - j8Ptr[0] = JE8(0); - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - XOR32RtoR(EDX, EDX); - DIV32R (ECX); - MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); - MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); - x86SetJ8(j8Ptr[0]); -} -//#endif -//End of * Register mult/div & Register trap logic - -/*REC_FUNC(LB); -REC_FUNC(LBU); -REC_FUNC(LH); -REC_FUNC(LHU); -REC_FUNC(LW); - -REC_FUNC(SB); -REC_FUNC(SH); -REC_FUNC(SW);*/ - -REC_FUNC(LWL); -REC_FUNC(LWR); -REC_FUNC(SWL); -REC_FUNC(SWR); -//#if 0 -static void recLB() { -// Rt = mem[Rs + Im] (signed) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead8); - if (_Rt_) { - MOVSX32R8toR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - ADD32ItoR(ESP, 4); -} - -static void recLBU() { -// Rt = mem[Rs + Im] (unsigned) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead8); - if (_Rt_) { - MOVZX32R8toR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - ADD32ItoR(ESP, 4); -} - -static void recLH() { -// Rt = mem[Rs + Im] (signed) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead16); - if (_Rt_) { - MOVSX32R16toR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - ADD32ItoR(ESP, 4); -} - -static void recLHU() { -// Rt = mem[Rs + Im] (unsigned) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead16); - if (_Rt_) { - MOVZX32R16toR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - ADD32ItoR(ESP, 4); -} - -static void recLW() { -// Rt = mem[Rs + Im] (unsigned) - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead32); - if (_Rt_) { - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } - ADD32ItoR(ESP, 4); -} -/* -void recLWL() { -} - -void recLWR() { -} -*/ -static void recSB() { -// mem[Rs + Im] = Rt - - PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemWrite8); - ADD32ItoR(ESP, 8); -} - -static void recSH() { -// mem[Rs + Im] = Rt - - PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemWrite16); - ADD32ItoR(ESP, 8); -} - -static void recSW() { -// mem[Rs + Im] = Rt - - PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - PUSH32R (EAX); - CALLFunc((u32)psxMemWrite32); - ADD32ItoR(ESP, 8); -} -//#endif -/* -void recSWL() { -} - -void recSWR() { -} -*/ -/*REC_FUNC(SLL); -REC_FUNC(SRL); -REC_FUNC(SRA); -#if 0*/ -static void recSLL() { -// Rd = Rt << Sa - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Sa_) SHL32ItoR(EAX, _Sa_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } else { - XOR32RtoR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } -} - -static void recSRL() { -// Rd = Rt >> Sa - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Sa_) SHR32ItoR(EAX, _Sa_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } else { - XOR32RtoR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } -} - -static void recSRA() { -// Rd = Rt >> Sa - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Sa_) SAR32ItoR(EAX, _Sa_); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } else { - XOR32RtoR(EAX, EAX); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); - } -} -//#endif - -/*REC_FUNC(SLLV); -REC_FUNC(SRLV); -REC_FUNC(SRAV); -#if 0*/ -static void recSLLV() { -// Rd = Rt << Rs - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Rs_) { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); - SHL32CLtoR(EAX); - } - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recSRLV() { -// Rd = Rt >> Rs - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Rs_) { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); - SHR32CLtoR(EAX); - } - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recSRAV() { -// Rd = Rt >> Rs - if (!_Rd_) return; - - if (_Rt_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - if (_Rs_) { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); - SAR32CLtoR(EAX); - } - } - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} -//#endif - -/*REC_SYS(SYSCALL); -REC_SYS(BREAK); - -#if 0*/ -static void recSYSCALL() { - MOV32ItoR(EAX, pc - 4); - MOV32RtoM((u32)&psxRegs.pc, EAX); - PUSH32I (branch == 1 ? 1 : 0); - PUSH32I (0x20); - CALLFunc ((u32)psxException); - ADD32ItoR(ESP, 8); - - if (!branch) branch = 2; -} - -static void recBREAK() { -} -//#endif -/* -REC_FUNC(MFHI); -REC_FUNC(MTHI); -REC_FUNC(MFLO); -REC_FUNC(MTLO); -#if 0*/ -static void recMFHI() { -// Rd = Hi - if (!_Rd_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recMTHI() { -// Hi = Rs - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX); -} - -static void recMFLO() { -// Rd = Lo - if (!_Rd_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); -} - -static void recMTLO() { -// Lo = Rs - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); -} -//#endif - -/*REC_BRANCH(J); -REC_BRANCH(JR); -REC_BRANCH(JAL); -REC_BRANCH(JALR); -REC_BRANCH(BLTZ); -REC_BRANCH(BGTZ); -REC_BRANCH(BLTZAL); -REC_BRANCH(BGEZAL); -REC_BRANCH(BNE); -REC_BRANCH(BEQ); -REC_BRANCH(BLEZ); -REC_BRANCH(BGEZ); - -#if 0*/ -static void recBLTZ() { -// Branch if Rs < 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JL8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recBGEZ() { -// Branch if Rs >= 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JGE8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recBLTZAL() { -// Branch if Rs < 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JL8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recBGEZAL() { -// Branch if Rs >= 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JGE8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recJ() { -// j target - MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); - - SetBranch(); -} - -static void recJAL() { -// jal target - - MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); - MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); - - SetBranch(); -} - -static void recJR() { -// jr Rs - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - MOV32RtoM((u32)&target, EAX); - - SetBranch(); -} - -static void recJALR() { -// jalr Rs - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - MOV32RtoM((u32)&target, EAX); - - if (_Rd_) { - MOV32ItoM((u32)&psxRegs.GPR.r[_Rd_], pc + 4); - } - - SetBranch(); -} - -static void recBEQ() { -// Branch if Rs == Rt - - if (_Rs_ == _Rt_) { - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - } else { - if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - } else { - XOR32RtoR(EAX, EAX); - } - CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - j8Ptr[0] = JE8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - } - - SetBranch(); -} - -static void recBNE() { -// Branch if Rs != Rt - - if (_Rs_) { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - } else { - XOR32RtoR(EAX, EAX); - } - CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - j8Ptr[0] = JNE8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recBLEZ() { -// Branch if Rs <= 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JLE8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} - -static void recBGTZ() { -// Branch if Rs > 0 - - CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); - j8Ptr[0] = JG8(0); - - MOV32ItoM((u32)&target, pc+4); - j8Ptr[1] = JMP8(0); - - x86SetJ8(j8Ptr[0]); - - MOV32ItoM((u32)&target, _Imm_ * 4 + pc); - - x86SetJ8(j8Ptr[1]); - - SetBranch(); -} -//#endif - -/*REC_FUNC(MFC0); -REC_FUNC(MTC0); -REC_FUNC(CFC0); -REC_FUNC(CTC0); -REC_FUNC(RFE); -#if 0*/ -static void recMFC0() { -// Rt = Cop0->Rd - if (!_Rt_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); -} - -static void recCFC0() { -// Rt = Cop0->Rd - if (!_Rt_) return; - - MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); -} - -static void recMTC0() { -// Cop0->Rd = Rt - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); -} - -static void recCTC0() { -// Cop0->Rd = Rt - - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); -} - -static void recRFE() { - MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status); - MOV32RtoR(ECX, EAX); - AND32ItoR(EAX, 0xfffffff0); - AND32ItoR(ECX, 0x3c); - SHR32ItoR(ECX, 2); - OR32RtoR (EAX, ECX); - MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX); -} -//#endif - -#define CP2_FUNC(f) \ -void gte##f(); \ -static void rec##f() { \ - MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ - MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ - CALLFunc ((u32)gte##f); \ -/* branch = 2; */\ -} - -CP2_FUNC(MFC2); -CP2_FUNC(MTC2); -CP2_FUNC(CFC2); -CP2_FUNC(CTC2); -CP2_FUNC(LWC2); -CP2_FUNC(SWC2); - -CP2_FUNC(RTPS); -CP2_FUNC(OP); -CP2_FUNC(NCLIP); -CP2_FUNC(DPCS); -CP2_FUNC(INTPL); -CP2_FUNC(MVMVA); -CP2_FUNC(NCDS); -CP2_FUNC(NCDT); -CP2_FUNC(CDP); -CP2_FUNC(NCCS); -CP2_FUNC(CC); -CP2_FUNC(NCS); -CP2_FUNC(NCT); -CP2_FUNC(SQR); -CP2_FUNC(DCPL); -CP2_FUNC(DPCT); -CP2_FUNC(AVSZ3); -CP2_FUNC(AVSZ4); -CP2_FUNC(RTPT); -CP2_FUNC(GPF); -CP2_FUNC(GPL); -CP2_FUNC(NCCT); - -static void recHLE() { - MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xff]); - CALL32R(EAX); - branch = 2; -} - -// - -static void (*recBSC[64])() = { - recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ, - recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI , - recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL, - recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL, - recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL, - recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL, - recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL, - recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL -}; - -static void (*recSPC[64])() = { - recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV, - recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL, - recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL, - recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL, - recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR , - recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL -}; - -static void (*recREG[32])() = { - recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL -}; - -static void (*recCP0[32])() = { - recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL -}; - -static void (*recCP2[64])() = { - recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00 - recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08 - recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10 - recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18 - recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20 - recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28 - recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30 - recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38 -}; - -static void (*recCP2BSC[32])() = { - recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, - recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL -}; - -static void recRecompile() { - /* if x86Ptr reached the mem limit reset whole mem */ - if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000)) - recReset(); - - PC_REC32(psxRegs.pc) = (u32)x86Ptr; - pc = psxRegs.pc; - - for (count=0; count<500;) { - char *p; - - p = (char *)PSXM(pc); - if (p == NULL) recError(); - psxRegs.code = *(u32 *)p; - - pc+=4; count++; - recBSC[psxRegs.code>>26](); - - if (branch) { - break; - } - } - - if (!branch) { - MOV32ItoM((u32)&psxRegs.pc, pc); - } - - /* store cycle */ - ADD32ItoM((u32)&psxRegs.cycle, count); - - branch = 0; - - RET(); -} - - -R3000Acpu psxRec = { - recInit, - recReset, - recExecute, - recExecuteBlock, - recClear, - recShutdown -}; +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#pragma warning(disable:4761) +#endif +#include +#include +#include + +#include "PsxCommon.h" +#include "ix86.h" + +static u32 *recLUT; + +#define PC_REC(x) (recLUT[x >> 16] + (x & 0xffff)) +#define PC_REC8(x) (*(u8 *)PC_REC(x)) +#define PC_REC16(x) (*(u16*)PC_REC(x)) +#define PC_REC32(x) (*(u32*)PC_REC(x)) + +#define RECMEM_SIZE (8*1024*1024) + +static char *recMem; /* the recompiled blocks will be here */ +static char *recRAM; /* and the ptr to the blocks here */ +static char *recROM; /* and here */ + +static u32 pc; /* recompiler pc */ +static int count; /* recompiler intruction count */ +static int branch; /* set for branch */ +static u32 target; /* branch target */ + +static void (*recBSC[64])(); +static void (*recSPC[64])(); +static void (*recREG[32])(); +static void (*recCP0[32])(); +static void (*recCP2[64])(); +static void (*recCP2BSC[32])(); + +/* set a pending branch */ +#define SetBranch() { \ + branch = 1; \ + psxRegs.code = PSXMu32(pc); \ + pc+=4; count++; \ + recBSC[psxRegs.code>>26](); \ + \ + MOV32MtoR(EAX, (u32)&target); \ + MOV32RtoM((u32)&psxRegs.pc, EAX); \ + CALLFunc((u32)psxBranchTest); \ +} + +#define REC_FUNC(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ +/* branch = 2; */\ +} + +#define REC_SYS(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ + branch = 2; \ +} + +#define REC_BRANCH(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ + branch = 2; \ + count++; \ +} + +static void recRecompile(); + +static int recInit() { + int i; + + recLUT = (u32*) malloc(0x010000 * 4); + + recMem = (char*) malloc(RECMEM_SIZE); + recRAM = (char*) malloc(0x200000); + recROM = (char*) malloc(0x080000); + if (recRAM == NULL || recROM == NULL || recMem == NULL || recLUT == NULL) { + SysMessage("Error allocating memory"); return -1; + } + + for (i=0; i<0x80; i++) recLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16]; + memcpy(recLUT + 0x8000, recLUT, 0x80 * 4); + memcpy(recLUT + 0xa000, recLUT, 0x80 * 4); + + for (i=0; i<0x08; i++) recLUT[i + 0xbfc0] = (u32)&recROM[i << 16]; + + return 0; +} + +static void recReset() { + memset(recRAM, 0, 0x200000); + memset(recROM, 0, 0x080000); + + x86Init(recMem); + branch = 0; +} + +static void recShutdown() { + if (recMem == NULL) return; + free(recLUT); + free(recMem); + free(recRAM); + free(recROM); +} + +static void recError() { + SysReset(); + ClosePlugins(); + SysMessage("Unrecoverable error while running recompiler\n"); + SysRunGui(); +} + +#define execute() { \ + void (**recFunc)(); \ + char *p; \ + \ + p = (char*)PC_REC(psxRegs.pc); \ + if (p != NULL) recFunc = (void (**)()) (u32)p; \ + else { recError(); return; } \ + \ + if (*recFunc == 0) { \ + recRecompile(); \ + } \ + (*recFunc)(); \ +} + +static void DumpRegs() { + int i, j; + + printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle); + for (i=0; i<4; i++) { + for (j=0; j<8; j++) + printf("%lx ", psxRegs.GPR.r[j*i]); + printf("\n"); + } +} + +static void recExecuteBios() { + while (psxRegs.pc != 0x80030000) { + execute(); + } +} + +static void recExecute() { + for (;;) execute(); +} + +static void recExecuteBlock() { + execute(); +} + +static void recClear(u32 Addr, u32 Size) { + memset((void*)PC_REC(Addr), 0, Size * 4); +} + +static void recNULL() { +// SysMessage("recUNK: %8.8x\n", psxRegs.code); +} + +/********************************************************* +* goes to opcodes tables... * +* Format: table[something....] * +*********************************************************/ + +//REC_SYS(SPECIAL); +static void recSPECIAL() { + recSPC[_Funct_](); +} + +static void recREGIMM() { + recREG[_Rt_](); +} + +static void recCOP0() { + recCP0[_Rs_](); +} + +//REC_SYS(COP2); +static void recCOP2() { + recCP2[_Funct_](); +} + +static void recBASIC() { + recCP2BSC[_Rs_](); +} + +//end of Tables opcodes... + +/********************************************************* +* Arithmetic with immediate operand * +* Format: OP rt, rs, immediate * +*********************************************************/ +/* +REC_FUNC(ADDI); +REC_FUNC(ADDIU); +REC_FUNC(ANDI); +REC_FUNC(ORI); +REC_FUNC(XORI); +REC_FUNC(SLTI); +REC_FUNC(SLTIU); +#if 0*/ +static void recADDIU() { +// Rt = Rs + Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); + } +} + +static void recADDI() { +// Rt = Rs + Im + recADDIU(); +} + +static void recSLTI() { +// Rt = Rs < Im (signed) + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32ItoR(EAX, _Imm_); + SETL8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recSLTIU() { +// Rt = Rs < Im (unsigned) + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32ItoR(EAX, _Imm_); + SETB8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recANDI() { +// Rt = Rs And Im + if (!_Rt_) return; + + if (_Rs_ && _ImmU_) { + if (_Rs_ == _Rt_) { + AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + AND32ItoR(EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } +} + +static void recORI() { +// Rt = Rs Or Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_ImmU_) OR32ItoR (EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } +} + +static void recXORI() { +// Rt = Rs Xor Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32ItoR(EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoR(EAX, _ImmU_ ^ 0); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } +} +//#endif +//end of * Arithmetic with immediate operand + +/********************************************************* +* Load higher 16 bits of the first word in GPR with imm * +* Format: OP rt, immediate * +*********************************************************/ +/*REC_FUNC(LUI); +#if 0*/ +static void recLUI() { +// Rt = Imm << 16 + if (!_Rt_) return; + + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], psxRegs.code << 16); +} +//#endif +//End of Load Higher ..... + + +/********************************************************* +* Register arithmetic * +* Format: OP rd, rs, rt * +*********************************************************/ +/* +REC_FUNC(ADD); +REC_FUNC(ADDU); +REC_FUNC(SUB); +REC_FUNC(SUBU); +REC_FUNC(AND); +REC_FUNC(OR); +REC_FUNC(XOR); +REC_FUNC(NOR); +REC_FUNC(SLT); +REC_FUNC(SLTU); + +#if 0*/ +static void recADDU() { +// Rd = Rs + Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recADD() { +// Rd = Rs + Rt + recADDU(); +} + +static void recSUBU() { +// Rd = Rs - Rt + if (!_Rd_) return; + + if (_Rs_ || _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSUB() { +// Rd = Rs - Rt + recSUBU(); +} + +static void recAND() { +// Rd = Rs And Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recOR() { +// Rd = Rs Or Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recXOR() { +// Rd = Rs Xor Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32ItoR(EAX, 0); + } else if (_Rt_) { + XOR32RtoR(EAX, EAX); + XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recNOR() { +// Rd = Rs Nor Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); + NOT32R (EAX); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + NOT32R (EAX); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + NOT32R (EAX); + } else { + MOV32ItoR(EAX, ~0); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSLT() { +// Rd = Rs < Rt (signed) + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + SETL8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSLTU() { +// Rd = Rs < Rt (unsigned) + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + SBB32RtoR(EAX, EAX); + NEG32R (EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} +//#endif +//End of * Register arithmetic + +/********************************************************* +* Register mult/div & Register trap logic * +* Format: OP rs, rt * +*********************************************************/ + +/*REC_FUNC(MULT); +REC_FUNC(MULTU); +REC_FUNC(DIV); +REC_FUNC(DIVU); +#if 0*/ +static void recMULT() { +// Lo/Hi = Rs * Rt (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); +} + +static void recMULTU() { +// Lo/Hi = Rs * Rt (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MUL32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); +} + +static void recDIV() { +// Lo/Hi = Rs / Rt (signed) + + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); + CMP32ItoR(ECX, 0); + j8Ptr[0] = JE8(0); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CDQ(); + IDIV32R (ECX); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); + x86SetJ8(j8Ptr[0]); +} + +static void recDIVU() { +// Lo/Hi = Rs / Rt (unsigned) + + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); + CMP32ItoR(ECX, 0); + j8Ptr[0] = JE8(0); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32RtoR(EDX, EDX); + DIV32R (ECX); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); + x86SetJ8(j8Ptr[0]); +} +//#endif +//End of * Register mult/div & Register trap logic + +/*REC_FUNC(LB); +REC_FUNC(LBU); +REC_FUNC(LH); +REC_FUNC(LHU); +REC_FUNC(LW); + +REC_FUNC(SB); +REC_FUNC(SH); +REC_FUNC(SW);*/ + +REC_FUNC(LWL); +REC_FUNC(LWR); +REC_FUNC(SWL); +REC_FUNC(SWR); +//#if 0 +static void recLB() { +// Rt = mem[Rs + Im] (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead8); + if (_Rt_) { + MOVSX32R8toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLBU() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead8); + if (_Rt_) { + MOVZX32R8toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLH() { +// Rt = mem[Rs + Im] (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead16); + if (_Rt_) { + MOVSX32R16toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLHU() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead16); + if (_Rt_) { + MOVZX32R16toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLW() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead32); + if (_Rt_) { + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} +/* +void recLWL() { +} + +void recLWR() { +} +*/ +static void recSB() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite8); + ADD32ItoR(ESP, 8); +} + +static void recSH() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite16); + ADD32ItoR(ESP, 8); +} + +static void recSW() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite32); + ADD32ItoR(ESP, 8); +} +//#endif +/* +void recSWL() { +} + +void recSWR() { +} +*/ +/*REC_FUNC(SLL); +REC_FUNC(SRL); +REC_FUNC(SRA); +#if 0*/ +static void recSLL() { +// Rd = Rt << Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SHL32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} + +static void recSRL() { +// Rd = Rt >> Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SHR32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} + +static void recSRA() { +// Rd = Rt >> Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SAR32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} +//#endif + +/*REC_FUNC(SLLV); +REC_FUNC(SRLV); +REC_FUNC(SRAV); +#if 0*/ +static void recSLLV() { +// Rd = Rt << Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SHL32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSRLV() { +// Rd = Rt >> Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SHR32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSRAV() { +// Rd = Rt >> Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SAR32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} +//#endif + +/*REC_SYS(SYSCALL); +REC_SYS(BREAK); + +#if 0*/ +static void recSYSCALL() { + MOV32ItoR(EAX, pc - 4); + MOV32RtoM((u32)&psxRegs.pc, EAX); + PUSH32I (branch == 1 ? 1 : 0); + PUSH32I (0x20); + CALLFunc ((u32)psxException); + ADD32ItoR(ESP, 8); + + if (!branch) branch = 2; +} + +static void recBREAK() { +} +//#endif +/* +REC_FUNC(MFHI); +REC_FUNC(MTHI); +REC_FUNC(MFLO); +REC_FUNC(MTLO); +#if 0*/ +static void recMFHI() { +// Rd = Hi + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recMTHI() { +// Hi = Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX); +} + +static void recMFLO() { +// Rd = Lo + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recMTLO() { +// Lo = Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); +} +//#endif + +/*REC_BRANCH(J); +REC_BRANCH(JR); +REC_BRANCH(JAL); +REC_BRANCH(JALR); +REC_BRANCH(BLTZ); +REC_BRANCH(BGTZ); +REC_BRANCH(BLTZAL); +REC_BRANCH(BGEZAL); +REC_BRANCH(BNE); +REC_BRANCH(BEQ); +REC_BRANCH(BLEZ); +REC_BRANCH(BGEZ); + +#if 0*/ +static void recBLTZ() { +// Branch if Rs < 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JL8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGEZ() { +// Branch if Rs >= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JGE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBLTZAL() { +// Branch if Rs < 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JL8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGEZAL() { +// Branch if Rs >= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JGE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recJ() { +// j target + MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); + + SetBranch(); +} + +static void recJAL() { +// jal target + + MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + SetBranch(); +} + +static void recJR() { +// jr Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&target, EAX); + + SetBranch(); +} + +static void recJALR() { +// jalr Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&target, EAX); + + if (_Rd_) { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rd_], pc + 4); + } + + SetBranch(); +} + +static void recBEQ() { +// Branch if Rs == Rt + + if (_Rs_ == _Rt_) { + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + } else { + if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else { + XOR32RtoR(EAX, EAX); + } + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + j8Ptr[0] = JE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + } + + SetBranch(); +} + +static void recBNE() { +// Branch if Rs != Rt + + if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else { + XOR32RtoR(EAX, EAX); + } + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + j8Ptr[0] = JNE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBLEZ() { +// Branch if Rs <= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JLE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGTZ() { +// Branch if Rs > 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JG8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} +//#endif + +/*REC_FUNC(MFC0); +REC_FUNC(MTC0); +REC_FUNC(CFC0); +REC_FUNC(CTC0); +REC_FUNC(RFE); +#if 0*/ +static void recMFC0() { +// Rt = Cop0->Rd + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recCFC0() { +// Rt = Cop0->Rd + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recMTC0() { +// Cop0->Rd = Rt + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); +} + +static void recCTC0() { +// Cop0->Rd = Rt + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); +} + +static void recRFE() { + MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status); + MOV32RtoR(ECX, EAX); + AND32ItoR(EAX, 0xfffffff0); + AND32ItoR(ECX, 0x3c); + SHR32ItoR(ECX, 2); + OR32RtoR (EAX, ECX); + MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX); +} +//#endif + +#define CP2_FUNC(f) \ +void gte##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc ((u32)gte##f); \ +/* branch = 2; */\ +} + +CP2_FUNC(MFC2); +CP2_FUNC(MTC2); +CP2_FUNC(CFC2); +CP2_FUNC(CTC2); +CP2_FUNC(LWC2); +CP2_FUNC(SWC2); + +CP2_FUNC(RTPS); +CP2_FUNC(OP); +CP2_FUNC(NCLIP); +CP2_FUNC(DPCS); +CP2_FUNC(INTPL); +CP2_FUNC(MVMVA); +CP2_FUNC(NCDS); +CP2_FUNC(NCDT); +CP2_FUNC(CDP); +CP2_FUNC(NCCS); +CP2_FUNC(CC); +CP2_FUNC(NCS); +CP2_FUNC(NCT); +CP2_FUNC(SQR); +CP2_FUNC(DCPL); +CP2_FUNC(DPCT); +CP2_FUNC(AVSZ3); +CP2_FUNC(AVSZ4); +CP2_FUNC(RTPT); +CP2_FUNC(GPF); +CP2_FUNC(GPL); +CP2_FUNC(NCCT); + +static void recHLE() { + MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xff]); + CALL32R(EAX); + branch = 2; +} + +// + +static void (*recBSC[64])() = { + recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ, + recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI , + recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL, + recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL, + recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL, + recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL +}; + +static void (*recSPC[64])() = { + recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV, + recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL, + recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL, + recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL, + recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR , + recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL +}; + +static void (*recREG[32])() = { + recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void (*recCP0[32])() = { + recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void (*recCP2[64])() = { + recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00 + recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08 + recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10 + recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18 + recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20 + recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28 + recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30 + recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38 +}; + +static void (*recCP2BSC[32])() = { + recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void recRecompile() { + /* if x86Ptr reached the mem limit reset whole mem */ + if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000)) + recReset(); + + PC_REC32(psxRegs.pc) = (u32)x86Ptr; + pc = psxRegs.pc; + + for (count=0; count<500;) { + char *p; + + p = (char *)PSXM(pc); + if (p == NULL) recError(); + psxRegs.code = *(u32 *)p; + + pc+=4; count++; + recBSC[psxRegs.code>>26](); + + if (branch) { + break; + } + } + + if (!branch) { + MOV32ItoM((u32)&psxRegs.pc, pc); + } + + /* store cycle */ + ADD32ItoM((u32)&psxRegs.cycle, count); + + branch = 0; + + RET(); +} + + +R3000Acpu psxRec = { + recInit, + recReset, + recExecute, + recExecuteBlock, + recClear, + recShutdown +}; -- cgit v1.2.3