diff options
Diffstat (limited to 'libpcsxcore/ppc')
-rw-r--r-- | libpcsxcore/ppc/pGte.h | 91 | ||||
-rw-r--r-- | libpcsxcore/ppc/pR3000A.c | 3540 | ||||
-rw-r--r-- | libpcsxcore/ppc/pasm.s | 124 | ||||
-rw-r--r-- | libpcsxcore/ppc/ppc.c | 32 | ||||
-rw-r--r-- | libpcsxcore/ppc/ppc.h | 60 | ||||
-rw-r--r-- | libpcsxcore/ppc/ppc_mnemonics.h | 529 | ||||
-rw-r--r-- | libpcsxcore/ppc/reguse.c | 419 | ||||
-rw-r--r-- | libpcsxcore/ppc/reguse.h | 83 |
8 files changed, 0 insertions, 4878 deletions
diff --git a/libpcsxcore/ppc/pGte.h b/libpcsxcore/ppc/pGte.h deleted file mode 100644 index a968460..0000000 --- a/libpcsxcore/ppc/pGte.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Pcsx - Pc Psx Emulator - * Copyright (C) 1999-2003 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA - */ - -#ifndef PGET_H -#define PGET_H - -#ifdef __cplusplus -extern "C" { -#endif - -int psxCP2time[64] = { - 2, 16 , 1 , 1, 1, 1 , 8, 1, // 00 - 1 , 1 , 1 , 1, 6 , 1 , 1 , 1, // 08 - 8 , 8, 8, 19, 13 , 1 , 44 , 1, // 10 - 1 , 1 , 1 , 17, 11 , 1 , 14 , 1, // 18 - 30 , 1 , 1 , 1, 1, 1 , 1 , 1, // 20 - 5 , 8 , 17 , 1, 1, 5, 6, 1, // 28 - 23 , 1 , 1 , 1, 1, 1 , 1 , 1, // 30 - 1 , 1 , 1 , 1, 1, 6 , 5 , 39 // 38 -}; - -#define CP2_FUNC(f) \ -void gte##f(); \ -static void rec##f() { \ - if (pc < cop2readypc) idlecyclecount += (cop2readypc - pc)>>2; \ - iFlushRegs(0); \ - LIW(0, (u32)psxRegs.code); \ - STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \ - FlushAllHWReg(); \ - CALLFunc ((u32)gte##f); \ - cop2readypc = pc + psxCP2time[_fFunct_(psxRegs.code)]<<2; \ -} - -#define CP2_FUNCNC(f) \ -void gte##f(); \ -static void rec##f() { \ - if (pc < cop2readypc) idlecyclecount += (cop2readypc - pc)>>2; \ - iFlushRegs(0); \ - CALLFunc ((u32)gte##f); \ -/* branch = 2; */\ - cop2readypc = pc + psxCP2time[_fFunct_(psxRegs.code)]; \ -} - -CP2_FUNC(MFC2); -CP2_FUNC(MTC2); -CP2_FUNC(CFC2); -CP2_FUNC(CTC2); -CP2_FUNC(LWC2); -CP2_FUNC(SWC2); -CP2_FUNCNC(RTPS); -CP2_FUNC(OP); -CP2_FUNCNC(NCLIP); -CP2_FUNC(DPCS); -CP2_FUNC(INTPL); -CP2_FUNC(MVMVA); -CP2_FUNCNC(NCDS); -CP2_FUNCNC(NCDT); -CP2_FUNCNC(CDP); -CP2_FUNCNC(NCCS); -CP2_FUNCNC(CC); -CP2_FUNCNC(NCS); -CP2_FUNCNC(NCT); -CP2_FUNC(SQR); -CP2_FUNC(DCPL); -CP2_FUNCNC(DPCT); -CP2_FUNCNC(AVSZ3); -CP2_FUNCNC(AVSZ4); -CP2_FUNCNC(RTPT); -CP2_FUNC(GPF); -CP2_FUNC(GPL); -CP2_FUNCNC(NCCT); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/libpcsxcore/ppc/pR3000A.c b/libpcsxcore/ppc/pR3000A.c deleted file mode 100644 index 93745f8..0000000 --- a/libpcsxcore/ppc/pR3000A.c +++ /dev/null @@ -1,3540 +0,0 @@ -/* Pcsx - Pc Psx Emulator - * Copyright (C) 1999-2003 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., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA - */ - -#ifdef _MSC_VER_ -#pragma warning(disable:4244) -#pragma warning(disable:4761) -#endif -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <sys/types.h> -#include <sys/mman.h> - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - -#include "../psxcommon.h" -#include "ppc.h" -#include "reguse.h" -#include "../r3000a.h" -#include "../psxhle.h" - -//#define NO_CONSTANT - -u32 *psxRecLUT; - -#undef _Op_ -#define _Op_ _fOp_(psxRegs.code) -#undef _Funct_ -#define _Funct_ _fFunct_(psxRegs.code) -#undef _Rd_ -#define _Rd_ _fRd_(psxRegs.code) -#undef _Rt_ -#define _Rt_ _fRt_(psxRegs.code) -#undef _Rs_ -#define _Rs_ _fRs_(psxRegs.code) -#undef _Sa_ -#define _Sa_ _fSa_(psxRegs.code) -#undef _Im_ -#define _Im_ _fIm_(psxRegs.code) -#undef _Target_ -#define _Target_ _fTarget_(psxRegs.code) - -#undef _Imm_ -#define _Imm_ _fImm_(psxRegs.code) -#undef _ImmU_ -#define _ImmU_ _fImmU_(psxRegs.code) - -#undef PC_REC -#undef PC_REC8 -#undef PC_REC16 -#undef PC_REC32 -#define PC_REC(x) (psxRecLUT[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 OFFSET(X,Y) ((u32)(Y)-(u32)(X)) - -#define RECMEM_SIZE (12*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 u32 pcold; /* recompiler oldpc */ -static int count; /* recompiler intruction count */ -static int branch; /* set for branch */ -static u32 target; /* branch target */ -static u32 resp; - -u32 cop2readypc = 0; -u32 idlecyclecount = 0; - -#define NUM_REGISTERS 34 -typedef struct { - int state; - u32 k; - int reg; -} iRegisters; - -static iRegisters iRegs[34]; - -#define ST_UNK 0x00 -#define ST_CONST 0x01 -#define ST_MAPPED 0x02 - -#ifdef NO_CONSTANT -#define IsConst(reg) 0 -#else -#define IsConst(reg) (iRegs[reg].state & ST_CONST) -#endif -#define IsMapped(reg) (iRegs[reg].state & ST_MAPPED) - -static void (*recBSC[64])(); -static void (*recSPC[64])(); -static void (*recREG[32])(); -static void (*recCP0[32])(); -static void (*recCP2[64])(); -static void (*recCP2BSC[32])(); - -#define REG_LO 32 -#define REG_HI 33 - -// Hardware register usage -#define HWUSAGE_NONE 0x00 - -#define HWUSAGE_READ 0x01 -#define HWUSAGE_WRITE 0x02 -#define HWUSAGE_CONST 0x04 -#define HWUSAGE_ARG 0x08 /* used as an argument for a function call */ - -#define HWUSAGE_RESERVED 0x10 /* won't get flushed when flushing all regs */ -#define HWUSAGE_SPECIAL 0x20 /* special purpose register */ -#define HWUSAGE_HARDWIRED 0x40 /* specific hardware register mapping that is never disposed */ -#define HWUSAGE_INITED 0x80 -#define HWUSAGE_PSXREG 0x100 - -// Remember to invalidate the special registers if they are modified by compiler -enum { - ARG1 = 3, - ARG2 = 4, - ARG3 = 5, - PSXREGS, // ptr - PSXMEM, // ptr - CYCLECOUNT, // ptr - PSXPC, // ptr - TARGETPTR, // ptr - TARGET, // ptr - RETVAL, - REG_RZERO, - REG_WZERO -}; - -typedef struct { - int code; - u32 k; - int usage; - int lastUsed; - - void (*flush)(int hwreg); - int private; -} HWRegister; -static HWRegister HWRegisters[NUM_HW_REGISTERS]; -static int HWRegUseCount; -static int DstCPUReg; -static int UniqueRegAlloc; - -static int GetFreeHWReg(); -static void InvalidateCPURegs(); -static void DisposeHWReg(int index); -static void FlushHWReg(int index); -static void FlushAllHWReg(); -static void MapPsxReg32(int reg); -static void FlushPsxReg32(int hwreg); -static int UpdateHWRegUsage(int hwreg, int usage); -static int GetHWReg32(int reg); -static int PutHWReg32(int reg); -static int GetSpecialIndexFromHWRegs(int which); -static int GetHWRegFromCPUReg(int cpureg); -static int MapRegSpecial(int which); -static void FlushRegSpecial(int hwreg); -static int GetHWRegSpecial(int which); -static int PutHWRegSpecial(int which); -static void recRecompile(); -static void recError(); - -#pragma mark --- Generic register mapping --- - -static int GetFreeHWReg() -{ - int i, least, index; - - if (DstCPUReg != -1) { - index = GetHWRegFromCPUReg(DstCPUReg); - DstCPUReg = -1; - } else { - // LRU algorith with a twist ;) - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) { - break; - } - } - - least = HWRegisters[i].lastUsed; index = i; - for (; i<NUM_HW_REGISTERS; i++) { - if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) { - if (HWRegisters[i].usage == HWUSAGE_NONE && HWRegisters[i].code >= 13) { - index = i; - break; - } - else if (HWRegisters[i].lastUsed < least) { - least = HWRegisters[i].lastUsed; - index = i; - } - } - } - - // Cycle the registers - if (HWRegisters[index].usage == HWUSAGE_NONE) { - for (; i<NUM_HW_REGISTERS; i++) { - if (!(HWRegisters[i].usage & HWUSAGE_RESERVED)) { - if (HWRegisters[i].usage == HWUSAGE_NONE && - HWRegisters[i].code >= 13 && - HWRegisters[i].lastUsed < least) { - least = HWRegisters[i].lastUsed; - index = i; - break; - } - } - } - } - } - -/* if (HWRegisters[index].code < 13 && HWRegisters[index].code > 3) { - SysPrintf("Allocating volatile register %i\n", HWRegisters[index].code); - } - if (HWRegisters[index].usage != HWUSAGE_NONE) { - SysPrintf("RegUse too big. Flushing %i\n", HWRegisters[index].code); - }*/ - if (HWRegisters[index].usage & (HWUSAGE_RESERVED | HWUSAGE_HARDWIRED)) { - if (HWRegisters[index].usage & HWUSAGE_RESERVED) { - SysPrintf("Error! Trying to map a new register to a reserved register (r%i)", - HWRegisters[index].code); - } - if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) { - SysPrintf("Error! Trying to map a new register to a hardwired register (r%i)", - HWRegisters[index].code); - } - } - - if (HWRegisters[index].lastUsed != 0) { - UniqueRegAlloc = 0; - } - - // Make sure the register is really flushed! - FlushHWReg(index); - HWRegisters[index].usage = HWUSAGE_NONE; - HWRegisters[index].flush = NULL; - - return index; -} - -static void FlushHWReg(int index) -{ - if (index < 0) return; - if (HWRegisters[index].usage == HWUSAGE_NONE) return; - - if (HWRegisters[index].flush) { - HWRegisters[index].usage |= HWUSAGE_RESERVED; - HWRegisters[index].flush(index); - HWRegisters[index].flush = NULL; - } - - if (HWRegisters[index].usage & HWUSAGE_HARDWIRED) { - HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE); - } else { - HWRegisters[index].usage = HWUSAGE_NONE; - } -} - -// get rid of a mapped register without flushing the contents to the memory -static void DisposeHWReg(int index) -{ - if (index < 0) return; - if (HWRegisters[index].usage == HWUSAGE_NONE) return; - - HWRegisters[index].usage &= ~(HWUSAGE_READ | HWUSAGE_WRITE); - if (HWRegisters[index].usage == HWUSAGE_NONE) { - SysPrintf("Error! not correctly disposing register (r%i)", HWRegisters[index].code); - } - - FlushHWReg(index); -} - -// operated on cpu registers -__inline static void FlushCPURegRange(int start, int end) -{ - int i; - - if (end <= 0) end = 31; - if (start <= 0) start = 0; - - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (HWRegisters[i].code >= start && HWRegisters[i].code <= end) - if (HWRegisters[i].flush) - FlushHWReg(i); - } - - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (HWRegisters[i].code >= start && HWRegisters[i].code <= end) - FlushHWReg(i); - } -} - -static void FlushAllHWReg() -{ - FlushCPURegRange(0,31); -} - -static void InvalidateCPURegs() -{ - FlushCPURegRange(0,12); -} - -#pragma mark --- Mapping utility functions --- - -static void MoveHWRegToCPUReg(int cpureg, int hwreg) -{ - int dstreg; - - if (HWRegisters[hwreg].code == cpureg) - return; - - dstreg = GetHWRegFromCPUReg(cpureg); - - HWRegisters[dstreg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG); - if (HWRegisters[hwreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) { - FlushHWReg(dstreg); - MR(HWRegisters[dstreg].code, HWRegisters[hwreg].code); - } else { - if (HWRegisters[dstreg].usage & (HWUSAGE_READ | HWUSAGE_WRITE)) { - MR(HWRegisters[hwreg].code, HWRegisters[dstreg].code); - } - else if (HWRegisters[dstreg].usage != HWUSAGE_NONE) { - FlushHWReg(dstreg); - } - } - - HWRegisters[dstreg].code = HWRegisters[hwreg].code; - HWRegisters[hwreg].code = cpureg; -} - -static int UpdateHWRegUsage(int hwreg, int usage) -{ - HWRegisters[hwreg].lastUsed = ++HWRegUseCount; - if (usage & HWUSAGE_WRITE) { - HWRegisters[hwreg].usage &= ~HWUSAGE_CONST; - } - if (!(usage & HWUSAGE_INITED)) { - HWRegisters[hwreg].usage &= ~HWUSAGE_INITED; - } - HWRegisters[hwreg].usage |= usage; - - return HWRegisters[hwreg].code; -} - -static int GetHWRegFromCPUReg(int cpureg) -{ - int i; - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (HWRegisters[i].code == cpureg) { - return i; - } - } - - SysPrintf("Error! Register location failure (r%i)", cpureg); - return 0; -} - -// this function operates on cpu registers -void SetDstCPUReg(int cpureg) -{ - DstCPUReg = cpureg; -} - -static void ReserveArgs(int args) -{ - int index, i; - - for (i=0; i<args; i++) { - index = GetHWRegFromCPUReg(3+i); - HWRegisters[index].usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG; - } -} - -static void ReleaseArgs() -{ - int i; - - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (HWRegisters[i].usage & HWUSAGE_ARG) { - //HWRegisters[i].usage = HWUSAGE_NONE; - //HWRegisters[i].flush = NULL; - HWRegisters[i].usage &= ~(HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG); - FlushHWReg(i); - } - } -} - -#pragma mark --- Psx register mapping --- - -static void MapPsxReg32(int reg) -{ - int hwreg = GetFreeHWReg(); - HWRegisters[hwreg].flush = FlushPsxReg32; - HWRegisters[hwreg].private = reg; - - if (iRegs[reg].reg != -1) { - SysPrintf("error: double mapped psx register"); - } - - iRegs[reg].reg = hwreg; - iRegs[reg].state |= ST_MAPPED; -} - -static void FlushPsxReg32(int hwreg) -{ - int reg = HWRegisters[hwreg].private; - - if (iRegs[reg].reg == -1) { - SysPrintf("error: flushing unmapped psx register"); - } - - if (HWRegisters[hwreg].usage & HWUSAGE_WRITE) { - if (branch) { - /*int reguse = nextPsxRegUse(pc-8, reg); - if (reguse == REGUSE_NONE || (reguse & REGUSE_READ))*/ { - STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS)); - } - } else { - int reguse = nextPsxRegUse(pc-4, reg); - if (reguse == REGUSE_NONE || (reguse & REGUSE_READ)) { - STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS)); - } - } - } - - iRegs[reg].reg = -1; - iRegs[reg].state = ST_UNK; -} - -static int GetHWReg32(int reg) -{ - int usage = HWUSAGE_PSXREG | HWUSAGE_READ; - - if (reg == 0) { - return GetHWRegSpecial(REG_RZERO); - } - if (!IsMapped(reg)) { - usage |= HWUSAGE_INITED; - MapPsxReg32(reg); - - HWRegisters[iRegs[reg].reg].usage |= HWUSAGE_RESERVED; - if (IsConst(reg)) { - LIW(HWRegisters[iRegs[reg].reg].code, iRegs[reg].k); - usage |= HWUSAGE_WRITE | HWUSAGE_CONST; - //iRegs[reg].state &= ~ST_CONST; - } - else { - LWZ(HWRegisters[iRegs[reg].reg].code, OFFSET(&psxRegs, &psxRegs.GPR.r[reg]), GetHWRegSpecial(PSXREGS)); - } - HWRegisters[iRegs[reg].reg].usage &= ~HWUSAGE_RESERVED; - } - else if (DstCPUReg != -1) { - int dst = DstCPUReg; - DstCPUReg = -1; - - if (HWRegisters[iRegs[reg].reg].code < 13) { - MoveHWRegToCPUReg(dst, iRegs[reg].reg); - } else { - MR(DstCPUReg, HWRegisters[iRegs[reg].reg].code); - } - } - - DstCPUReg = -1; - - return UpdateHWRegUsage(iRegs[reg].reg, usage); -} - -static int PutHWReg32(int reg) -{ - int usage = HWUSAGE_PSXREG | HWUSAGE_WRITE; - if (reg == 0) { - return PutHWRegSpecial(REG_WZERO); - } - - if (DstCPUReg != -1 && IsMapped(reg)) { - if (HWRegisters[iRegs[reg].reg].code != DstCPUReg) { - int tmp = DstCPUReg; - DstCPUReg = -1; - DisposeHWReg(iRegs[reg].reg); - DstCPUReg = tmp; - } - } - if (!IsMapped(reg)) { - usage |= HWUSAGE_INITED; - MapPsxReg32(reg); - } - - DstCPUReg = -1; - iRegs[reg].state &= ~ST_CONST; - - return UpdateHWRegUsage(iRegs[reg].reg, usage); -} - -#pragma mark --- Special register mapping --- - -static int GetSpecialIndexFromHWRegs(int which) -{ - int i; - for (i=0; i<NUM_HW_REGISTERS; i++) { - if (HWRegisters[i].usage & HWUSAGE_SPECIAL) { - if (HWRegisters[i].private == which) { - return i; - } - } - } - return -1; -} - -static int MapRegSpecial(int which) -{ - int hwreg = GetFreeHWReg(); - HWRegisters[hwreg].flush = FlushRegSpecial; - HWRegisters[hwreg].private = which; - - return hwreg; -} - -static void FlushRegSpecial(int hwreg) -{ - int which = HWRegisters[hwreg].private; - - if (!(HWRegisters[hwreg].usage & HWUSAGE_WRITE)) - return; - - switch (which) { - case CYCLECOUNT: - STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS)); - break; - case PSXPC: - STW(HWRegisters[hwreg].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS)); - break; - case TARGET: - STW(HWRegisters[hwreg].code, 0, GetHWRegSpecial(TARGETPTR)); - break; - } -} - -static int GetHWRegSpecial(int which) -{ - int index = GetSpecialIndexFromHWRegs(which); - int usage = HWUSAGE_READ | HWUSAGE_SPECIAL; - - if (index == -1) { - usage |= HWUSAGE_INITED; - index = MapRegSpecial(which); - - HWRegisters[index].usage |= HWUSAGE_RESERVED; - switch (which) { - case PSXREGS: - case PSXMEM: - SysPrintf("error! shouldn't be here!\n"); - //HWRegisters[index].flush = NULL; - //LIW(HWRegisters[index].code, (u32)&psxRegs); - break; - case TARGETPTR: - HWRegisters[index].flush = NULL; - LIW(HWRegisters[index].code, (u32)&target); - break; - case REG_RZERO: - HWRegisters[index].flush = NULL; - LIW(HWRegisters[index].code, 0); - break; - case RETVAL: - MoveHWRegToCPUReg(3, index); - /*reg = GetHWRegFromCPUReg(3); - HWRegisters[reg].code = HWRegisters[index].code; - HWRegisters[index].code = 3;*/ - HWRegisters[index].flush = NULL; - - usage |= HWUSAGE_RESERVED; - break; - - case CYCLECOUNT: - LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.cycle), GetHWRegSpecial(PSXREGS)); - break; - case PSXPC: - LWZ(HWRegisters[index].code, OFFSET(&psxRegs, &psxRegs.pc), GetHWRegSpecial(PSXREGS)); - break; - case TARGET: - LWZ(HWRegisters[index].code, 0, GetHWRegSpecial(TARGETPTR)); - break; - default: - SysPrintf("Error: Unknown special register in GetHWRegSpecial()\n"); - break; - } - HWRegisters[index].usage &= ~HWUSAGE_RESERVED; - } - else if (DstCPUReg != -1) { - int dst = DstCPUReg; - DstCPUReg = -1; - - MoveHWRegToCPUReg(dst, index); - } - - return UpdateHWRegUsage(index, usage); -} - -static int PutHWRegSpecial(int which) -{ - int index = GetSpecialIndexFromHWRegs(which); - int usage = HWUSAGE_WRITE | HWUSAGE_SPECIAL; - - if (DstCPUReg != -1 && index != -1) { - if (HWRegisters[index].code != DstCPUReg) { - int tmp = DstCPUReg; - DstCPUReg = -1; - DisposeHWReg(index); - DstCPUReg = tmp; - } - } - switch (which) { - case PSXREGS: - case TARGETPTR: - SysPrintf("Error: Read-only special register in PutHWRegSpecial()\n"); - case REG_WZERO: - if (index >= 0) { - if (HWRegisters[index].usage & HWUSAGE_WRITE) - break; - } - index = MapRegSpecial(which); - HWRegisters[index].flush = NULL; - break; - default: - if (index == -1) { - usage |= HWUSAGE_INITED; - index = MapRegSpecial(which); - - HWRegisters[index].usage |= HWUSAGE_RESERVED; - switch (which) { - case ARG1: - case ARG2: - case ARG3: - MoveHWRegToCPUReg(3+(which-ARG1), index); - /*reg = GetHWRegFromCPUReg(3+(which-ARG1)); - - if (HWRegisters[reg].usage != HWUSAGE_NONE) { - HWRegisters[reg].usage &= ~(HWUSAGE_HARDWIRED | HWUSAGE_ARG); - if (HWRegisters[reg].flush != NULL && HWRegisters[reg].usage & (HWUSAGE_WRITE | HWUSAGE_READ)) { - MR(HWRegisters[index].code, HWRegisters[reg].code); - } else { - FlushHWReg(reg); - } - } - HWRegisters[reg].code = HWRegisters[index].code; - if (!(HWRegisters[index].code >= 3 && HWRegisters[index].code <=31)) - SysPrintf("Error! Register allocation"); - HWRegisters[index].code = 3+(which-ARG1);*/ - HWRegisters[index].flush = NULL; - - usage |= HWUSAGE_RESERVED | HWUSAGE_HARDWIRED | HWUSAGE_ARG; - break; - } - } - HWRegisters[index].usage &= ~HWUSAGE_RESERVED; - break; - } - - DstCPUReg = -1; - - return UpdateHWRegUsage(index, usage); -} - -#pragma mark --- --- - -static void MapConst(int reg, u32 _const) { - if (reg == 0) - return; - if (IsConst(reg) && iRegs[reg].k == _const) - return; - - DisposeHWReg(iRegs[reg].reg); - iRegs[reg].k = _const; - iRegs[reg].state = ST_CONST; -} - -static void MapCopy(int dst, int src) -{ - // do it the lazy way for now - MR(PutHWReg32(dst), GetHWReg32(src)); -} - -static void iFlushReg(u32 nextpc, int reg) { - if (!IsMapped(reg) && IsConst(reg)) { - GetHWReg32(reg); - } - if (IsMapped(reg)) { - if (nextpc) { - int use = nextPsxRegUse(nextpc, reg); - if ((use & REGUSE_RW) == REGUSE_WRITE) { - DisposeHWReg(iRegs[reg].reg); - } else { - FlushHWReg(iRegs[reg].reg); - } - } else { - FlushHWReg(iRegs[reg].reg); - } - } -} - -static void iFlushRegs(u32 nextpc) { - int i; - - for (i=1; i<NUM_REGISTERS; i++) { - iFlushReg(nextpc, i); - } -} - -static void Return() -{ - iFlushRegs(0); - FlushAllHWReg(); - if (((u32)returnPC & 0x1fffffc) == (u32)returnPC) { - BA((u32)returnPC); - } - else { - LIW(0, (u32)returnPC); - MTLR(0); - BLR(); - } -} - -static void iRet() { - /* store cycle */ - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - Return(); -} - -static int iLoadTest() { - u32 tmp; - - // check for load delay - tmp = psxRegs.code >> 26; - switch (tmp) { - case 0x10: // COP0 - switch (_Rs_) { - case 0x00: // MFC0 - case 0x02: // CFC0 - return 1; - } - break; - case 0x12: // COP2 - switch (_Funct_) { - case 0x00: - switch (_Rs_) { - case 0x00: // MFC2 - case 0x02: // CFC2 - return 1; - } - break; - } - break; - case 0x32: // LWC2 - return 1; - default: - if (tmp >= 0x20 && tmp <= 0x26) { // LB/LH/LWL/LW/LBU/LHU/LWR - return 1; - } - break; - } - return 0; -} - -/* set a pending branch */ -static void SetBranch() { - int treg; - branch = 1; - psxRegs.code = PSXMu32(pc); - pc+=4; - - if (iLoadTest() == 1) { - iFlushRegs(0); - LIW(0, psxRegs.code); - STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); - /* store cycle */ - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - - treg = GetHWRegSpecial(TARGET); - MR(PutHWRegSpecial(ARG2), treg); - DisposeHWReg(GetHWRegFromCPUReg(treg)); - LIW(PutHWRegSpecial(ARG1), _Rt_); - LIW(GetHWRegSpecial(PSXPC), pc); - FlushAllHWReg(); - CALLFunc((u32)psxDelayTest); - - Return(); - return; - } - - recBSC[psxRegs.code>>26](); - - iFlushRegs(0); - treg = GetHWRegSpecial(TARGET); - MR(PutHWRegSpecial(PSXPC), GetHWRegSpecial(TARGET)); // FIXME: this line should not be needed - DisposeHWReg(GetHWRegFromCPUReg(treg)); - FlushAllHWReg(); - - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - FlushAllHWReg(); - CALLFunc((u32)psxBranchTest); - - // TODO: don't return if target is compiled - Return(); -} - -static void iJump(u32 branchPC) { - u32 *b1, *b2; - branch = 1; - psxRegs.code = PSXMu32(pc); - pc+=4; - - if (iLoadTest() == 1) { - iFlushRegs(0); - LIW(0, psxRegs.code); - STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); - /* store cycle */ - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - - LIW(PutHWRegSpecial(ARG2), branchPC); - LIW(PutHWRegSpecial(ARG1), _Rt_); - LIW(GetHWRegSpecial(PSXPC), pc); - FlushAllHWReg(); - CALLFunc((u32)psxDelayTest); - - Return(); - return; - } - - recBSC[psxRegs.code>>26](); - - iFlushRegs(branchPC); - LIW(PutHWRegSpecial(PSXPC), branchPC); - FlushAllHWReg(); - - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) { - // LIW(PutHWRegSpecial(CYCLECOUNT), 0); - //} else { - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - //} - FlushAllHWReg(); - CALLFunc((u32)psxBranchTest); - - if (!Config.HLE && Config.PsxOut && - ((branchPC & 0x1fffff) == 0xa0 || - (branchPC & 0x1fffff) == 0xb0 || - (branchPC & 0x1fffff) == 0xc0)) - CALLFunc((u32)psxJumpTest); - - // always return for now... - //Return(); - - // maybe just happened an interruption, check so - LIW(0, branchPC); - CMPLW(GetHWRegSpecial(PSXPC), 0); - BNE_L(b1); - - LIW(3, PC_REC(branchPC)); - LWZ(3, 0, 3); - CMPLWI(3, 0); - BNE_L(b2); - - B_DST(b1); - Return(); - - // next bit is already compiled - jump right to it - B_DST(b2); - MTCTR(3); - BCTR(); -} - -static void iBranch(u32 branchPC, int savectx) { - HWRegister HWRegistersS[NUM_HW_REGISTERS]; - iRegisters iRegsS[NUM_REGISTERS]; - int HWRegUseCountS = 0; - u32 respold=0; - u32 *b1, *b2; - - if (savectx) { - respold = resp; - memcpy(iRegsS, iRegs, sizeof(iRegs)); - memcpy(HWRegistersS, HWRegisters, sizeof(HWRegisters)); - HWRegUseCountS = HWRegUseCount; - } - - branch = 1; - psxRegs.code = PSXMu32(pc); - - // the delay test is only made when the branch is taken - // savectx == 0 will mean that :) - if (savectx == 0 && iLoadTest() == 1) { - iFlushRegs(0); - LIW(0, psxRegs.code); - STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); - /* store cycle */ - count = (idlecyclecount + ((pc+4) - pcold) / 4) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - - LIW(PutHWRegSpecial(ARG2), branchPC); - LIW(PutHWRegSpecial(ARG1), _Rt_); - LIW(GetHWRegSpecial(PSXPC), pc); - FlushAllHWReg(); - CALLFunc((u32)psxDelayTest); - - Return(); - return; - } - - pc+= 4; - recBSC[psxRegs.code>>26](); - - iFlushRegs(branchPC); - LIW(PutHWRegSpecial(PSXPC), branchPC); - FlushAllHWReg(); - - /* store cycle */ - count = (idlecyclecount + (pc - pcold) / 4) * BIAS; - //if (/*psxRegs.code == 0 &&*/ count == 2 && branchPC == pcold) { - // LIW(PutHWRegSpecial(CYCLECOUNT), 0); - //} else { - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - //} - FlushAllHWReg(); - CALLFunc((u32)psxBranchTest); - - // always return for now... - //Return(); - - LIW(0, branchPC); - CMPLW(GetHWRegSpecial(PSXPC), 0); - BNE_L(b1); - - LIW(3, PC_REC(branchPC)); - LWZ(3, 0, 3); - CMPLWI(3, 0); - BNE_L(b2); - - B_DST(b1); - Return(); - - B_DST(b2); - MTCTR(3); - BCTR(); - - // maybe just happened an interruption, check so -/* CMP32ItoM((u32)&psxRegs.pc, branchPC); - j8Ptr[1] = JE8(0); - RET(); - - x86SetJ8(j8Ptr[1]); - MOV32MtoR(EAX, PC_REC(branchPC)); - TEST32RtoR(EAX, EAX); - j8Ptr[2] = JNE8(0); - RET(); - - x86SetJ8(j8Ptr[2]); - JMP32R(EAX);*/ - - pc-= 4; - if (savectx) { - resp = respold; - memcpy(iRegs, iRegsS, sizeof(iRegs)); - memcpy(HWRegisters, HWRegistersS, sizeof(HWRegisters)); - HWRegUseCount = HWRegUseCountS; - } -} - - -static void iDumpRegs() { - 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"); - } -} - -void iDumpBlock(char *ptr) { -/* FILE *f; - u32 i; - - SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxCurrentCycle); - - for (i = psxRegs.pc; i < pc; i+=4) - SysPrintf("%s\n", disR3000AF(PSXMu32(i), i)); - - fflush(stdout); - f = fopen("dump1", "w"); - fwrite(ptr, 1, (u32)x86Ptr - (u32)ptr, f); - fclose(f); - system("ndisasmw -u dump1"); - fflush(stdout);*/ -} - -#define REC_FUNC(f) \ -void psx##f(); \ -static void rec##f() { \ - iFlushRegs(0); \ - LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \ - STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \ - LIW(PutHWRegSpecial(PSXPC), (u32)pc); \ - FlushAllHWReg(); \ - CALLFunc((u32)psx##f); \ -/* branch = 2; */\ -} - -#define REC_SYS(f) \ -void psx##f(); \ -static void rec##f() { \ - iFlushRegs(0); \ - LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \ - STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \ - LIW(PutHWRegSpecial(PSXPC), (u32)pc); \ - FlushAllHWReg(); \ - CALLFunc((u32)psx##f); \ - branch = 2; \ - iRet(); \ -} - -#define REC_BRANCH(f) \ -void psx##f(); \ -static void rec##f() { \ - iFlushRegs(0); \ - LIW(PutHWRegSpecial(ARG1), (u32)psxRegs.code); \ - STW(GetHWRegSpecial(ARG1), OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \ - LIW(PutHWRegSpecial(PSXPC), (u32)pc); \ - FlushAllHWReg(); \ - CALLFunc((u32)psx##f); \ - branch = 2; \ - iRet(); \ -} - -static void freeMem(int all) -{ - if (recMem) free(recMem); - if (recRAM) free(recRAM); - if (recROM) free(recROM); - recMem = recRAM = recROM = 0; - - if (all && psxRecLUT) { - free(psxRecLUT); psxRecLUT = NULL; - } -} - -static int allocMem() { - int i; - - freeMem(0); - - if (psxRecLUT==NULL) - psxRecLUT = (u32*) malloc(0x010000 * 4); - - recMem = (char*) malloc(RECMEM_SIZE); - //recMem = mmap(NULL, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); - recRAM = (char*) malloc(0x200000); - recROM = (char*) malloc(0x080000); - if (recRAM == NULL || recROM == NULL || recMem == NULL/*(void *)-1*/ || psxRecLUT == NULL) { - freeMem(1); - SysMessage("Error allocating memory"); return -1; - } - - for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16]; - memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * 4); - memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * 4); - - for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (u32)&recROM[i << 16]; - - return 0; -} - -static int recInit() { - return allocMem(); -} - -static void recReset() { - memset(recRAM, 0, 0x200000); - memset(recROM, 0, 0x080000); - - ppcInit(); - ppcSetPtr((u32 *)recMem); - - branch = 0; - memset(iRegs, 0, sizeof(iRegs)); - iRegs[0].state = ST_CONST; - iRegs[0].k = 0; -} - -static void recShutdown() { - freeMem(1); - ppcShutdown(); -} - -static void recError() { - SysReset(); - ClosePlugins(); - SysMessage("Unrecoverable error while running recompiler\n"); - SysRunGui(); -} - -__inline static void 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(); - } - recRun(*recFunc, (u32)&psxRegs, (u32)&psxM); -} - -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... - -#pragma mark - Arithmetic with immediate operand - -/********************************************************* -* Arithmetic with immediate operand * -* Format: OP rt, rs, immediate * -*********************************************************/ - -#if 0 -/*REC_FUNC(ADDI); -REC_FUNC(ADDIU); -REC_FUNC(ANDI); -REC_FUNC(ORI); -REC_FUNC(XORI); -REC_FUNC(SLTI); -REC_FUNC(SLTIU);*/ -#else -static void recADDIU() { -// Rt = Rs + Im - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, iRegs[_Rs_].k + _Imm_); - } else { - if (_Imm_ == 0) { - MapCopy(_Rt_, _Rs_); - } else { - ADDI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _Imm_); - } - } -} - -static void recADDI() { -// Rt = Rs + Im - recADDIU(); -} - -//REC_FUNC(SLTI); -//REC_FUNC(SLTIU); -//CR0: SIGN | POSITIVE | ZERO | SOVERFLOW | SOVERFLOW | OVERFLOW | CARRY -static void recSLTI() { -// Rt = Rs < Im (signed) - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_); - } else { - if (_Imm_ == 0) { - SRWI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), 31); - } else { - int reg; - CMPWI(GetHWReg32(_Rs_), _Imm_); - reg = PutHWReg32(_Rt_); - LI(reg, 1); - BLT(1); - LI(reg, 0); - } - } -} - -static void recSLTIU() { -// Rt = Rs < Im (unsigned) - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_); - } else { - int reg; - CMPLWI(GetHWReg32(_Rs_), _Imm_); - reg = PutHWReg32(_Rt_); - LI(reg, 1); - BLT(1); - LI(reg, 0); - } -} - -static void recANDI() { -// Rt = Rs And Im - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_); - } else { - ANDI_(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_); - } -} - -static void recORI() { -// Rt = Rs Or Im - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_); - } else { - if (_Imm_ == 0) { - MapCopy(_Rt_, _Rs_); - } else { - ORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_); - } - } -} - -static void recXORI() { -// Rt = Rs Xor Im - if (!_Rt_) return; - - if (IsConst(_Rs_)) { - MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_); - } else { - XORI(PutHWReg32(_Rt_), GetHWReg32(_Rs_), _ImmU_); - } -} -#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; - - MapConst(_Rt_, psxRegs.code << 16); -} -//#endif -//End of Load Higher ..... - -#pragma mark - Register arithmetic - -/********************************************************* -* Register arithmetic * -* Format: OP rd, rs, rt * -*********************************************************/ - -#if 0 -/*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);*/ -#else -static void recADDU() { -// Rd = Rs + Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) { - ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), (s16)iRegs[_Rs_].k); - } else if ((iRegs[_Rs_].k & 0xffff) == 0) { - ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k>>16); - } else { - ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) { - ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (s16)iRegs[_Rt_].k); - } else if ((iRegs[_Rt_].k & 0xffff) == 0) { - ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k>>16); - } else { - ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else { - ADD(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } -} - -static void recADD() { -// Rd = Rs + Rt - recADDU(); -} - -static void recSUBU() { -// Rd = Rs - Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k); - } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((s32)(s16)(-iRegs[_Rt_].k) == (s32)(-iRegs[_Rt_].k)) { - ADDI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), -iRegs[_Rt_].k); - } else if (((-iRegs[_Rt_].k) & 0xffff) == 0) { - ADDIS(PutHWReg32(_Rd_), GetHWReg32(_Rs_), (-iRegs[_Rt_].k)>>16); - } else { - SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else { - SUB(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } -} - -static void recSUB() { -// Rd = Rs - Rt - recSUBU(); -} - -static void recAND() { -// Rd = Rs And Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - // TODO: implement shifted (ANDIS) versions of these - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - ANDI_(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k); - } else { - AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else { - AND(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } -} - -static void recOR() { -// Rd = Rs Or Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k); - } - else { - if (_Rs_ == _Rt_) { - MapCopy(_Rd_, _Rs_); - } - else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - ORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - ORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k); - } else { - OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else { - OR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } -} - -static void recXOR() { -// Rd = Rs Xor Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - XORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - XORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k); - } else { - XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else { - XOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } -} - -static void recNOR() { -// Rd = Rs Nor Rt - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k)); - } /*else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - NORI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - NORI(PutHWReg32(_Rd_), GetHWReg32(_Rs_), iRegs[_Rt_].k); - } else { - NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } */else { - NOR(PutHWReg32(_Rd_), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } -} - -static void recSLT() { -// Rd = Rs < Rt (signed) - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k); - } else { // TODO: add immidiate cases - int reg; - CMPW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - reg = PutHWReg32(_Rd_); - LI(reg, 1); - BLT(1); - LI(reg, 0); - } -} - -static void recSLTU() { -// Rd = Rs < Rt (unsigned) - if (!_Rd_) return; - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k); - } else { // TODO: add immidiate cases - SUBFC(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_)); - SUBFE(PutHWReg32(_Rd_), GetHWReg32(_Rd_), GetHWReg32(_Rd_)); - NEG(PutHWReg32(_Rd_), GetHWReg32(_Rd_)); - } -} -#endif -//End of * Register arithmetic - -#pragma mark - mult/div & Register trap logic - -/********************************************************* -* Register mult/div & Register trap logic * -* Format: OP rs, rt * -*********************************************************/ - -#if 0 -REC_FUNC(MULT); -REC_FUNC(MULTU); -REC_FUNC(DIV); -REC_FUNC(DIVU); -#else - -int DoShift(u32 k) -{ - u32 i; - for (i=0; i<30; i++) { - if (k == (1ul << i)) - return i; - } - return -1; -} - -//REC_FUNC(MULT); - -// FIXME: doesn't work in GT - wrong way marker -static void recMULT() { -// Lo/Hi = Rs * Rt (signed) - s32 k; int r; - int usehi, uselo; - - if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) || - (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) { - MapConst(REG_LO, 0); - MapConst(REG_HI, 0); - return; - } - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - u64 res = (s64)((s64)(s32)iRegs[_Rs_].k * (s64)(s32)iRegs[_Rt_].k); - MapConst(REG_LO, (res & 0xffffffff)); - MapConst(REG_HI, ((res >> 32) & 0xffffffff)); - return; - } - - if (IsConst(_Rs_)) { - k = (s32)iRegs[_Rs_].k; - r = _Rt_; - } else if (IsConst(_Rt_)) { - k = (s32)iRegs[_Rt_].k; - r = _Rs_; - } else { - r = -1; - k = 0; - } - - // FIXME: this should not be needed!!! -// uselo = isPsxRegUsed(pc, REG_LO); -// usehi = isPsxRegUsed(pc, REG_HI); - uselo = 1; //isPsxRegUsed(pc, REG_LO); - usehi = 1; //isPsxRegUsed(pc, REG_HI); - - - if (r != -1) { - int shift = DoShift(k); - if (shift != -1) { - if (uselo) { - SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift) - } - if (usehi) { - SRAWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift); - } - } else { - //if ((s32)(s16)k == k) { - // MULLWI(PutHWReg32(REG_LO), GetHWReg32(r), k); - // MULHWI(PutHWReg32(REG_HI), GetHWReg32(r), k); - //} else - { - if (uselo) { - MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - if (usehi) { - MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - } - } else { - if (uselo) { - MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - if (usehi) { - MULHW(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } -} - -static void recMULTU() { -// Lo/Hi = Rs * Rt (unsigned) - u32 k; int r; - int usehi, uselo; - - if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) || - (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) { - MapConst(REG_LO, 0); - MapConst(REG_HI, 0); - return; - } - - if (IsConst(_Rs_) && IsConst(_Rt_)) { - u64 res = (u64)((u64)(u32)iRegs[_Rs_].k * (u64)(u32)iRegs[_Rt_].k); - MapConst(REG_LO, (res & 0xffffffff)); - MapConst(REG_HI, ((res >> 32) & 0xffffffff)); - return; - } - - if (IsConst(_Rs_)) { - k = (s32)iRegs[_Rs_].k; - r = _Rt_; - } else if (IsConst(_Rt_)) { - k = (s32)iRegs[_Rt_].k; - r = _Rs_; - } else { - r = -1; - k = 0; - } - - uselo = isPsxRegUsed(pc, REG_LO); - usehi = isPsxRegUsed(pc, REG_HI); - - if (r != -1) { - int shift = DoShift(k); - if (shift != -1) { - if (uselo) { - SLWI(PutHWReg32(REG_LO), GetHWReg32(r), shift); - } - if (usehi) { - SRWI(PutHWReg32(REG_HI), GetHWReg32(r), 31-shift); - } - } else { - { - if (uselo) { - MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - if (usehi) { - MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - } - } else { - if (uselo) { - MULLW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - if (usehi) { - MULHWU(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } -} - -static void recDIV() { -// Lo/Hi = Rs / Rt (signed) - int usehi; - - if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) { - MapConst(REG_LO, 0); - MapConst(REG_HI, 0); - return; - } - if (IsConst(_Rt_) && IsConst(_Rs_)) { - MapConst(REG_LO, (s32)iRegs[_Rs_].k / (s32)iRegs[_Rt_].k); - MapConst(REG_HI, (s32)iRegs[_Rs_].k % (s32)iRegs[_Rt_].k); - return; - } - - usehi = isPsxRegUsed(pc, REG_HI); - - if (IsConst(_Rt_)) { - int shift = DoShift(iRegs[_Rt_].k); - if (shift != -1) { - SRAWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift); - ADDZE(PutHWReg32(REG_LO), GetHWReg32(REG_LO)); - if (usehi) { - RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31); - } - } else if (iRegs[_Rt_].k == 3) { - // http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html - LIS(PutHWReg32(REG_HI), 0x5555); - ADDI(PutHWReg32(REG_HI), GetHWReg32(REG_HI), 0x5556); - MULHW(PutHWReg32(REG_LO), GetHWReg32(REG_HI), GetHWReg32(_Rs_)); - SRWI(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 31); - ADD(PutHWReg32(REG_LO), GetHWReg32(REG_LO), GetHWReg32(REG_HI)); - if (usehi) { - MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), 3); - SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI)); - } - } else { - DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - if (usehi) { - if ((iRegs[_Rt_].k & 0x7fff) == iRegs[_Rt_].k) { - MULLI(PutHWReg32(REG_HI), GetHWReg32(REG_LO), iRegs[_Rt_].k); - } else { - MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_)); - } - SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI)); - } - } - } else { - DIVW(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - if (usehi) { - MULLW(PutHWReg32(REG_HI), GetHWReg32(REG_LO), GetHWReg32(_Rt_)); - SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI)); - } - } -} - -static void recDIVU() { -// Lo/Hi = Rs / Rt (unsigned) - int usehi; - - if (IsConst(_Rs_) && iRegs[_Rs_].k == 0) { - MapConst(REG_LO, 0); - MapConst(REG_HI, 0); - return; - } - if (IsConst(_Rt_) && IsConst(_Rs_)) { - MapConst(REG_LO, (u32)iRegs[_Rs_].k / (u32)iRegs[_Rt_].k); - MapConst(REG_HI, (u32)iRegs[_Rs_].k % (u32)iRegs[_Rt_].k); - return; - } - - usehi = isPsxRegUsed(pc, REG_HI); - - if (IsConst(_Rt_)) { - int shift = DoShift(iRegs[_Rt_].k); - if (shift != -1) { - SRWI(PutHWReg32(REG_LO), GetHWReg32(_Rs_), shift); - if (usehi) { - RLWINM(PutHWReg32(REG_HI), GetHWReg32(_Rs_), 0, 31-shift, 31); - } - } else { - DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - if (usehi) { - MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO)); - SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI)); - } - } - } else { - DIVWU(PutHWReg32(REG_LO), GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - if (usehi) { - MULLW(PutHWReg32(REG_HI), GetHWReg32(_Rt_), GetHWReg32(REG_LO)); - SUB(PutHWReg32(REG_HI), GetHWReg32(_Rs_), GetHWReg32(REG_HI)); - } - } -} -#endif -//End of * Register mult/div & Register trap logic - -#pragma mark - memory access - - -#if 0 -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); -#else -static void preMemRead() -{ - int rs; - - ReserveArgs(1); - if (_Rs_ != _Rt_) { - DisposeHWReg(iRegs[_Rt_].reg); - } - rs = GetHWReg32(_Rs_); - if (rs != 3 || _Imm_ != 0) { - ADDI(PutHWRegSpecial(ARG1), rs, _Imm_); - } - if (_Rs_ == _Rt_) { - DisposeHWReg(iRegs[_Rt_].reg); - } - InvalidateCPURegs(); - //FlushAllHWReg(); -} - -static void preMemWrite(int size) -{ - int rs; - - ReserveArgs(2); - rs = GetHWReg32(_Rs_); - if (rs != 3 || _Imm_ != 0) { - ADDI(PutHWRegSpecial(ARG1), rs, _Imm_); - } - if (size == 1) { - RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 24, 31); - //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xff); - } else if (size == 2) { - RLWINM(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0, 16, 31); - //ANDI_(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_), 0xffff); - } else { - MR(PutHWRegSpecial(ARG2), GetHWReg32(_Rt_)); - } - - InvalidateCPURegs(); - //FlushAllHWReg(); -} - -static void recLB() { -// Rt = mem[Rs + Im] (signed) - - /*if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - if (!_Rt_) return; - // since bios is readonly it won't change - MapConst(_Rt_, psxRs8(addr)); - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (!_Rt_) return; - - addr = (u32)&psxM[addr & 0x1fffff]; - LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct? - LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_)); - EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (!_Rt_) return; - - addr = (u32)&psxH[addr & 0xfff]; - LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct? - LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_)); - EXTSB(PutHWReg32(_Rt_), GetHWReg32(_Rt_)); - return; - } - // SysPrintf("unhandled r8 %x\n", addr); - }*/ - - preMemRead(); - CALLFunc((u32)psxMemRead8); - if (_Rt_) { - EXTSB(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL)); - DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL)); - } -} - -static void recLBU() { -// Rt = mem[Rs + Im] (unsigned) - - /*if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - if (!_Rt_) return; - // since bios is readonly it won't change - MapConst(_Rt_, psxRu8(addr)); - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (!_Rt_) return; - - addr = (u32)&psxM[addr & 0x1fffff]; - LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct? - LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (!_Rt_) return; - - addr = (u32)&psxH[addr & 0xfff]; - LIW(PutHWReg32(_Rt_), ((addr>>16)<<16)+(addr&0x8000<<1)); // FIXME: is this correct? - LBZ(PutHWReg32(_Rt_), addr&0xffff, GetHWReg32(_Rt_)); - return; - } - // SysPrintf("unhandled r8 %x\n", addr); - }*/ - - preMemRead(); - CALLFunc((u32)psxMemRead8); - - if (_Rt_) { - SetDstCPUReg(3); - PutHWReg32(_Rt_); - } -} - -static void recLH() { -// Rt = mem[Rs + Im] (signed) - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - if (!_Rt_) return; - // since bios is readonly it won't change - MapConst(_Rt_, psxRs16(addr)); - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]); - LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]); - LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - EXTSH(PutHWReg32(_Rt_), GetHWReg32(_Rt_)); - return; - } - // SysPrintf("unhandled r16 %x\n", addr); - } - - preMemRead(); - CALLFunc((u32)psxMemRead16); - if (_Rt_) { - EXTSH(PutHWReg32(_Rt_), GetHWRegSpecial(RETVAL)); - DisposeHWReg(GetSpecialIndexFromHWRegs(RETVAL)); - } -} - -static void recLHU() { -// Rt = mem[Rs + Im] (unsigned) - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - if (!_Rt_) return; - // since bios is readonly it won't change - MapConst(_Rt_, psxRu16(addr)); - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]); - LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]); - LHBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80) { - if (addr >= 0x1f801c00 && addr < 0x1f801e00) { - if (!_Rt_) return; - - ReserveArgs(1); - LIW(PutHWRegSpecial(ARG1), addr); - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)SPU_readRegister); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - } - switch (addr) { - case 0x1f801100: case 0x1f801110: case 0x1f801120: - if (!_Rt_) return; - - ReserveArgs(1); - LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3); - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)psxRcntRcount); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - - case 0x1f801104: case 0x1f801114: case 0x1f801124: - if (!_Rt_) return; - - ReserveArgs(1); - LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3); - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)psxRcntRmode); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - - case 0x1f801108: case 0x1f801118: case 0x1f801128: - if (!_Rt_) return; - - ReserveArgs(1); - LIW(PutHWRegSpecial(ARG1), (addr >> 4) & 0x3); - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)psxRcntRtarget); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - } - } - // SysPrintf("unhandled r16u %x\n", addr); - } - - preMemRead(); - CALLFunc((u32)psxMemRead16); - if (_Rt_) { - SetDstCPUReg(3); - PutHWReg32(_Rt_); - } -} - -static void recLW() { -// Rt = mem[Rs + Im] (unsigned) - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - if (!_Rt_) return; - // since bios is readonly it won't change - MapConst(_Rt_, psxRu32(addr)); - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxM[addr & 0x1fffff]); - LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xfff]); - LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - return; - } - if (t == 0x1f80) { - switch (addr) { - case 0x1f801080: case 0x1f801084: case 0x1f801088: - case 0x1f801090: case 0x1f801094: case 0x1f801098: - case 0x1f8010a0: case 0x1f8010a4: case 0x1f8010a8: - case 0x1f8010b0: case 0x1f8010b4: case 0x1f8010b8: - case 0x1f8010c0: case 0x1f8010c4: case 0x1f8010c8: - case 0x1f8010d0: case 0x1f8010d4: case 0x1f8010d8: - case 0x1f8010e0: case 0x1f8010e4: case 0x1f8010e8: - case 0x1f801070: case 0x1f801074: - case 0x1f8010f0: case 0x1f8010f4: - if (!_Rt_) return; - - LIW(PutHWReg32(_Rt_), (u32)&psxH[addr & 0xffff]); - LWBRX(PutHWReg32(_Rt_), 0, GetHWReg32(_Rt_)); - return; - - case 0x1f801810: - if (!_Rt_) return; - - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)GPU_readData); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - - case 0x1f801814: - if (!_Rt_) return; - - DisposeHWReg(iRegs[_Rt_].reg); - InvalidateCPURegs(); - CALLFunc((u32)GPU_readStatus); - - SetDstCPUReg(3); - PutHWReg32(_Rt_); - return; - } - } -// SysPrintf("unhandled r32 %x\n", addr); - } - - preMemRead(); - CALLFunc((u32)psxMemRead32); - if (_Rt_) { - SetDstCPUReg(3); - PutHWReg32(_Rt_); - } -} - -REC_FUNC(LWL); -REC_FUNC(LWR); -REC_FUNC(SWL); -REC_FUNC(SWR); -/*extern u32 LWL_MASK[4]; -extern u32 LWL_SHIFT[4]; - -void iLWLk(u32 shift) { - if (IsConst(_Rt_)) { - MOV32ItoR(ECX, iRegs[_Rt_].k); - } else { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - } - AND32ItoR(ECX, LWL_MASK[shift]); - SHL32ItoR(EAX, LWL_SHIFT[shift]); - OR32RtoR (EAX, ECX); -} - -void recLWL() { -// Rt = Rt Merge mem[Rs + Im] - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]); - iLWLk(addr & 3); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]); - iLWLk(addr & 3); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - return; - } - } - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - PUSH32R (EAX); - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead32); - - if (_Rt_) { - ADD32ItoR(ESP, 4); - POP32R (EDX); - AND32ItoR(EDX, 0x3); // shift = addr & 3; - - MOV32ItoR(ECX, (u32)LWL_SHIFT); - MOV32RmStoR(ECX, ECX, EDX, 2); - SHL32CLtoR(EAX); // mem(EAX) << LWL_SHIFT[shift] - - MOV32ItoR(ECX, (u32)LWL_MASK); - MOV32RmStoR(ECX, ECX, EDX, 2); - if (IsConst(_Rt_)) { - MOV32ItoR(EDX, iRegs[_Rt_].k); - } else { - MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]); - } - AND32RtoR(EDX, ECX); // _rRt_ & LWL_MASK[shift] - - OR32RtoR(EAX, EDX); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } else { -// ADD32ItoR(ESP, 8); - resp+= 8; - } -} - -static void recLWBlock(int count) { - u32 *code = PSXM(pc); - int i, respsave; -// Rt = mem[Rs + Im] (unsigned) - -// iFlushRegs(0); - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0xfff0) == 0xbfc0) { - // since bios is readonly it won't change - for (i=0; i<count; i++, code++, addr+=4) { - if (_fRt_(*code)) { - MapConst(_fRt_(*code), psxRu32(addr)); - } - } - return; - } - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - for (i=0; i<count; i++, code++, addr+=4) { - if (!_fRt_(*code)) return; - iRegs[_fRt_(*code)].state = ST_UNK; - - MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]); - MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX); - } - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - for (i=0; i<count; i++, code++, addr+=4) { - if (!_fRt_(*code)) return; - iRegs[_fRt_(*code)].state = ST_UNK; - - MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]); - MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX); - } - return; - } - } - - SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_)); - iPushOfB(); - CALLFunc((u32)psxMemPointer); -// ADD32ItoR(ESP, 4); - resp+= 4; - - respsave = resp; resp = 0; - TEST32RtoR(EAX, EAX); - j32Ptr[4] = JZ32(0); - XOR32RtoR(ECX, ECX); - for (i=0; i<count; i++, code++) { - if (_fRt_(*code)) { - iRegs[_fRt_(*code)].state = ST_UNK; - - MOV32RmStoR(EDX, EAX, ECX, 2); - MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EDX); - } - if (i != (count-1)) INC32R(ECX); - } - j32Ptr[5] = JMP32(0); - x86SetJ32(j32Ptr[4]); - for (i=0, code = PSXM(pc); i<count; i++, code++) { - psxRegs.code = *code; - recLW(); - } - ADD32ItoR(ESP, resp); - x86SetJ32(j32Ptr[5]); - resp = respsave; -} - -extern u32 LWR_MASK[4]; -extern u32 LWR_SHIFT[4]; - -void iLWRk(u32 shift) { - if (IsConst(_Rt_)) { - MOV32ItoR(ECX, iRegs[_Rt_].k); - } else { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - } - AND32ItoR(ECX, LWR_MASK[shift]); - SHR32ItoR(EAX, LWR_SHIFT[shift]); - OR32RtoR (EAX, ECX); -} - -void recLWR() { -// Rt = Rt Merge mem[Rs + Im] - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]); - iLWRk(addr & 3); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]); - iLWRk(addr & 3); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - return; - } - } - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - PUSH32R (EAX); - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - CALLFunc((u32)psxMemRead32); - - if (_Rt_) { - ADD32ItoR(ESP, 4); - POP32R (EDX); - AND32ItoR(EDX, 0x3); // shift = addr & 3; - - MOV32ItoR(ECX, (u32)LWR_SHIFT); - MOV32RmStoR(ECX, ECX, EDX, 2); - SHR32CLtoR(EAX); // mem(EAX) >> LWR_SHIFT[shift] - - MOV32ItoR(ECX, (u32)LWR_MASK); - MOV32RmStoR(ECX, ECX, EDX, 2); - - if (IsConst(_Rt_)) { - MOV32ItoR(EDX, iRegs[_Rt_].k); - } else { - MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]); - } - AND32RtoR(EDX, ECX); // _rRt_ & LWR_MASK[shift] - - OR32RtoR(EAX, EDX); - - iRegs[_Rt_].state = ST_UNK; - MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); - } else { -// ADD32ItoR(ESP, 8); - resp+= 8; - } -}*/ - -static void recSB() { -// mem[Rs + Im] = Rt - - /*if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (IsConst(_Rt_)) { - MOV8ItoM((u32)&psxM[addr & 0x1fffff], (u8)iRegs[_Rt_].k); - } else { - MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV8RtoM((u32)&psxM[addr & 0x1fffff], EAX); - } - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (IsConst(_Rt_)) { - MOV8ItoM((u32)&psxH[addr & 0xfff], (u8)iRegs[_Rt_].k); - } else { - MOV8MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV8RtoM((u32)&psxH[addr & 0xfff], EAX); - } - return; - } -// SysPrintf("unhandled w8 %x\n", addr); - }*/ - - preMemWrite(1); - CALLFunc((u32)psxMemWrite8); -} - -static void recSH() { -// mem[Rs + Im] = Rt - - /*if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - if (IsConst(_Rt_)) { - MOV16ItoM((u32)&psxM[addr & 0x1fffff], (u16)iRegs[_Rt_].k); - } else { - MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV16RtoM((u32)&psxM[addr & 0x1fffff], EAX); - } - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - if (IsConst(_Rt_)) { - MOV16ItoM((u32)&psxH[addr & 0xfff], (u16)iRegs[_Rt_].k); - } else { - MOV16MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); - MOV16RtoM((u32)&psxH[addr & 0xfff], EAX); - } - return; - } - if (t == 0x1f80) { - if (addr >= 0x1f801c00 && addr < 0x1f801e00) { - if (IsConst(_Rt_)) { - PUSH32I(iRegs[_Rt_].k); - } else { - PUSH32M((u32)&psxRegs.GPR.r[_Rt_]); - } - PUSH32I (addr); - CALL32M ((u32)&SPU_writeRegister); -#ifndef __WIN32__ - resp+= 8; -#endif - return; - } - } -// SysPrintf("unhandled w16 %x\n", addr); - }*/ - - preMemWrite(2); - CALLFunc((u32)psxMemWrite16); -} - -static void recSW() { -// mem[Rs + Im] = Rt - u32 *b1, *b2; -#if 0 - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - LIW(0, addr & 0x1fffff); - STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - LIW(0, (u32)&psxH[addr & 0xfff]); - STWBRX(GetHWReg32(_Rt_), 0, 0); - return; - } - if (t == 0x1f80) { - switch (addr) { - case 0x1f801080: case 0x1f801084: - case 0x1f801090: case 0x1f801094: - case 0x1f8010a0: case 0x1f8010a4: - case 0x1f8010b0: case 0x1f8010b4: - case 0x1f8010c0: case 0x1f8010c4: - case 0x1f8010d0: case 0x1f8010d4: - case 0x1f8010e0: case 0x1f8010e4: - case 0x1f801074: - case 0x1f8010f0: - LIW(0, (u32)&psxH[addr & 0xffff]); - STWBRX(GetHWReg32(_Rt_), 0, 0); - return; - -/* case 0x1f801810: - if (IsConst(_Rt_)) { - PUSH32I(iRegs[_Rt_].k); - } else { - PUSH32M((u32)&psxRegs.GPR.r[_Rt_]); - } - CALL32M((u32)&GPU_writeData); -#ifndef __WIN32__ - resp+= 4; -#endif - return; - - case 0x1f801814: - if (IsConst(_Rt_)) { - PUSH32I(iRegs[_Rt_].k); - } else { - PUSH32M((u32)&psxRegs.GPR.r[_Rt_]); - } - CALL32M((u32)&GPU_writeStatus); -#ifndef __WIN32__ - resp+= 4; -#endif*/ - } - } -// SysPrintf("unhandled w32 %x\n", addr); - } - -/* LIS(0, 0x0079 + ((_Imm_ <= 0) ? 1 : 0)); - CMPLW(GetHWReg32(_Rs_), 0); - BGE_L(b1); - - //SaveContext(); - ADDI(0, GetHWReg32(_Rs_), _Imm_); - RLWINM(0, GetHWReg32(_Rs_), 0, 11, 31); - STWBRX(GetHWReg32(_Rt_), GetHWRegSpecial(PSXMEM), 0); - B_L(b2); - - B_DST(b1);*/ -#endif - preMemWrite(4); - CALLFunc((u32)psxMemWrite32); - - //B_DST(b2); -} - -/* -static void recSWBlock(int count) { - u32 *code; - int i, respsave; -// mem[Rs + Im] = Rt - -// iFlushRegs(); - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - code = PSXM(pc); - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - for (i=0; i<count; i++, code++, addr+=4) { - if (IsConst(_fRt_(*code))) { - MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_fRt_(*code)].k); - } else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_fRt_(*code)]); - MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX); - } - } - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - for (i=0; i<count; i++, code++, addr+=4) { - if (!_fRt_(*code)) return; - iRegs[_fRt_(*code)].state = ST_UNK; - - MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]); - MOV32RtoM((u32)&psxRegs.GPR.r[_fRt_(*code)], EAX); - } - return; - } - } - - SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_)); - iPushOfB(); - CALLFunc((u32)psxMemPointer); -// ADD32ItoR(ESP, 4); - resp+= 4; - - respsave = resp; resp = 0; - TEST32RtoR(EAX, EAX); - j32Ptr[4] = JZ32(0); - XOR32RtoR(ECX, ECX); - for (i=0, code = PSXM(pc); i<count; i++, code++) { - if (IsConst(_fRt_(*code))) { - MOV32ItoR(EDX, iRegs[_fRt_(*code)].k); - } else { - MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_fRt_(*code)]); - } - MOV32RtoRmS(EAX, ECX, 2, EDX); - if (i != (count-1)) INC32R(ECX); - } - j32Ptr[5] = JMP32(0); - x86SetJ32(j32Ptr[4]); - for (i=0, code = PSXM(pc); i<count; i++, code++) { - psxRegs.code = *code; - recSW(); - } - ADD32ItoR(ESP, resp); - x86SetJ32(j32Ptr[5]); - resp = respsave; -} - -extern u32 SWL_MASK[4]; -extern u32 SWL_SHIFT[4]; - -void iSWLk(u32 shift) { - if (IsConst(_Rt_)) { - MOV32ItoR(ECX, iRegs[_Rt_].k); - } else { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - } - SHR32ItoR(ECX, SWL_SHIFT[shift]); - AND32ItoR(EAX, SWL_MASK[shift]); - OR32RtoR (EAX, ECX); -} - -void recSWL() { -// mem[Rs + Im] = Rt Merge mem[Rs + Im] - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]); - iSWLk(addr & 3); - MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]); - iSWLk(addr & 3); - MOV32RtoM((u32)&psxH[addr & 0xffc], EAX); - return; - } - } - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - PUSH32R (EAX); - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - - CALLFunc((u32)psxMemRead32); - - ADD32ItoR(ESP, 4); - POP32R (EDX); - AND32ItoR(EDX, 0x3); // shift = addr & 3; - - MOV32ItoR(ECX, (u32)SWL_MASK); - MOV32RmStoR(ECX, ECX, EDX, 2); - AND32RtoR(EAX, ECX); // mem & SWL_MASK[shift] - - MOV32ItoR(ECX, (u32)SWL_SHIFT); - MOV32RmStoR(ECX, ECX, EDX, 2); - if (IsConst(_Rt_)) { - MOV32ItoR(EDX, iRegs[_Rt_].k); - } else { - MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]); - } - SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift] - - OR32RtoR (EAX, EDX); - PUSH32R (EAX); - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - - CALLFunc((u32)psxMemWrite32); -// ADD32ItoR(ESP, 8); - resp+= 8; -} - -extern u32 SWR_MASK[4]; -extern u32 SWR_SHIFT[4]; - -void iSWRk(u32 shift) { - if (IsConst(_Rt_)) { - MOV32ItoR(ECX, iRegs[_Rt_].k); - } else { - MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); - } - SHL32ItoR(ECX, SWR_SHIFT[shift]); - AND32ItoR(EAX, SWR_MASK[shift]); - OR32RtoR (EAX, ECX); -} - -void recSWR() { -// mem[Rs + Im] = Rt Merge mem[Rs + Im] - - if (IsConst(_Rs_)) { - u32 addr = iRegs[_Rs_].k + _Imm_; - int t = addr >> 16; - - if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) { - MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]); - iSWRk(addr & 3); - MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX); - return; - } - if (t == 0x1f80 && addr < 0x1f801000) { - MOV32MtoR(EAX, (u32)&psxH[addr & 0xffc]); - iSWRk(addr & 3); - MOV32RtoM((u32)&psxH[addr & 0xffc], EAX); - return; - } - } - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - PUSH32R (EAX); - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - - CALLFunc((u32)psxMemRead32); - - ADD32ItoR(ESP, 4); - POP32R (EDX); - AND32ItoR(EDX, 0x3); // shift = addr & 3; - - MOV32ItoR(ECX, (u32)SWR_MASK); - MOV32RmStoR(ECX, ECX, EDX, 2); - AND32RtoR(EAX, ECX); // mem & SWR_MASK[shift] - - MOV32ItoR(ECX, (u32)SWR_SHIFT); - MOV32RmStoR(ECX, ECX, EDX, 2); - if (IsConst(_Rt_)) { - MOV32ItoR(EDX, iRegs[_Rt_].k); - } else { - MOV32MtoR(EDX, (u32)&psxRegs.GPR.r[_Rt_]); - } - SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift] - - OR32RtoR (EAX, EDX); - PUSH32R (EAX); - - if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); - else { - MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); - if (_Imm_) ADD32ItoR(EAX, _Imm_); - } - AND32ItoR(EAX, ~3); - PUSH32R (EAX); - - CALLFunc((u32)psxMemWrite32); -// ADD32ItoR(ESP, 8); - resp+= 8; -}*/ -#endif - -#if 0 -/*REC_FUNC(SLL); -REC_FUNC(SRL); -REC_FUNC(SRA);*/ -#else -static void recSLL() { -// Rd = Rt << Sa - if (!_Rd_) return; - - if (IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rt_].k << _Sa_); - } else { - SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_); - } -} - -static void recSRL() { -// Rd = Rt >> Sa - if (!_Rd_) return; - - if (IsConst(_Rt_)) { - MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_); - } else { - SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_); - } -} - -static void recSRA() { -// Rd = Rt >> Sa - if (!_Rd_) return; - - if (IsConst(_Rt_)) { - MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_); - } else { - SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), _Sa_); - } -} -#endif - -#pragma mark - shift ops - -#if 0 -/*REC_FUNC(SLLV); -REC_FUNC(SRLV); -REC_FUNC(SRAV);*/ -#else -static void recSLLV() { -// Rd = Rt << Rs - if (!_Rd_) return; - - if (IsConst(_Rt_) && IsConst(_Rs_)) { - MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - SLWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - SLW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_)); - } -} - -static void recSRLV() { -// Rd = Rt >> Rs - if (!_Rd_) return; - - if (IsConst(_Rt_) && IsConst(_Rs_)) { - MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - SRWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - SRW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_)); - } -} - -static void recSRAV() { -// Rd = Rt >> Rs - if (!_Rd_) return; - - if (IsConst(_Rt_) && IsConst(_Rs_)) { - MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k); - } else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - SRAWI(PutHWReg32(_Rd_), GetHWReg32(_Rt_), iRegs[_Rs_].k); - } else { - SRAW(PutHWReg32(_Rd_), GetHWReg32(_Rt_), GetHWReg32(_Rs_)); - } -} -#endif - -//REC_SYS(SYSCALL); -//REC_SYS(BREAK); - -//#if 0*/ -/*int dump;*/ -static void recSYSCALL() { -// dump=1; - iFlushRegs(0); - - ReserveArgs(2); - LIW(PutHWRegSpecial(PSXPC), pc - 4); - LIW(PutHWRegSpecial(ARG1), 0x20); - LIW(PutHWRegSpecial(ARG2), (branch == 1 ? 1 : 0)); - FlushAllHWReg(); - CALLFunc ((u32)psxException); - - branch = 2; - iRet(); -} - -static void recBREAK() { -} -//#endif - -#if 0 -/*REC_FUNC(MFHI); -REC_FUNC(MTHI); -REC_FUNC(MFLO); -REC_FUNC(MTLO);*/ -#else -static void recMFHI() { -// Rd = Hi - if (!_Rd_) return; - - if (IsConst(REG_HI)) { - MapConst(_Rd_, iRegs[REG_HI].k); - } else { - MapCopy(_Rd_, REG_HI); - } -} - -static void recMTHI() { -// Hi = Rs - - if (IsConst(_Rs_)) { - MapConst(REG_HI, iRegs[_Rs_].k); - } else { - MapCopy(REG_HI, _Rs_); - } -} - -static void recMFLO() { -// Rd = Lo - if (!_Rd_) return; - - if (IsConst(REG_LO)) { - MapConst(_Rd_, iRegs[REG_LO].k); - } else { - MapCopy(_Rd_, REG_LO); - } -} - -static void recMTLO() { -// Lo = Rs - - if (IsConst(_Rs_)) { - MapConst(REG_LO, iRegs[_Rs_].k); - } else { - MapCopy(REG_LO, _Rs_); - } -} -#endif - -#pragma mark - branch ops - -#if 0 -/*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);*/ -#else -static void recBLTZ() { -// Branch if Rs < 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k < 0) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BLT_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; -} - -static void recBGTZ() { -// Branch if Rs > 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k > 0) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BGT_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; -} - -static void recBLTZAL() { -// Branch if Rs < 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k < 0) { - MapConst(31, pc + 4); - - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BLT_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - MapConst(31, pc + 4); - - iBranch(bpc, 0); - pc+=4; -} - -static void recBGEZAL() { -// Branch if Rs >= 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k >= 0) { - MapConst(31, pc + 4); - - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BGE_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - MapConst(31, pc + 4); - - iBranch(bpc, 0); - pc+=4; -} - -static void recJ() { -// j target - - iJump(_Target_ * 4 + (pc & 0xf0000000)); -} - -static void recJAL() { -// jal target - MapConst(31, pc + 4); - - iJump(_Target_ * 4 + (pc & 0xf0000000)); -} - -static void recJR() { -// jr Rs - - if (IsConst(_Rs_)) { - iJump(iRegs[_Rs_].k); - //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k); - } else { - MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_)); - SetBranch(); - } -} - -static void recJALR() { -// jalr Rs - - if (_Rd_) { - MapConst(_Rd_, pc + 4); - } - - if (IsConst(_Rs_)) { - iJump(iRegs[_Rs_].k); - //LIW(PutHWRegSpecial(TARGET), iRegs[_Rs_].k); - } else { - MR(PutHWRegSpecial(TARGET), GetHWReg32(_Rs_)); - SetBranch(); - } -} - -static void recBEQ() { -// Branch if Rs == Rt - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (_Rs_ == _Rt_) { - iJump(bpc); - } - else { - if (IsConst(_Rs_) && IsConst(_Rt_)) { - if (iRegs[_Rs_].k == iRegs[_Rt_].k) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k); - } - else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) { - CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k); - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k); - } - else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) { - CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k); - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - - BEQ_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; - } -} - -static void recBNE() { -// Branch if Rs != Rt - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (_Rs_ == _Rt_) { - iJump(pc+4); - } - else { - if (IsConst(_Rs_) && IsConst(_Rt_)) { - if (iRegs[_Rs_].k != iRegs[_Rt_].k) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - else if (IsConst(_Rs_) && !IsMapped(_Rs_)) { - if ((iRegs[_Rs_].k & 0xffff) == iRegs[_Rs_].k) { - CMPLWI(GetHWReg32(_Rt_), iRegs[_Rs_].k); - } - else if ((s32)(s16)iRegs[_Rs_].k == (s32)iRegs[_Rs_].k) { - CMPWI(GetHWReg32(_Rt_), iRegs[_Rs_].k); - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - else if (IsConst(_Rt_) && !IsMapped(_Rt_)) { - if ((iRegs[_Rt_].k & 0xffff) == iRegs[_Rt_].k) { - CMPLWI(GetHWReg32(_Rs_), iRegs[_Rt_].k); - } - else if ((s32)(s16)iRegs[_Rt_].k == (s32)iRegs[_Rt_].k) { - CMPWI(GetHWReg32(_Rs_), iRegs[_Rt_].k); - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - } - else { - CMPLW(GetHWReg32(_Rs_), GetHWReg32(_Rt_)); - } - - BNE_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; - } -} - -static void recBLEZ() { -// Branch if Rs <= 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k <= 0) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BLE_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; -} - -static void recBGEZ() { -// Branch if Rs >= 0 - u32 bpc = _Imm_ * 4 + pc; - u32 *b; - - if (IsConst(_Rs_)) { - if ((s32)iRegs[_Rs_].k >= 0) { - iJump(bpc); return; - } else { - iJump(pc+4); return; - } - } - - CMPWI(GetHWReg32(_Rs_), 0); - BGE_L(b); - - iBranch(pc+4, 1); - - B_DST(b); - - iBranch(bpc, 0); - pc+=4; -} -#endif - -#if 1 -//REC_FUNC(MFC0); -//REC_SYS(MTC0); -//REC_FUNC(CFC0); -//REC_SYS(CTC0); -REC_FUNC(RFE); -//#else -static void recMFC0() { -// Rt = Cop0->Rd - if (!_Rt_) return; - - LWZ(PutHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS)); -} - -static void recCFC0() { -// Rt = Cop0->Rd - - recMFC0(); -} - -static void recMTC0() { -// Cop0->Rd = Rt - - /*if (IsConst(_Rt_)) { - switch (_Rd_) { - case 12: - MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k); - break; - case 13: - MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k & ~(0xfc00)); - break; - default: - MOV32ItoM((u32)&psxRegs.CP0.r[_Rd_], iRegs[_Rt_].k); - break; - } - } else*/ { - switch (_Rd_) { - case 13: - RLWINM(0,GetHWReg32(_Rt_),0,22,15); // & ~(0xfc00) - STW(0, OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS)); - break; - default: - STW(GetHWReg32(_Rt_), OFFSET(&psxRegs, &psxRegs.CP0.r[_Rd_]), GetHWRegSpecial(PSXREGS)); - break; - } - } - - if (_Rd_ == 12 || _Rd_ == 13) { - iFlushRegs(0); - LIW(PutHWRegSpecial(PSXPC), (u32)pc); - FlushAllHWReg(); - CALLFunc((u32)psxTestSWInts); - if(_Rd_ == 12) { - LWZ(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS)); - ORIS(0, 0, 0x8000); - STW(0, OFFSET(&psxRegs, &psxRegs.interrupt), GetHWRegSpecial(PSXREGS)); - } - branch = 2; - iRet(); - } -} - -static void recCTC0() { -// Cop0->Rd = Rt - - recMTC0(); -} -#else -static void recRFE() { - // TODO: implement multiple temp registers or cop0 registers - RLWINM(t1,Status,0,0,27); - RLWINM(Status,Status,30,28,31); - OR(Status,t1,Status); - - 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); - CALLFunc((u32)psxExceptionTest); -} -#endif - -#if 0 -#define CP2_FUNC(f) \ -void gte##f(); \ -static void rec##f() { \ - iFlushRegs(0); \ - LIW(0, (u32)psxRegs.code); \ - STW(0, OFFSET(&psxRegs, &psxRegs.code), GetHWRegSpecial(PSXREGS)); \ - FlushAllHWReg(); \ - CALLFunc ((u32)gte##f); \ -} -CP2_FUNC(LWC2); -CP2_FUNC(SWC2); - -#else -#include "pGte.h" -#endif -// - -static void recHLE() { - iFlushRegs(0); - FlushAllHWReg(); - - if ((psxRegs.code & 0x3ffffff) == (psxRegs.code & 0x7)) { - CALLFunc((u32)psxHLEt[psxRegs.code & 0x7]); - } else { - // somebody else must have written to current opcode for this to happen!!!! - CALLFunc((u32)psxHLEt[0]); // call dummy function - } - - count = (idlecyclecount + (pc - pcold) / 4 + 20) * BIAS; - ADDI(PutHWRegSpecial(CYCLECOUNT), GetHWRegSpecial(CYCLECOUNT), count); - FlushAllHWReg(); - CALLFunc((u32)psxBranchTest); - Return(); - - 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() { - //static int recCount = 0; - char *p; - u32 *ptr; - int i; - - cop2readypc = 0; - idlecyclecount = 0; - - // initialize state variables - UniqueRegAlloc = 1; - HWRegUseCount = 0; - DstCPUReg = -1; - memset(HWRegisters, 0, sizeof(HWRegisters)); - for (i=0; i<NUM_HW_REGISTERS; i++) - HWRegisters[i].code = cpuHWRegisters[NUM_HW_REGISTERS-i-1]; - - // reserve the special psxReg register - HWRegisters[0].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED; - HWRegisters[0].private = PSXREGS; - HWRegisters[0].k = (u32)&psxRegs; - - HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED; - HWRegisters[1].private = PSXMEM; - HWRegisters[1].k = (u32)&psxM; - - // reserve the special psxRegs.cycle register - //HWRegisters[1].usage = HWUSAGE_SPECIAL | HWUSAGE_RESERVED | HWUSAGE_HARDWIRED; - //HWRegisters[1].private = CYCLECOUNT; - - //memset(iRegs, 0, sizeof(iRegs)); - for (i=0; i<NUM_REGISTERS; i++) { - iRegs[i].state = ST_UNK; - iRegs[i].reg = -1; - } - iRegs[0].k = 0; - iRegs[0].state = ST_CONST; - - /* if ppcPtr reached the mem limit reset whole mem */ - if (((u32)ppcPtr - (u32)recMem) >= (RECMEM_SIZE - 0x10000)) - recReset(); - - ppcAlign(/*32*/4); - ptr = ppcPtr; - - // give us write access - //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE); - - // tell the LUT where to find us - PC_REC32(psxRegs.pc) = (u32)ppcPtr; - - pcold = pc = psxRegs.pc; - - //SysPrintf("RecCount: %i\n", recCount++); - - for (count=0; count<500;) { - p = (char *)PSXM(pc); - if (p == NULL) recError(); - psxRegs.code = SWAP32(*(u32 *)p); -/* - if ((psxRegs.code >> 26) == 0x23) { // LW - int i; - u32 code; - - for (i=1;; i++) { - p = (char *)PSXM(pc+i*4); - if (p == NULL) recError(); - code = *(u32 *)p; - - if ((code >> 26) != 0x23 || - _fRs_(code) != _Rs_ || - _fImm_(code) != (_Imm_+i*4)) - break; - } - if (i > 1) { - recLWBlock(i); - pc = pc + i*4; continue; - } - } - - if ((psxRegs.code >> 26) == 0x2b) { // SW - int i; - u32 code; - - for (i=1;; i++) { - p = (char *)PSXM(pc+i*4); - if (p == NULL) recError(); - code = *(u32 *)p; - - if ((code >> 26) != 0x2b || - _fRs_(code) != _Rs_ || - _fImm_(code) != (_Imm_+i*4)) - break; - } - if (i > 1) { - recSWBlock(i); - pc = pc + i*4; continue; - } - }*/ - - pc+=4; count++; -// iFlushRegs(0); // test - recBSC[psxRegs.code>>26](); - - if (branch) { - branch = 0; - //if (dump) iDumpBlock(ptr); - goto done; - } - } - - iFlushRegs(pc); - - LIW(PutHWRegSpecial(PSXPC), pc); - - iRet(); - -done:; -#if 0 - MakeDataExecutable(ptr, ((u8*)ppcPtr)-((u8*)ptr)); -#else - u32 a = (u32)(u8*)ptr; - while(a < (u32)(u8*)ppcPtr) { - __asm__ __volatile__("icbi 0,%0" : : "r" (a)); - __asm__ __volatile__("dcbst 0,%0" : : "r" (a)); - a += 4; - } - __asm__ __volatile__("sync"); - __asm__ __volatile__("isync"); -#endif - -#if 1 - sprintf((char *)ppcPtr, "PC=%08x", pcold); - ppcPtr += strlen((char *)ppcPtr); -#endif - - //mprotect(recMem, RECMEM_SIZE, PROT_EXEC|PROT_READ/*|PROT_WRITE*/); -} - - -R3000Acpu psxRec = { - recInit, - recReset, - recExecute, - recExecuteBlock, - recClear, - recShutdown -}; - diff --git a/libpcsxcore/ppc/pasm.s b/libpcsxcore/ppc/pasm.s deleted file mode 100644 index 96891b4..0000000 --- a/libpcsxcore/ppc/pasm.s +++ /dev/null @@ -1,124 +0,0 @@ - - -#define OLD_REGISTER_OFFSET (19*4) -#define SP_SIZE (OLD_REGISTER_OFFSET+4+8) - -/*asm void recRun(register void (*func)(), register u32 hw1, register u32 hw2)*/ - .text - .align 4 - .globl recRun -recRun: - /* prologue code */ - mflr r0 - stmw r13, -(32-13)*4(r1) - stw r0, 4(r1) - stwu r1, -((32-13)*4+8)(r1) - - /* execute code */ - mtctr r3 - mr r31, r4 - mr r30, r5 - bctrl -/* -} -asm void returnPC() -{*/ - .text - .align 4 - .globl returnPC -returnPC: - // end code - lwz r0, (32-13)*4+8+4(r1) - addi r1, r1, (32-13)*4+8 - mtlr r0 - lmw r13, -(32-13)*4(r1) - blr -//}*/ - -// Memory functions that only works with a linear memory - - .text - .align 4 - .globl dynMemRead8 -dynMemRead8: -// assumes that memory pointer is in r30 - addis r2,r3,-0x1f80 - srwi. r4,r2,16 - bne+ .norm8 - cmplwi r2,0x1000 - blt- .norm8 - b psxHwRead8 -.norm8: - clrlwi r5,r3,3 - lbzx r3,r5,r30 - blr - - .text - .align 4 - .globl dynMemRead16 -dynMemRead16: -// assumes that memory pointer is in r30 - addis r2,r3,-0x1f80 - srwi. r4,r2,16 - bne+ .norm16 - cmplwi r2,0x1000 - blt- .norm16 - b psxHwRead16 -.norm16: - clrlwi r5,r3,3 - lhbrx r3,r5,r30 - blr - - .text - .align 4 - .globl dynMemRead32 -dynMemRead32: -// assumes that memory pointer is in r30 - addis r2,r3,-0x1f80 - srwi. r4,r2,16 - bne+ .norm32 - cmplwi r2,0x1000 - blt- .norm32 - b psxHwRead32 -.norm32: - clrlwi r5,r3,3 - lwbrx r3,r5,r30 - blr - -/* - N P Z - 0 0 0 X -- 0 0 1 X - 1 0 0 X - 1 0 1 X - -P | (!N & Z) -P | !(N | !Z) -*/ - - .text - .align 4 - .globl dynMemWrite32 -dynMemWrite32: -// assumes that memory pointer is in r30 - addis r2,r3,-0x1f80 - srwi. r5,r2,16 - bne+ .normw32 - cmplwi r2,0x1000 - blt .normw32 - b psxHwWrite32 -.normw32: - mtcrf 0xFF, r3 - clrlwi r5,r3,3 - crandc 0, 2, 0 - cror 2, 1, 0 - bne+ .okw32 - // write test - li r2,0x0130 - addis r2,r2,0xfffe - cmplw r3,r2 - bnelr -.okw32: - stwbrx r4,r5,r30 - blr - diff --git a/libpcsxcore/ppc/ppc.c b/libpcsxcore/ppc/ppc.c deleted file mode 100644 index efaf8b6..0000000 --- a/libpcsxcore/ppc/ppc.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ix86 core v0.5.1 - * Authors: linuzappz <linuzappz@pcsx.net> - * alexey silinov - */ - -#include <stdio.h> -#include <string.h> - -#include "ppc.h" - -// General Purpose hardware registers -int cpuHWRegisters[NUM_HW_REGISTERS] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 -}; - -u32 *ppcPtr; - -void ppcInit() { -} -void ppcSetPtr(u32 *ptr) { - ppcPtr = ptr; -} -void ppcAlign(int bytes) { - // forward align - ppcPtr = (u32*)(((u32)ppcPtr + bytes) & ~(bytes - 1)); -} - -void ppcShutdown() { -} - diff --git a/libpcsxcore/ppc/ppc.h b/libpcsxcore/ppc/ppc.h deleted file mode 100644 index a6134d4..0000000 --- a/libpcsxcore/ppc/ppc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * ppc definitions v0.5.1 - * Authors: linuzappz <linuzappz@pcsx.net> - * alexey silinov - */ - -#ifndef __PPC_H__ -#define __PPC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -// include basic types -#include "../psxcommon.h" -#include "ppc_mnemonics.h" - -#define NUM_HW_REGISTERS 29 - -/* general defines */ -#define write8(val) *(u8 *)ppcPtr = val; ppcPtr++; -#define write16(val) *(u16*)ppcPtr = val; ppcPtr+=2; -#define write32(val) *(u32*)ppcPtr = val; ppcPtr+=4; -#define write64(val) *(u64*)ppcPtr = val; ppcPtr+=8; - -#define CALLFunc(FUNC) \ -{ \ - u32 _func = (FUNC); \ - ReleaseArgs(); \ - if ((_func & 0x1fffffc) == _func) { \ - BLA(_func); \ - } else { \ - LIW(0, _func); \ - MTCTR(0); \ - BCTRL(); \ - } \ -} - -extern int cpuHWRegisters[NUM_HW_REGISTERS]; - -extern u32 *ppcPtr; -extern u8 *j8Ptr[32]; -extern u32 *j32Ptr[32]; - -void ppcInit(); -void ppcSetPtr(u32 *ptr); -void ppcShutdown(); - -void ppcAlign(int bytes); -void returnPC(); -void recRun(void (*func)(), u32 hw1, u32 hw2); -u8 dynMemRead8(u32 mem); -u16 dynMemRead16(u32 mem); -u32 dynMemRead32(u32 mem); -void dynMemWrite32(u32 mem, u32 val); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/libpcsxcore/ppc/ppc_mnemonics.h b/libpcsxcore/ppc/ppc_mnemonics.h deleted file mode 100644 index 3cc6525..0000000 --- a/libpcsxcore/ppc/ppc_mnemonics.h +++ /dev/null @@ -1,529 +0,0 @@ -// ppc_mnemonics.h - -#define INSTR (*(ppcPtr)++) - -/* Link register related */ -#define MFLR(REG) \ - {int _reg = (REG); \ - INSTR = (0x7C0802A6 | (_reg << 21));} - -#define MTLR(REG) \ - {int _reg = (REG); \ - INSTR = (0x7C0803A6 | (_reg << 21));} - -#define MTCTR(REG) \ - {int _reg = (REG); \ - INSTR = (0x7C0903A6 | (_reg << 21));} - -#define BLR() \ - {INSTR = (0x4E800020);} - -#define BGTLR() \ - {INSTR = (0x4D810020);} - - -/* Load ops */ -#define LI(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x38000000 | (_reg << 21) | ((IMM) & 0xffff));} - -#define LIS(REG_DST, IMM) \ - {int _dst = (REG_DST); \ - INSTR = (0x3C000000 | (_dst << 21) | ((IMM) & 0xffff));} - -#define LWZ(REG_DST, OFFSET, REG) \ - {int _reg = (REG); int _dst=(REG_DST); \ - INSTR = (0x80000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define LWZX(REG_DST, REG, REG_OFF) \ - {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \ - INSTR = (0x7C00002E | (_dst << 21) | (_reg << 16) | (_off << 11));} - -#define LWBRX(REG_DST, REG, REG_OFF) \ - {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \ - INSTR = (0x7C00042C | (_dst << 21) | (_reg << 16) | (_off << 11));} - -#define LHZ(REG_DST, OFFSET, REG) \ - {int _reg = (REG); int _dst=(REG_DST); \ - INSTR = (0xA0000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define LHA(REG_DST, OFFSET, REG) \ - {int _reg = (REG); int _dst=(REG_DST); \ - INSTR = (0xA8000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define LHBRX(REG_DST, REG, REG_OFF) \ - {int _reg = (REG), _off = (REG_OFF); int _dst=(REG_DST); \ - INSTR = (0x7C00062C | (_dst << 21) | (_reg << 16) | (_off << 11));} - -#define LBZ(REG_DST, OFFSET, REG) \ - {int _reg = (REG); int _dst=(REG_DST); \ - INSTR = (0x88000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define LMW(REG_DST, OFFSET, REG) \ - {int _reg = (REG); int _dst=(REG_DST); \ - INSTR = (0xB8000000 | (_dst << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - - - -/* Store ops */ -#define STMW(REG_SRC, OFFSET, REG) \ - {int _reg = (REG), _src=(REG_SRC); \ - INSTR = (0xBC000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define STW(REG_SRC, OFFSET, REG) \ - {int _reg = (REG), _src=(REG_SRC); \ - INSTR = (0x90000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define STWBRX(REG_SRC, REG, REG_OFF) \ - {int _reg = (REG), _src=(REG_SRC), _off = (REG_OFF); \ - INSTR = (0x7C00052C | (_src << 21) | (_reg << 16) | (_off << 11));} - -#define STH(REG_SRC, OFFSET, REG) \ - {int _reg = (REG), _src=(REG_SRC); \ - INSTR = (0xB0000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define STHBRX(REG_SRC, REG, REG_OFF) \ - {int _reg = (REG), _src=(REG_SRC), _off = (REG_OFF); \ - INSTR = (0x7C00072C | (_src << 21) | (_reg << 16) | (_off << 11));} - -#define STB(REG_SRC, OFFSET, REG) \ - {int _reg = (REG), _src=(REG_SRC); \ - INSTR = (0x98000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - -#define STWU(REG_SRC, OFFSET, REG) \ - {int _reg = (REG), _src=(REG_SRC); \ - INSTR = (0x94000000 | (_src << 21) | (_reg << 16) | ((OFFSET) & 0xffff));} - - -/* Arithmic ops */ -#define ADDI(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x38000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));} - -#define ADDIS(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x3C000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));} - -#define MR(REG_DST, REG_SRC) \ - {int __src = (REG_SRC); int __dst=(REG_DST); \ - if (__src != __dst) {ADDI(__dst, __src, 0)}} - -#define ADD(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000214 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define ADDO(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000614 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define ADDEO(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000514 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define ADDE(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000114 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define ADDCO(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000414 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define ADDIC(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x30000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));} - -#define ADDIC_(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x34000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));} - -#define ADDZE(REG_DST, REG_SRC) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x7C000194 | (_dst << 21) | (_src << 16));} - -#define SUBF(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000050 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUBFO(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000450 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUBFC(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000010 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUBFE(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000110 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUBFCO(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000410 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUBFCO_(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000411 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define SUB(REG_DST, REG1, REG2) \ - {SUBF(REG_DST, REG2, REG1)} - -#define SUBO(REG_DST, REG1, REG2) \ - {SUBFO(REG_DST, REG2, REG1)} - -#define SUBCO(REG_DST, REG1, REG2) \ - {SUBFCO(REG_DST, REG2, REG1)} - -#define SUBCO_(REG_DST, REG1, REG2) \ - {SUBFCO_(REG_DST, REG2, REG1)} - -#define SRAWI(REG_DST, REG_SRC, SHIFT) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x7C000670 | (_src << 21) | (_dst << 16) | (SHIFT << 11));} - -#define MULHW(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000096 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define MULLW(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C0001D6 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define MULHWU(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000016 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define MULLI(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x1C000000 | (_dst << 21) | (_src << 16) | ((IMM) & 0xffff));} - -#define DIVW(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C0003D6 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - -#define DIVWU(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000396 | (_dst << 21) | (_reg1 << 16) | (_reg2 << 11));} - - -/* Branch ops */ -#define B_FROM(VAR) VAR = ppcPtr -#define B_DST(VAR) *VAR = *VAR | (((s16)((u32)ppcPtr - (u32)VAR)) & 0xfffc) - -#define B(DST) \ - {INSTR = (0x48000000 | (((s32)(((DST)+1)<<2)) & 0x3fffffc));} - -#define B_L(VAR) \ - {B_FROM(VAR); INSTR = (0x48000000);} - -#define BA(DST) \ - {INSTR = (0x48000002 | ((s32)((DST) & 0x3fffffc)));} - -#define BLA(DST) \ - {INSTR = (0x48000003 | ((s32)((DST) & 0x3fffffc)));} - -#define BNS(DST) \ - {INSTR = (0x40830000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BNE(DST) \ - {INSTR = (0x40820000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BNE_L(VAR) \ - {B_FROM(VAR); INSTR = (0x40820000);} - -#define BEQ(DST) \ - {INSTR = (0x41820000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BEQ_L(VAR) \ - {B_FROM(VAR); INSTR = (0x41820000);} - -#define BLT(DST) \ - {INSTR = (0x41800000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BLT_L(VAR) \ - {B_FROM(VAR); INSTR = (0x41800000);} - -#define BGT(DST) \ - {INSTR = (0x41810000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BGT_L(VAR) \ - {B_FROM(VAR); INSTR = (0x41810000);} - -#define BGE(DST) \ - {INSTR = (0x40800000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BGE_L(VAR) \ - {B_FROM(VAR); INSTR = (0x40800000);} - -#define BLE(DST) \ - {INSTR = (0x40810000 | (((s16)(((DST)+1)<<2)) & 0xfffc));} - -#define BLE_L(VAR) \ - {B_FROM(VAR); INSTR = (0x40810000);} - -#define BCTRL() \ - {INSTR = (0x4E800421);} - -#define BCTR() \ - {INSTR = (0x4E800420);} - - -/* compare ops */ -#define CMPLWI(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x28000000 | (_reg << 16) | ((IMM) & 0xffff));} - -#define CMPLWI2(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x29000000 | (_reg << 16) | ((IMM) & 0xffff));} - -#define CMPLWI7(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x2B800000 | (_reg << 16) | ((IMM) & 0xffff));} - -#define CMPLW(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7C000040 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPLW1(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7C800040 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPLW2(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7D000040 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPW(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7C000000 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPW1(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7C800000 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPW2(REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); \ - INSTR = (0x7D000000 | (_reg1 << 16) | (_reg2 << 11));} - -#define CMPWI(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x2C000000 | (_reg << 16) | ((IMM) & 0xffff));} - -#define CMPWI2(REG, IMM) \ - {int _reg = (REG); \ - INSTR = (0x2D000000 | (_reg << 16) | ((IMM) & 0xffff));} - -#define MTCRF(MASK, REG) \ - {int _reg = (REG); \ - INSTR = (0x7C000120 | (_reg << 21) | (((MASK)&0xff)<<12));} - -#define MFCR(REG) \ - {int _reg = (REG); \ - INSTR = (0x7C000026 | (_reg << 21));} - -#define CROR(CR_DST, CR1, CR2) \ - {INSTR = (0x4C000382 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));} - -#define CRXOR(CR_DST, CR1, CR2) \ - {INSTR = (0x4C000182 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));} - -#define CRNAND(CR_DST, CR1, CR2) \ - {INSTR = (0x4C0001C2 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));} - -#define CRANDC(CR_DST, CR1, CR2) \ - {INSTR = (0x4C000102 | ((CR_DST) << 21) | ((CR1) << 16) | ((CR2) << 11));} - - -/* shift ops */ -#define RLWINM(REG_DST, REG_SRC, SHIFT, START, END) \ - {int _src = (REG_SRC); int _dst = (REG_DST); \ - INSTR = (0x54000000 | (_src << 21) | (_dst << 16) | (SHIFT << 11) | (START << 6) | (END << 1));} - -#define RLWINM_(REG_DST, REG_SRC, SHIFT, START, END) \ - {int _src = (REG_SRC); int _dst = (REG_DST); \ - INSTR = (0x54000001 | (_src << 21) | (_dst << 16) | (SHIFT << 11) | (START << 6) | (END << 1));} - -#define CLRRWI(REG_DST, REG_SRC, LEN) \ - RLWINM(REG_DST, REG_SRC, 0, 0, 31-LEN) - -#define SLWI(REG_DST, REG_SRC, SHIFT) \ - {int _shift = (SHIFT); \ - if (_shift==0) {MR(REG_DST, REG_SRC)} else \ - {RLWINM(REG_DST, REG_SRC, _shift, 0, 31-_shift)}} - -#define SRWI(REG_DST, REG_SRC, SHIFT) \ - {int _shift = (SHIFT); \ - if (_shift==0) {MR(REG_DST, REG_SRC)} else \ - RLWINM(REG_DST, REG_SRC, 32-_shift, _shift, 31)} - -#define SLW(REG_DST, REG_SRC, REG_SHIFT) \ - {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \ - INSTR = (0x7C000030 | (_src << 21) | (_dst << 16) | (_shift << 11));} - -#define SRW(REG_DST, REG_SRC, REG_SHIFT) \ - {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \ - INSTR = (0x7C000430 | (_src << 21) | (_dst << 16) | (_shift << 11));} - -#define SRAW(REG_DST, REG_SRC, REG_SHIFT) \ - {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \ - INSTR = (0x7C000630 | (_src << 21) | (_dst << 16) | (_shift << 11));} - -#define SRAWI(REG_DST, REG_SRC, SHIFT) \ - {int _src = (REG_SRC); int _dst = (REG_DST); int _shift = (SHIFT); \ - if (_shift==0) {MR(REG_DST, REG_SRC)} else \ - INSTR = (0x7C000670 | (_src << 21) | (_dst << 16) | (_shift << 11));} - -#define RLWNM(REG_DST, REG_SRC, REG_SHIFT, START, END) \ - {int _src = (REG_SRC), _shift = (REG_SHIFT); int _dst = (REG_DST); \ - INSTR = (0x5C000000 | (_src << 21) | (_dst << 16) | (_shift << 11) | (START << 6) | (END << 1));} - -/* other ops */ -#define ORI(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC), _imm = (IMM); int _dst = (REG_DST); \ - if (!((_imm == 0) && ((_src^_dst) == 0))) \ - INSTR = (0x60000000 | (_src << 21) | (_dst << 16) | (_imm & 0xffff));} - -#define ORIS(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC), _imm = (IMM); int _dst = (REG_DST); \ - if (!((_imm == 0) && ((_src^_dst) == 0))) \ - INSTR = (0x64000000 | (_src << 21) | (_dst << 16) | (_imm & 0xffff));} - -#define OR(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000378 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define OR_(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000379 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define XORI(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x68000000 | (_src << 21) | (_dst << 16) | ((IMM) & 0xffff));} - -#define XOR(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000278 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define XOR_(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000279 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define ANDI_(REG_DST, REG_SRC, IMM) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x70000000 | (_src << 21) | (_dst << 16) | ((IMM) & 0xffff));} - -#define AND(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C000038 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define NOR(REG_DST, REG1, REG2) \ - {int _reg1 = (REG1), _reg2 = (REG2); int _dst=(REG_DST); \ - INSTR = (0x7C0000f8 | (_reg1 << 21) | (_dst << 16) | (_reg2 << 11));} - -#define NEG(REG_DST, REG_SRC) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x7C0000D0 | (_dst << 21) | (_src << 16));} - -#define NOP() \ - {INSTR = 0x60000000;} - -#define MCRXR(CR_DST) \ - {INSTR = (0x7C000400 | (CR_DST << 23));} - -#define EXTSB(REG_DST, REG_SRC) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x7C000774 | (_src << 21) | (_dst << 16));} - -#define EXTSH(REG_DST, REG_SRC) \ - {int _src = (REG_SRC); int _dst=(REG_DST); \ - INSTR = (0x7C000734 | (_src << 21) | (_dst << 16));} - - -/* floating point ops */ -#define FDIVS(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xEC000024 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FDIV(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xFC000024 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FMULS(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xEC000032 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FMUL(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xFC000032 | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FADDS(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xEC00002A | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FADD(FPR_DST, FPR1, FPR2) \ - {INSTR = (0xFC00002A | (FPR_DST << 21) | (FPR1 << 16) | (FPR2 << 11));} - -#define FRSP(FPR_DST, FPR_SRC) \ - {INSTR = (0xFC000018 | (FPR_DST << 21) | (FPR_SRC << 11));} - -#define FCTIW(FPR_DST, FPR_SRC) \ - {INSTR = (0xFC00001C | (FPR_DST << 21) | (FPR_SRC << 11));} - - -#define LFS(FPR_DST, OFFSET, REG) \ - {INSTR = (0xC0000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));} - -#define STFS(FPR_DST, OFFSET, REG) \ - {INSTR = (0xD0000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));} - -#define LFD(FPR_DST, OFFSET, REG) \ - {INSTR = (0xC8000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));} - -#define STFD(FPR_DST, OFFSET, REG) \ - {INSTR = (0xD8000000 | (FPR_DST << 21) | (REG << 16) | ((OFFSET) & 0xffff));} - - - -/* extra combined opcodes */ -#if 1 -#define LIW(REG, IMM) /* Load Immidiate Word */ \ -{ \ - int __reg = (REG); u32 __imm = (u32)(IMM); \ - if ((s32)__imm == (s32)((s16)__imm)) \ - { \ - LI(__reg, (s32)((s16)__imm)); \ - } else if (__reg == 0) { \ - LIS(__reg, (((u32)__imm)>>16)); \ - if ((((u32)__imm) & 0xffff) != 0) \ - { \ - ORI(__reg, __reg, __imm); \ - } \ - } else { \ - if ((((u32)__imm) & 0xffff) == 0) { \ - LIS(__reg, (((u32)__imm)>>16)); \ - } else { \ - LI(__reg, __imm); \ - if ((__imm & 0x8000) == 0) { \ - ADDIS(__reg, __reg, ((u32)__imm)>>16); \ - } else { \ - ADDIS(__reg, __reg, ((((u32)__imm)>>16) & 0xffff) + 1); \ - } \ - } \ - /*if ((((u32)__imm) & 0xffff) != 0) \ - { \ - ORI(__reg, __reg, __imm); \ - }*/ \ - } \ -} -#else -#define LIW(REG, IMM) /* Load Immidiate Word */ \ -{ \ - int __reg = (REG); u32 __imm = (u32)(IMM); \ - if ((s32)__imm == (s32)((s16)__imm)) \ - { \ - LI(__reg, (s32)((s16)__imm)); \ - } \ - else \ - { \ - LIS(__reg, (((u32)__imm)>>16)); \ - if ((((u32)__imm) & 0xffff) != 0) \ - { \ - ORI(__reg, __reg, __imm); \ - } \ - } \ -} -#endif diff --git a/libpcsxcore/ppc/reguse.c b/libpcsxcore/ppc/reguse.c deleted file mode 100644 index 47d70a5..0000000 --- a/libpcsxcore/ppc/reguse.c +++ /dev/null @@ -1,419 +0,0 @@ - -#include "../psxcommon.h" -#include "reguse.h" - -#include "../r3000a.h" - -//#define SAME_CYCLE_MODE - -static const int useBSC[64] = { - /*recSPECIAL*/ REGUSE_SUB | REGUSE_SPECIAL, - /*recREGIMM*/ REGUSE_SUB | REGUSE_REGIMM, - /*recJ*/ REGUSE_JUMP, - /*recJAL*/ REGUSE_JUMP | REGUSE_R31_W, - /*recBEQ*/ REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R, - /*recBNE*/ REGUSE_BRANCH | REGUSE_RS_R | REGUSE_RT_R, - /*recBLEZ*/ REGUSE_BRANCH | REGUSE_RS_R, - /*recBGTZ*/ REGUSE_BRANCH | REGUSE_RS_R, - /*recADDI*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, - /*recADDIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, - /*recSLTI*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, - /*recSLTIU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_W, - /*recANDI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, - /*recORI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, - /*recXORI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_W, - /*recLUI*/ REGUSE_ACC | REGUSE_RT_W, - /*recCOP0*/ REGUSE_SUB | REGUSE_COP0, - REGUSE_NONE, - /*recCOP2*/ REGUSE_SUB | REGUSE_COP2, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recLB*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, - /*recLH*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, - /*recLWL*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT, - /*recLW*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, - /*recLBU*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, - /*recLHU*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT_W, - /*recLWR*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_RT, - REGUSE_NONE, - /*recSB*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, - /*recSH*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, - /*recSWL*/ REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R, - /*recSW*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_RT_R, - REGUSE_NONE, REGUSE_NONE, - /*recSWR*/ REGUSE_MEM | REGUSE_RS_R | REGUSE_RT_R, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recLWC2*/ REGUSE_MEM_R | REGUSE_RS_R | REGUSE_COP2_RT_W, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, - /*recSWC2*/ REGUSE_MEM_W | REGUSE_RS_R | REGUSE_COP2_RT_R, - /*recHLE*/ REGUSE_UNKNOWN, // TODO: can this be done in a better way - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE -}; - -static const int useSPC[64] = { - /*recSLL*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, - REGUSE_NONE, - /*recSRL*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, - /*recSRA*/ REGUSE_ACC | REGUSE_RT_R | REGUSE_RD_W, - /*recSLLV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - REGUSE_NONE, - /*recSRLV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recSRAV*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recJR*/ REGUSE_JUMPR | REGUSE_RS_R, - /*recJALR*/ REGUSE_JUMPR | REGUSE_RS_R | REGUSE_RD_W, - REGUSE_NONE, REGUSE_NONE, - /*rSYSCALL*/ REGUSE_SYS | REGUSE_PC | REGUSE_COP0_STATUS | REGUSE_EXCEPTION, - /*recBREAK*/ REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, - /*recMFHI*/ REGUSE_LOGIC | REGUSE_RD_W | REGUSE_HI_R, - /*recMTHI*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_HI_W, - /*recMFLO*/ REGUSE_LOGIC | REGUSE_RD_W | REGUSE_LO_R, - /*recMTLO*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_LO_W, - REGUSE_NONE, REGUSE_NONE , REGUSE_NONE, REGUSE_NONE, - /*recMULT*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, - /*recMULTU*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, - /*recDIV*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, - /*recDIVU*/ REGUSE_MULT | REGUSE_RS_R | REGUSE_RT_R | REGUSE_LO_W | REGUSE_HI_W, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recADD*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recADDU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recSUB*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recSUBU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recAND*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recXOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recNOR*/ REGUSE_LOGIC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - REGUSE_NONE, REGUSE_NONE, - /*recSLT*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - /*recSLTU*/ REGUSE_ACC | REGUSE_RS_R | REGUSE_RT_R | REGUSE_RD_W, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE -}; - -static const int useREGIMM[32] = { - /*recBLTZ*/ REGUSE_BRANCH | REGUSE_RS_R, - /*recBGEZ*/ REGUSE_BRANCH | REGUSE_RS_R, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, - /*recBLTZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W, - /*recBGEZAL*/REGUSE_BRANCH | REGUSE_RS_R | REGUSE_R31_W, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE -}; - -static const int useCP0[32] = { - /*recMFC0*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R, - REGUSE_NONE, - /*recCFC0*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP0_RD_R, - REGUSE_NONE, - /*recMTC0*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W, - REGUSE_NONE, - /*recCTC0*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP0_RD_W, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recRFE*/ REGUSE_LOGIC | REGUSE_COP0_STATUS, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE -}; - -// TODO: make more explicit -static const int useCP2[64] = { - /*recBASIC*/ REGUSE_SUB | REGUSE_BASIC, - /*recRTPS*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recNCLIP*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recOP*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recDPCS*/ REGUSE_GTE, - /*recINTPL*/ REGUSE_GTE, - /*recMVMVA*/ REGUSE_GTE, - /*recNCDS*/ REGUSE_GTE, - /*recCDP*/ REGUSE_GTE, - REGUSE_NONE, - /*recNCDT*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recNCCS*/ REGUSE_GTE, - /*recCC*/ REGUSE_GTE, - REGUSE_NONE, - /*recNCS*/ REGUSE_GTE, - REGUSE_NONE, - /*recNCT*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, - /*recSQR*/ REGUSE_GTE, - /*recDCPL*/ REGUSE_GTE, - /*recDPCT*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, - /*recAVSZ3*/ REGUSE_GTE, - /*recAVSZ4*/ REGUSE_GTE, - REGUSE_NONE, - /*recRTPT*/ REGUSE_GTE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, REGUSE_NONE, - /*recGPF*/ REGUSE_GTE, - /*recGPL*/ REGUSE_GTE, - /*recNCCT*/ REGUSE_GTE -}; - -static const int useCP2BSC[32] = { - /*recMFC2*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R, - REGUSE_NONE, - /*recCFC2*/ REGUSE_LOGIC | REGUSE_RT_W | REGUSE_COP2_RD_R, - REGUSE_NONE, - /*recMTC2*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W, - REGUSE_NONE, - /*recCTC2*/ REGUSE_LOGIC | REGUSE_RT_R | REGUSE_COP2_RD_W, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE, - REGUSE_NONE -}; - -static int getRegUse(u32 code) __attribute__ ((__pure__)); -static int getRegUse(u32 code) -{ - int use = useBSC[code>>26]; - - switch (use & REGUSE_SUBMASK) { - case REGUSE_NONE: - break; - case REGUSE_SPECIAL: - use = useSPC[_fFunct_(code)]; - break; - case REGUSE_REGIMM: - use = useREGIMM[_fRt_(code)]; - break; - case REGUSE_COP0: - use = useCP0[_fRs_(code)]; - break; - case REGUSE_COP2: - use = useCP2[_fFunct_(code)]; - if ((use & REGUSE_SUBMASK) == REGUSE_BASIC) - use = useCP2BSC[_fRs_(code)]; - break; - default: - use = REGUSE_UNKNOWN; - break; - } - - if ((use & REGUSE_COP0_RD_W)) { - if (_fRd_(code) == 12 || _fRd_(code) == 13) { - use = REGUSE_UNKNOWN; - } - } - - return use; -} - -/* returns how psxreg is used in the code instruction */ -int useOfPsxReg(u32 code, int use, int psxreg) -{ - int retval = REGUSE_NONE; - - // get use if it wasn't supplied - if (-1 == use) use = getRegUse(code); - - // if we don't know what the usage is, assume it's read from - if (REGUSE_UNKNOWN == use) return REGUSE_READ; - - if (psxreg < 32) { - // check for 3 standard types - if ((use & REGUSE_RT) && _fRt_(code) == (u32)psxreg) { - retval |= ((use & REGUSE_RT_R) ? REGUSE_READ:0) | ((use & REGUSE_RT_W) ? REGUSE_WRITE:0); - } - if ((use & REGUSE_RS) && _fRs_(code) == (u32)psxreg) { - retval |= ((use & REGUSE_RS_R) ? REGUSE_READ:0) | ((use & REGUSE_RS_W) ? REGUSE_WRITE:0); - } - if ((use & REGUSE_RD) && _fRd_(code) == (u32)psxreg) { - retval |= ((use & REGUSE_RD_R) ? REGUSE_READ:0) | ((use & REGUSE_RD_W) ? REGUSE_WRITE:0); - } - // some instructions explicitly writes to r31 - if ((use & REGUSE_R31_W) && 31 == psxreg) { - retval |= REGUSE_WRITE; - } - } else if (psxreg == 32) { // Special register LO - retval |= ((use & REGUSE_LO_R) ? REGUSE_READ:0) | ((use & REGUSE_LO_W) ? REGUSE_WRITE:0); - } else if (psxreg == 33) { // Special register HI - retval |= ((use & REGUSE_HI_R) ? REGUSE_READ:0) | ((use & REGUSE_HI_W) ? REGUSE_WRITE:0); - } - - return retval; -} - -//#define NOREGUSE_FOLLOW - -static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr) __attribute__ ((__pure__, __unused__)); -static int _nextPsxRegUse(u32 pc, int psxreg, int numInstr) -{ - u32 *ptr, code, bPC = 0; - int i, use, reguse = 0; - - for (i=0; i<numInstr; ) { - // load current instruction - ptr = PSXM(pc); - if (ptr==NULL) { - // going nowhere... might as well assume a write, since we will hopefully never reach here - reguse = REGUSE_WRITE; - break; - } - code = SWAP32(*ptr); - // get usage patterns for instruction - use = getRegUse(code); - // find the use of psxreg in the instruction - reguse = useOfPsxReg(code, use, psxreg); - - // return if we have found a use - if (reguse != REGUSE_NONE) - break; - - // goto next instruction - pc += 4; - i++; - - // check for code branches/jumps - if (i != numInstr) { - if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) { -#ifndef NOREGUSE_FOLLOW - // check delay slot - reguse = _nextPsxRegUse(pc, psxreg, 1); - if (reguse != REGUSE_NONE) break; - - bPC = _fImm_(code) * 4 + pc; - reguse = _nextPsxRegUse(pc+4, psxreg, (numInstr-i-1)/2); - if (reguse != REGUSE_NONE) { - int reguse2 = _nextPsxRegUse(bPC, psxreg, (numInstr-i-1)/2); - if (reguse2 != REGUSE_NONE) - reguse |= reguse2; - else - reguse = REGUSE_NONE; - } -#endif - break; - } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) { -#ifndef NOREGUSE_FOLLOW - // check delay slot - reguse = _nextPsxRegUse(pc, psxreg, 1); - if (reguse != REGUSE_NONE) break; - - bPC = _fTarget_(code) * 4 + (pc & 0xf0000000); - reguse = _nextPsxRegUse(bPC, psxreg, numInstr-i-1); -#endif - break; - } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR) { -#ifndef NOREGUSE_FOLLOW - // jump to unknown location - bail after checking delay slot - reguse = _nextPsxRegUse(pc, psxreg, 1); -#endif - break; - } else if ((use & REGUSE_TYPEM) == REGUSE_SYS) { - break; - } - } - } - - return reguse; -} - - -int nextPsxRegUse(u32 pc, int psxreg) -{ -#if 1 - if (psxreg == 0) - return REGUSE_WRITE; // pretend we are writing to it to fool compiler - -#ifdef SAME_CYCLE_MODE - return REGUSE_READ; -#else - return _nextPsxRegUse(pc, psxreg, 80); -#endif -#else - u32 code, bPC = 0; - int use, reguse = 0, reguse1 = 0, b = 0, i, index = 0; - -retry: - for (i=index; i<80; i++) { - code = PSXMu32(pc); - use = getRegUse(code); - reguse = useOfPsxReg(code, use, psxreg); - - if (reguse != REGUSE_NONE) break; - - pc += 4; - if ((use & REGUSE_TYPEM) == REGUSE_BRANCH) { - if (b == 0) { - bPC = _fImm_(code) * 4 + pc; - index = i+1; - } - b += 1; // TODO: follow branches - continue; - } else if ((use & REGUSE_TYPEM) == REGUSE_JUMP) { - if (b == 0) { - bPC = _fTarget_(code) * 4 + (pc & 0xf0000000); - } - b = 2; - continue; - } else if ((use & REGUSE_TYPEM) == REGUSE_JUMPR || - (use & REGUSE_TYPEM) == REGUSE_SYS) { - b = 2; - continue; - } - - if (b == 2 && bPC && index == 0) { - pc = bPC; bPC = 0; - b = 1; - } - if (b >= 2) break; // only follow 1 branch - } - if (reguse == REGUSE_NONE) return reguse; - - if (bPC) { - reguse1 = reguse; - pc = bPC; bPC = 0; - b = 1; - goto retry; - } - - return reguse1 | reguse; -#endif -} - -int isPsxRegUsed(u32 pc, int psxreg) -{ - int use = nextPsxRegUse(pc, psxreg); - - if (use == REGUSE_NONE) - return 2; // unknown use - assume it is used - else if (use & REGUSE_READ) - return 1; // the next use is a read - else - return 0; // the next use is a write, i.e. current value is not important -} diff --git a/libpcsxcore/ppc/reguse.h b/libpcsxcore/ppc/reguse.h deleted file mode 100644 index de42dec..0000000 --- a/libpcsxcore/ppc/reguse.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef __REGUSE_H__ -#define __REGUSE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -// include basic types -#include "../psxcommon.h" - -#define REGUSE_NONE 0x0000 -#define REGUSE_UNKNOWN 0x0001 - -//sub functions -#define REGUSE_SPECIAL 0x0002 -#define REGUSE_REGIMM 0x0004 -#define REGUSE_COP0 0x0006 -#define REGUSE_COP2 0x0008 -#define REGUSE_BASIC 0x000a -#define REGUSE_SUBMASK 0x000e /* sub function mask */ - -#define REGUSE_ACC 0x0010 /* accumulator */ -#define REGUSE_LOGIC 0x0020 /* logic operations */ -#define REGUSE_MULT 0x0030 /* multiplier */ -#define REGUSE_JUMP 0x0040 /* jump to dest */ -#define REGUSE_JUMPR 0x0050 /* jump to reg */ -#define REGUSE_BRANCH 0x0060 /* branch */ -#define REGUSE_MEM_R 0x0070 /* read from memory */ -#define REGUSE_MEM_W 0x0080 /* write to memory */ -#define REGUSE_MEM 0x0090 /* read and write to memory */ -#define REGUSE_SYS 0x00a0 /* syscall */ -#define REGUSE_GTE 0x00b0 /* gte operation */ -#define REGUSE_SUB 0x00f0 /* sub usage */ -#define REGUSE_TYPEM 0x00f0 /* type mask */ - - -#define REGUSE_RS_R 0x0100 -#define REGUSE_RS_W 0x0200 -#define REGUSE_RS (REGUSE_RS_R | REGUSE_RS_W) -#define REGUSE_RT_R 0x0400 -#define REGUSE_RT_W 0x0800 -#define REGUSE_RT (REGUSE_RT_R | REGUSE_RT_W) -#define REGUSE_RD_R 0x1000 -#define REGUSE_RD_W 0x2000 -#define REGUSE_RD (REGUSE_RD_R | REGUSE_RD_W) - -#define REGUSE_R31_W 0x4000 /* writes to link register (r31) */ -#define REGUSE_PC 0x8000 /* reads pc */ - -#define REGUSE_LO_R 0x10000 -#define REGUSE_LO_W 0x20000 -#define REGUSE_LO (REGUSE_LO_R | REGUSE_LO_W) -#define REGUSE_HI_R 0x40000 -#define REGUSE_HI_W 0x80000 -#define REGUSE_HI (REGUSE_HI_R | REGUSE_HI_W) - -#define REGUSE_COP0_RD_R 0x100000 -#define REGUSE_COP0_RD_W 0x200000 -#define REGUSE_COP0_RD (REGUSE_COP0_RD_R | REGUSE_COP0_RD_W) -#define REGUSE_COP0_STATUS 0x400000 -#define REGUSE_EXCEPTION 0x800000 - -#define REGUSE_COP2_RT_R 0x1000000 -#define REGUSE_COP2_RT_W 0x2000000 -#define REGUSE_COP2_RT (REGUSE_COP2_RT_R | REGUSE_COP2_RT_W) -#define REGUSE_COP2_RD_R 0x4000000 -#define REGUSE_COP2_RD_W 0x8000000 -#define REGUSE_COP2_RD (REGUSE_COP2_RD_R | REGUSE_COP2_RD_W) - - -// specific register use -#define REGUSE_READ 1 -#define REGUSE_WRITE 2 -#define REGUSE_RW 3 - -int useOfPsxReg(u32 code, int use, int psxreg) __attribute__ ((__pure__));; -int nextPsxRegUse(u32 pc, int psxreg) __attribute__ ((__pure__));; -int isPsxRegUsed(u32 pc, int psxreg) __attribute__ ((__pure__));; - -#ifdef __cplusplus -} -#endif -#endif |