summaryrefslogtreecommitdiff
path: root/libpcsxcore/ix86
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2011-03-13 08:26:16 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2011-03-13 08:26:16 +0000
commit379a8879f7dae1a9074317c0270e12dd203b32c0 (patch)
tree348efb7ecd4f7cbc030f4b5db6683a857f2ae6cf /libpcsxcore/ix86
parentd34b4220bde29d7937d927e9d17a50470a36c500 (diff)
downloadpcsxr-379a8879f7dae1a9074317c0270e12dd203b32c0.tar.gz
Temporarily reverted r64524 until I (or someone else) find the time to sort out the stuff.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@64536 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'libpcsxcore/ix86')
-rw-r--r--libpcsxcore/ix86/iR3000A.c6007
-rw-r--r--libpcsxcore/ix86/ix86.c3454
2 files changed, 4736 insertions, 4725 deletions
diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c
index 291a1770..a1c761ec 100644
--- a/libpcsxcore/ix86/iR3000A.c
+++ b/libpcsxcore/ix86/iR3000A.c
@@ -1,2998 +1,3009 @@
-/***************************************************************************
- * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, 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. *
- ***************************************************************************/
-
-/*
-* i386 assembly functions for R3000A core.
-*/
-
-#ifdef __i386__
-
-#include "ix86.h"
-#include <sys/mman.h>
-
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-u32 *psxRecLUT;
-
-#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 RECMEM_SIZE (8 * 1024 * 1024)
-
-static char *recMem; /* the recompiled blocks will be here */
-static char *recRAM; /* and the ptr to the blocks here */
-static char *recROM; /* and here */
-
-static u32 pc; /* recompiler pc */
-static u32 pcold; /* recompiler oldpc */
-static int count; /* recompiler intruction count */
-static int branch; /* set for branch */
-static u32 target; /* branch target */
-static u32 resp;
-
-typedef struct {
- int state;
- u32 k;
- int reg;
-} iRegisters;
-
-static iRegisters iRegs[32];
-static iRegisters iRegsS[32];
-
-#define ST_UNK 0
-#define ST_CONST 1
-#define ST_MAPPED 2
-
-#define IsConst(reg) (iRegs[reg].state == ST_CONST)
-#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 DYNAREC_BLOCK 50
-
-static void MapConst(int reg, u32 _const) {
- iRegs[reg].k = _const;
- iRegs[reg].state = ST_CONST;
-}
-
-static void iFlushReg(int reg) {
- if (IsConst(reg)) {
- MOV32ItoM((u32)&psxRegs.GPR.r[reg], iRegs[reg].k);
- }
- iRegs[reg].state = ST_UNK;
-}
-
-static void iFlushRegs() {
- int i;
-
- for (i=1; i<32; i++) {
- iFlushReg(i);
- }
-}
-
-static void iRet() {
- /* store cycle */
- count = ((pc - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
- RET();
-}
-
-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() {
- branch = 1;
- psxRegs.code = PSXMu32(pc);
- pc += 4;
-
- if (iLoadTest() == 1) {
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
- /* store cycle */
- count = ((pc - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
-
- PUSH32M((u32)&target);
- PUSH32I(_Rt_);
- CALLFunc((u32)psxDelayTest);
- ADD32ItoR(ESP, 2*4);
-
- RET();
- return;
- }
- switch( psxRegs.code >> 26 ) {
- // Lode Runner (jr - beq)
-
- // bltz - bgez - bltzal - bgezal / beq - bne - blez - bgtz
- case 0x01:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- break;
-
- default:
- recBSC[psxRegs.code>>26]();
- break;
- }
-
- iFlushRegs();
- MOV32MtoR(EAX, (u32)&target);
- MOV32RtoM((u32)&psxRegs.pc, EAX);
- CALLFunc((u32)psxBranchTest);
-
- iRet();
-}
-
-static void iJump(u32 branchPC) {
- branch = 1;
- psxRegs.code = PSXMu32(pc);
- pc+=4;
-
- if (iLoadTest() == 1) {
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
- /* store cycle */
- count = ((pc - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
-
- PUSH32I(branchPC);
- PUSH32I(_Rt_);
- CALLFunc((u32)psxDelayTest);
- ADD32ItoR(ESP, 2*4);
-
- RET();
- return;
- }
-
- recBSC[psxRegs.code>>26]();
-
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.pc, branchPC);
- CALLFunc((u32)psxBranchTest);
- /* store cycle */
- count = ((pc - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
-
- // maybe just happened an interruption, check so
- CMP32ItoM((u32)&psxRegs.pc, branchPC);
- j8Ptr[0] = JE8(0);
- RET();
-
- x86SetJ8(j8Ptr[0]);
- MOV32MtoR(EAX, PC_REC(branchPC));
- TEST32RtoR(EAX, EAX);
- j8Ptr[1] = JNE8(0);
- RET();
-
- x86SetJ8(j8Ptr[1]);
- RET();
- JMP32R(EAX);
-}
-
-static void iBranch(u32 branchPC, int savectx) {
- u32 respold=0;
-
- if (savectx) {
- respold = resp;
- memcpy(iRegsS, iRegs, sizeof(iRegs));
- }
-
- 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();
- MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
- /* store cycle */
- count = (((pc+4) - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
-
- PUSH32I(branchPC);
- PUSH32I(_Rt_);
- CALLFunc((u32)psxDelayTest);
- ADD32ItoR(ESP, 2*4);
-
- RET();
- return;
- }
-
- pc+= 4;
- recBSC[psxRegs.code>>26]();
-
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.pc, branchPC);
- CALLFunc((u32)psxBranchTest);
- /* store cycle */
- count = ((pc - pcold) / 4) * BIAS;
- ADD32ItoM((u32)&psxRegs.cycle, count);
- if (resp) ADD32ItoR(ESP, resp);
-
- // 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));
- }
-}
-
-
-char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
-char *txt1 = "EAX = %x\n";
-char *txt2 = "M32 = %x\n";
-
-void iLogX86() {
- PUSHA32();
-
- PUSH32R (EDX);
- PUSH32R (ECX);
- PUSH32R (EAX);
- PUSH32M ((u32)&txt0);
- CALLFunc ((u32)SysPrintf);
- ADD32ItoR(ESP, 4*4);
-
- POPA32();
-}
-
-void iLogEAX() {
- PUSH32R (EAX);
- PUSH32M ((u32)&txt1);
- CALLFunc ((u32)SysPrintf);
- ADD32ItoR(ESP, 4*2);
-}
-
-void iLogM32(u32 mem) {
- PUSH32M (mem);
- PUSH32M ((u32)&txt2);
- CALLFunc ((u32)SysPrintf);
- ADD32ItoR(ESP, 4*2);
-}
-
-static void iDumpRegs() {
- int i, j;
-
- printf("%x %x\n", psxRegs.pc, psxRegs.cycle);
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 8; j++)
- printf("%x ", psxRegs.GPR.r[j * i]);
- printf("\n");
- }
-}
-
-void iDumpBlock(char *ptr) {
- FILE *f;
- u32 i;
- char buf[100];
-
- SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxRegs.cycle);
-
- 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);
- sprintf(buf, "objdump -m i386 -M i386 -D -b binary --adjust-vma=0x%lx dump1", (unsigned long)ptr);
- system(buf);
-}
-
-#define REC_FUNC(f) \
-void psx##f(); \
-static void rec##f() { \
- iFlushRegs(); \
- MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
- MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
- CALLFunc((u32)psx##f); \
-/* branch = 2; */\
-}
-
-#define REC_SYS(f) \
-void psx##f(); \
-static void rec##f() { \
- iFlushRegs(); \
- MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
- MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
- CALLFunc((u32)psx##f); \
- branch = 2; \
- iRet(); \
-}
-
-#define REC_BRANCH(f) \
-void psx##f(); \
-static void rec##f() { \
- iFlushRegs(); \
- MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
- MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
- CALLFunc((u32)psx##f); \
- branch = 2; \
- iRet(); \
-}
-
-static void recRecompile();
-
-static int recInit() {
- int i;
-
- psxRecLUT = (u32 *)malloc(0x010000 * 4);
-
- recMem = mmap(0, RECMEM_SIZE + 0x1000,
- PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-
- recRAM = (char *)malloc(0x200000);
- recROM = (char *)malloc(0x080000);
- if (recRAM == NULL || recROM == NULL || recMem == NULL || psxRecLUT == NULL) {
- 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 void recReset() {
- memset(recRAM, 0, 0x200000);
- memset(recROM, 0, 0x080000);
-
- x86Init();
-
- x86SetPtr(recMem);
-
- branch = 0;
- memset(iRegs, 0, sizeof(iRegs));
- iRegs[0].state = ST_CONST;
- iRegs[0].k = 0;
-}
-
-static void recShutdown() {
- if (recMem == NULL) return;
- free(psxRecLUT);
- munmap(recMem, RECMEM_SIZE + 0x1000);
- free(recRAM);
- free(recROM);
- x86Shutdown();
-}
-
-static void recError() {
- SysReset();
- ClosePlugins();
- SysMessage("Unrecoverable error while running recompiler\n");
- SysRunGui();
-}
-
-__inline static void execute() {
- void (**recFunc)() = NULL;
- char *p;
-
- p = (char *)PC_REC(psxRegs.pc);
- if (p != NULL) recFunc = (void (**)()) (u32)p;
- else { recError(); return; }
-
- if (*recFunc == 0) {
- recRecompile();
- }
- (*recFunc)();
-}
-
-static void recExecute() {
- for (;;) execute();
-}
-
-static void recExecuteBlock() {
- execute();
-}
-
-static void recClear(u32 Addr, u32 Size) {
- u32 bank,offset;
-
- bank = Addr >> 24;
- offset = Addr & 0xffffff;
-
-
- // Pitfall 3D - clear dynarec slots that contain 'stale' ram data
- // - fixes stage 1 loading crash
- if( bank == 0x80 || bank == 0xa0 || bank == 0x00 ) {
- offset &= 0x1fffff;
-
- if( offset >= DYNAREC_BLOCK * 4 )
- memset((void*)PC_REC(Addr - DYNAREC_BLOCK * 4), 0, DYNAREC_BLOCK * 4);
- else
- memset((void*)PC_REC(Addr - offset), 0, offset);
- }
-
-
- 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() {
- MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
- AND32ItoR(EAX, 0x40000000);
- j8Ptr[31] = JZ8(0);
-
- recCP2[_Funct_]();
-
- x86SetJ8(j8Ptr[31]);
-}
-
-static void recBASIC() {
- recCP2BSC[_Rs_]();
-}
-
-//end of Tables opcodes...
-
-/*********************************************************
-* Arithmetic with immediate operand *
-* Format: OP rt, rs, immediate *
-*********************************************************/
-
-/*REC_FUNC(ADDI);
-REC_FUNC(ADDIU);
-REC_FUNC(ANDI);
-REC_FUNC(ORI);
-REC_FUNC(XORI);
-REC_FUNC(SLTI);
-REC_FUNC(SLTIU);
-#if 0*/
-static void recADDIU() {
-// Rt = Rs + Im
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (_Rs_ == _Rt_) {
- if (IsConst(_Rt_)) {
- iRegs[_Rt_].k+= _Imm_;
- } else {
- if (_Imm_ == 1) {
- INC32M((u32)&psxRegs.GPR.r[_Rt_]);
- } else if (_Imm_ == -1) {
- DEC32M((u32)&psxRegs.GPR.r[_Rt_]);
- } else if (_Imm_) {
- ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_);
- }
- }
- } else {
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- if (_Imm_ == 1) {
- INC32R(EAX);
- } else if (_Imm_ == -1) {
- DEC32R(EAX);
- } else if (_Imm_) {
- ADD32ItoR(EAX, _Imm_);
- }
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
- }
-}
-
-static void recADDI() {
-// Rt = Rs + Im
- recADDIU();
-}
-
-static void recSLTI() {
-// Rt = Rs < Im (signed)
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32ItoR(EAX, _Imm_);
- SETL8R (EAX);
- AND32ItoR(EAX, 0xff);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-}
-
-static void recSLTIU() {
-// Rt = Rs < Im (unsigned)
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32ItoR(EAX, _Imm_);
- SETB8R (EAX);
- AND32ItoR(EAX, 0xff);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-}
-
-static void recANDI() {
-// Rt = Rs And Im
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (_Rs_ == _Rt_) {
- if (IsConst(_Rt_)) {
- iRegs[_Rt_].k&= _ImmU_;
- } else {
- AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
- }
- } else {
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- AND32ItoR(EAX, _ImmU_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
- }
-}
-
-static void recORI() {
-// Rt = Rs Or Im
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (_Rs_ == _Rt_) {
- if (IsConst(_Rt_)) {
- iRegs[_Rt_].k|= _ImmU_;
- } else {
- OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
- }
- } else {
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- if (_ImmU_) OR32ItoR (EAX, _ImmU_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
- }
-}
-
-static void recXORI() {
-// Rt = Rs Xor Im
- if (!_Rt_) return;
-
-// iFlushRegs();
-
- if (_Rs_ == _Rt_) {
- if (IsConst(_Rt_)) {
- iRegs[_Rt_].k^= _ImmU_;
- } else {
- XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
- }
- } else {
- if (IsConst(_Rs_)) {
- MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
- } else {
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- XOR32ItoR(EAX, _ImmU_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
- }
-}
-//#endif
-//end of * Arithmetic with immediate operand
-
-/*********************************************************
-* Load higher 16 bits of the first word in GPR with imm *
-* Format: OP rt, immediate *
-*********************************************************/
-/*REC_FUNC(LUI);
-#if 0*/
-static void recLUI() {
-// Rt = Imm << 16
- if (!_Rt_) return;
-
- MapConst(_Rt_, psxRegs.code << 16);
-}
-//#endif
-//End of Load Higher .....
-
-
-/*********************************************************
-* Register arithmetic *
-* Format: OP rd, rs, rt *
-*********************************************************/
-
-/*REC_FUNC(ADD);
-REC_FUNC(ADDU);
-REC_FUNC(SUB);
-REC_FUNC(SUBU);
-REC_FUNC(AND);
-REC_FUNC(OR);
-REC_FUNC(XOR);
-REC_FUNC(NOR);
-REC_FUNC(SLT);
-REC_FUNC(SLTU);
-
-#if 0*/
-static void recADDU() {
-// Rd = Rs + Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rt_ == _Rd_) {
- if (iRegs[_Rs_].k == 1) {
- INC32M((u32)&psxRegs.GPR.r[_Rd_]);
- } else if (iRegs[_Rs_].k == -1) {
- DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
- } else if (iRegs[_Rs_].k) {
- ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
- }
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- if (iRegs[_Rs_].k == 1) {
- INC32R(EAX);
- } else if (iRegs[_Rs_].k == 0xffffffff) {
- DEC32R(EAX);
- } else if (iRegs[_Rs_].k) {
- ADD32ItoR(EAX, iRegs[_Rs_].k);
- }
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rs_ == _Rd_) {
- if (iRegs[_Rt_].k == 1) {
- INC32M((u32)&psxRegs.GPR.r[_Rd_]);
- } else if (iRegs[_Rt_].k == -1) {
- DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
- } else if (iRegs[_Rt_].k) {
- ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
- }
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- if (iRegs[_Rt_].k == 1) {
- INC32R(EAX);
- } else if (iRegs[_Rt_].k == 0xffffffff) {
- DEC32R(EAX);
- } else if (iRegs[_Rt_].k) {
- ADD32ItoR(EAX, iRegs[_Rt_].k);
- }
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rs_ == _Rd_) { // Rd+= Rt
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (_Rt_ == _Rd_) { // Rd+= Rs
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else { // Rd = Rs + Rt
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- }
-}
-
-static void recADD() {
-// Rd = Rs + Rt
- recADDU();
-}
-
-static void recSUBU() {
-// Rd = Rs - Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- SUB32ItoR(EAX, iRegs[_Rt_].k);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSUB() {
-// Rd = Rs - Rt
- recSUBU();
-}
-
-static void recAND() {
-// Rd = Rs And Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rd_ == _Rt_) { // Rd&= Rs
- AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
- } else {
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rd_ == _Rs_) { // Rd&= kRt
- AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
- } else { // Rd = Rs & kRt
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- AND32ItoR(EAX, iRegs[_Rt_].k);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- if (_Rs_ == _Rd_) { // Rd&= Rt
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (_Rt_ == _Rd_) { // Rd&= Rs
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else { // Rd = Rs & Rt
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
- }
-}
-
-static void recOR() {
-// Rd = Rs Or Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- OR32ItoR (EAX, iRegs[_Rt_].k);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recXOR() {
-// Rd = Rs Xor Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- XOR32ItoR(EAX, iRegs[_Rt_].k);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recNOR() {
-// Rd = Rs Nor Rt
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- NOT32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- OR32ItoR (EAX, iRegs[_Rt_].k);
- NOT32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- NOT32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSLT() {
-// Rd = Rs < Rt (signed)
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- SETL8R (EAX);
- AND32ItoR(EAX, 0xff);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32ItoR(EAX, iRegs[_Rt_].k);
- SETL8R (EAX);
- AND32ItoR(EAX, 0xff);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- SETL8R (EAX);
- AND32ItoR(EAX, 0xff);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSLTU() {
-// Rd = Rs < Rt (unsigned)
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rs_].k);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- SBB32RtoR(EAX, EAX);
- NEG32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32ItoR(EAX, iRegs[_Rt_].k);
- SBB32RtoR(EAX, EAX);
- NEG32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- SBB32RtoR(EAX, EAX);
- NEG32R (EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-//#endif
-//End of * Register arithmetic
-
-/*********************************************************
-* Register mult/div & Register trap logic *
-* Format: OP rs, rt *
-*********************************************************/
-
-/*REC_FUNC(MULT);
-REC_FUNC(MULTU);
-REC_FUNC(DIV);
-REC_FUNC(DIVU);
-#if 0*/
-static void recMULT() {
-// Lo/Hi = Rs * Rt (signed)
-
-// iFlushRegs();
-
- if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
- (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
- XOR32RtoR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- return;
- }
-
- if (IsConst(_Rs_)) {
- MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multrsk %x\n", iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- }
- if (IsConst(_Rt_)) {
- MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multrtk %x\n", iRegs[_Rt_].k);
- IMUL32R (EDX);
- } else {
- IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
- }
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
-}
-
-static void recMULTU() {
-// Lo/Hi = Rs * Rt (unsigned)
-
-// iFlushRegs();
-
- if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
- (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
- XOR32RtoR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- return;
- }
-
- if (IsConst(_Rs_)) {
- MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multursk %x\n", iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- }
- if (IsConst(_Rt_)) {
- MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multurtk %x\n", iRegs[_Rt_].k);
- MUL32R (EDX);
- } else {
- MUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
- }
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
-}
-
-static void recDIV() {
-// Lo/Hi = Rs / Rt (signed)
-
-// iFlushRegs();
-
- if (IsConst(_Rt_)) {
- if (iRegs[_Rt_].k == 0) {
- MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- }
- return;
- }
- MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divrtk %x\n", iRegs[_Rt_].k);
- } else {
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
- CMP32ItoR(ECX, 0);
- j8Ptr[0] = JE8(0);
- }
- if (IsConst(_Rs_)) {
- MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divrsk %x\n", iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- }
- CDQ();
- IDIV32R (ECX);
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
-
- if (!IsConst(_Rt_)) {
- j8Ptr[1] = JMP8(1);
-
- x86SetJ8(j8Ptr[0]);
-
- MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- }
-
- x86SetJ8(j8Ptr[1]);
- }
-}
-
-static void recDIVU() {
-// Lo/Hi = Rs / Rt (unsigned)
-
-// iFlushRegs();
-
- if (IsConst(_Rt_)) {
- if (iRegs[_Rt_].k == 0) {
- MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- }
- return;
- }
- MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divurtk %x\n", iRegs[_Rt_].k);
- } else {
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
- CMP32ItoR(ECX, 0);
- j8Ptr[0] = JE8(0);
- }
- if (IsConst(_Rs_)) {
- MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divursk %x\n", iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- }
- XOR32RtoR(EDX, EDX);
- DIV32R (ECX);
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
-
- if (!IsConst(_Rt_)) {
- j8Ptr[1] = JMP8(1);
-
- x86SetJ8(j8Ptr[0]);
-
- MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- }
-
- x86SetJ8(j8Ptr[1]);
- }
-}
-//#endif
-//End of * Register mult/div & Register trap logic
-
-/*REC_FUNC(LB);
-REC_FUNC(LBU);
-REC_FUNC(LH);
-REC_FUNC(LHU);
-REC_FUNC(LW);
-
-REC_FUNC(SB);
-REC_FUNC(SH);
-REC_FUNC(SW);*/
-
-//REC_FUNC(LWL);
-//REC_FUNC(LWR);
-//REC_FUNC(SWL);
-//REC_FUNC(SWR);
-
-/* Push OfB for Stores/Loads */
-static void iPushOfB() {
- if (IsConst(_Rs_)) {
- PUSH32I (iRegs[_Rs_].k + _Imm_);
- } else {
- if (_Imm_) {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- ADD32ItoR(EAX, _Imm_);
- PUSH32R (EAX);
- } else {
- PUSH32M ((u32)&psxRegs.GPR.r[_Rs_]);
- }
- }
-}
-
-//#if 0
-static void recLB() {
-// Rt = mem[Rs + Im] (signed)
-
-// iFlushRegs();
-
- 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) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVSX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVSX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
-// SysPrintf("unhandled r8 %x\n", addr);
- }
-
- iPushOfB();
- CALLFunc((u32)psxMemRead8);
- if (_Rt_) {
- iRegs[_Rt_].state = ST_UNK;
- MOVSX32R8toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-// ADD32ItoR(ESP, 4);
- resp+= 4;
-}
-
-static void recLBU() {
-// Rt = mem[Rs + Im] (unsigned)
-
-// iFlushRegs();
-
- 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) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVZX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVZX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
-// SysPrintf("unhandled r8u %x\n", addr);
- }
-
- iPushOfB();
- CALLFunc((u32)psxMemRead8);
- if (_Rt_) {
- iRegs[_Rt_].state = ST_UNK;
- MOVZX32R8toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-// ADD32ItoR(ESP, 4);
- resp+= 4;
-}
-
-static void recLH() {
-// Rt = mem[Rs + Im] (signed)
-
-// iFlushRegs();
-
- 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) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVSX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVSX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
-// SysPrintf("unhandled r16 %x\n", addr);
- }
-
- iPushOfB();
- CALLFunc((u32)psxMemRead16);
- if (_Rt_) {
- iRegs[_Rt_].state = ST_UNK;
- MOVSX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-// ADD32ItoR(ESP, 4);
- resp+= 4;
-}
-
-static void recLHU() {
-// Rt = mem[Rs + Im] (unsigned)
-
-// iFlushRegs();
-
- 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) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVZX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOVZX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80) {
- if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- PUSH32I (addr);
- CALL32M ((u32)&SPU_readRegister);
- MOVZX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-#ifndef __WIN32__
- resp+= 4;
-#endif
- return;
- }
- switch (addr) {
- case 0x1f801100: case 0x1f801110: case 0x1f801120:
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- PUSH32I((addr >> 4) & 0x3);
- CALLFunc((u32)psxRcntRcount);
- MOVZX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- resp+= 4;
- return;
-
- case 0x1f801104: case 0x1f801114: case 0x1f801124:
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- PUSH32I((addr >> 4) & 0x3);
- CALLFunc((u32)psxRcntRmode);
- MOVZX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- resp+= 4;
- return;
-
- case 0x1f801108: case 0x1f801118: case 0x1f801128:
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- PUSH32I((addr >> 4) & 0x3);
- CALLFunc((u32)psxRcntRtarget);
- MOVZX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- resp+= 4;
- return;
- }
- }
-// SysPrintf("unhandled r16u %x\n", addr);
- }
-
- iPushOfB();
- CALLFunc((u32)psxMemRead16);
- if (_Rt_) {
- iRegs[_Rt_].state = ST_UNK;
- MOVZX32R16toR(EAX, EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-// ADD32ItoR(ESP, 4);
- resp+= 4;
-}
-
-static void recLW() {
-// Rt = mem[Rs + Im] (unsigned)
-
-// iFlushRegs();
-
- 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) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- 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;
- iRegs[_Rt_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxH[addr & 0xffff]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
-
- case 0x1f801810:
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- CALL32M((u32)&GPU_readData);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
-
- case 0x1f801814:
- if (!_Rt_) return;
- iRegs[_Rt_].state = ST_UNK;
-
- CALL32M((u32)&GPU_readStatus);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- return;
- }
- }
-// SysPrintf("unhandled r32 %x\n", addr);
- }
-
- iPushOfB();
- CALLFunc((u32)psxMemRead32);
- if (_Rt_) {
- iRegs[_Rt_].state = ST_UNK;
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
- }
-// ADD32ItoR(ESP, 4);
- resp+= 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) {
- 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 = (u32 *)PSXM(pc);
- int i, respsave;
-// Rt = mem[Rs + Im] (unsigned)
-
-// iFlushRegs();
-
- 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) {
- 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 = (u32 *)PSXM(pc); i < count; i++, code++) {
- psxRegs.code = *code;
- recLW();
- }
- ADD32ItoR(ESP, resp);
- x86SetJ32(j32Ptr[5]);
- resp = respsave;
-}
-
-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) {
- 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
-
-// iFlushRegs();
-
- 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);
- }
-
- PUSH32I(1);
- PUSH32I(addr & ~3);
- CALLFunc((u32)&recClear);
- resp += 8;
- 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);
- }
-
- if (IsConst(_Rt_)) {
- PUSH32I (iRegs[_Rt_].k);
- } else {
- PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
- }
- iPushOfB();
- CALLFunc((u32)psxMemWrite8);
-// ADD32ItoR(ESP, 8);
- resp+= 8;
-}
-
-static void recSH() {
-// mem[Rs + Im] = Rt
-
-// iFlushRegs();
-
- 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);
- }
-
- PUSH32I(1);
- PUSH32I(addr & ~3);
- CALLFunc((u32)&recClear);
- resp += 8;
- 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);
- }
-
- if (IsConst(_Rt_)) {
- PUSH32I (iRegs[_Rt_].k);
- } else {
- PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
- }
- iPushOfB();
- CALLFunc((u32)psxMemWrite16);
-// ADD32ItoR(ESP, 8);
- resp+= 8;
-}
-
-static void recSW() {
-// mem[Rs + Im] = Rt
-
-// iFlushRegs();
-
- if (IsConst(_Rs_)) {
- u32 addr = iRegs[_Rs_].k + _Imm_;
- int t = addr >> 16;
-
- if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
- if (IsConst(_Rt_)) {
- MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_Rt_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
- }
-
- PUSH32I(1);
- PUSH32I(addr);
- CALLFunc((u32)&recClear);
- resp += 8;
- return;
- }
-
- if (t == 0x1f80 && addr < 0x1f801000) {
- if (IsConst(_Rt_)) {
- MOV32ItoM((u32)&psxH[addr & 0xfff], iRegs[_Rt_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxH[addr & 0xfff], EAX);
- }
- 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:
- if (IsConst(_Rt_)) {
- MOV32ItoM((u32)&psxH[addr & 0xffff], iRegs[_Rt_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32RtoM((u32)&psxH[addr & 0xffff], EAX);
- }
- 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
- return;
- }
- }
-// SysPrintf("unhandled w32 %x\n", addr);
- }
-
- if (IsConst(_Rt_)) {
- PUSH32I (iRegs[_Rt_].k);
- } else {
- PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
- }
- iPushOfB();
- CALLFunc((u32)psxMemWrite32);
-// ADD32ItoR(ESP, 8);
- resp+= 8;
-}
-//#endif
-
-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 = (u32 *)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 = (u32 *)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 = (u32 *)PSXM(pc); i < count; i++, code++) {
- psxRegs.code = *code;
- recSW();
- }
- ADD32ItoR(ESP, resp);
- x86SetJ32(j32Ptr[5]);
- resp = respsave;
-}
-
-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 0
- if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
- MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
- iSWLk(addr & 3);
- MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
- return;
- }
-#endif
- 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;
-}
-
-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 0
- if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
- MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
- iSWRk(addr & 3);
- MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
- return;
- }
-#endif
- 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;
-}
-
-/*REC_FUNC(SLL);
-REC_FUNC(SRL);
-REC_FUNC(SRA);
-#if 0*/
-static void recSLL() {
-// Rd = Rt << Sa
- if (!_Rd_)
- return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- if (_Sa_) SHL32ItoR(EAX, _Sa_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSRL() {
-// Rd = Rt >> Sa
- if (!_Rd_)
- return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_)) {
- MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- if (_Sa_) SHR32ItoR(EAX, _Sa_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSRA() {
-// Rd = Rt >> Sa
- if (!_Rd_)
- return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_)) {
- MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- if (_Sa_) SAR32ItoR(EAX, _Sa_);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-//#endif
-
-/*REC_FUNC(SLLV);
-REC_FUNC(SRLV);
-REC_FUNC(SRAV);
-#if 0*/
-static void recSLLV() {
-// Rd = Rt << Rs
- if (!_Rd_)
- return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_) && IsConst(_Rs_)) {
- MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32ItoR(ECX, iRegs[_Rs_].k);
- SHL32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rt_].k);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SHL32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SHL32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSRLV() {
-// Rd = Rt >> Rs
- if (!_Rd_) return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_) && IsConst(_Rs_)) {
- MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32ItoR(ECX, iRegs[_Rs_].k);
- SHR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rt_].k);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SHR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SHR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-
-static void recSRAV() {
-// Rd = Rt >> Rs
- if (!_Rd_)
- return;
-
-// iFlushRegs();
-
- if (IsConst(_Rt_) && IsConst(_Rs_)) {
- MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
- } else if (IsConst(_Rs_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32ItoR(ECX, iRegs[_Rs_].k);
- SAR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else if (IsConst(_Rt_)) {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32ItoR(EAX, iRegs[_Rt_].k);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SAR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- } else {
- iRegs[_Rd_].state = ST_UNK;
-
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
- SAR32CLtoR(EAX);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
- }
-}
-//#endif
-
-/*REC_SYS(SYSCALL);
-REC_SYS(BREAK);
-
-#if 0*/
-int dump;
-static void recSYSCALL() {
-// dump = 1;
- iFlushRegs();
-
- MOV32ItoR(EAX, pc - 4);
- MOV32RtoM((u32)&psxRegs.pc, EAX);
- PUSH32I (branch == 1 ? 1 : 0);
- PUSH32I (0x20);
- CALLFunc ((u32)psxException);
- ADD32ItoR(ESP, 8);
-
- branch = 2;
- iRet();
-}
-
-static void recBREAK() {
-}
-//#endif
-
-/*REC_FUNC(MFHI);
-REC_FUNC(MTHI);
-REC_FUNC(MFLO);
-REC_FUNC(MTLO);
-#if 0*/
-static void recMFHI() {
-// Rd = Hi
- if (!_Rd_)
- return;
-
- iRegs[_Rd_].state = ST_UNK;
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
-}
-
-static void recMTHI() {
-// Hi = Rs
-
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
- }
-}
-
-static void recMFLO() {
-// Rd = Lo
- if (!_Rd_)
- return;
-
- iRegs[_Rd_].state = ST_UNK;
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
-}
-
-static void recMTLO() {
-// Lo = Rs
-
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&psxRegs.GPR.n.lo, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
- }
-}
-//#endif
-
-/*REC_BRANCH(J);
-REC_BRANCH(JR);
-REC_BRANCH(JAL);
-REC_BRANCH(JALR);
-REC_BRANCH(BLTZ);
-REC_BRANCH(BGTZ);
-REC_BRANCH(BLTZAL);
-REC_BRANCH(BGEZAL);
-REC_BRANCH(BNE);
-REC_BRANCH(BEQ);
-REC_BRANCH(BLEZ);
-REC_BRANCH(BGEZ);*/
-
-//#if 0
-static void recBLTZ() {
-// Branch if Rs < 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
-
- if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k < 0) {
- iJump(bpc);
- return;
- } else {
- iJump(pc + 4);
- return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JL32(0);
-
- iBranch(pc+4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc += 4;
-}
-
-static void recBGTZ() {
-// Branch if Rs > 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k > 0) {
- iJump(bpc);
- return;
- } else {
- iJump(pc + 4);
- return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JG32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc+=4;
-}
-
-static void recBLTZAL() {
-// Branch if Rs < 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k < 0) {
- MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
- iJump(bpc); return;
- } else {
- iJump(pc + 4); return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JL32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
- iBranch(bpc, 0);
- pc += 4;
-}
-
-static void recBGEZAL() {
-// Branch if Rs >= 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k >= 0) {
- MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
- iJump(bpc); return;
- } else {
- iJump(pc+4); return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JGE32(0);
-
- iBranch(pc+4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- MOV32ItoM((u32)&psxRegs.GPR.r[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_)) {
- MOV32ItoM((u32)&target, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&target, EAX);
- }
-
- SetBranch();
-}
-
-static void recJALR() {
-// jalr Rs
-
- if (IsConst(_Rs_)) {
- MOV32ItoM((u32)&target, iRegs[_Rs_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- MOV32RtoM((u32)&target, EAX);
- }
-
- if (_Rd_) {
- MapConst(_Rd_, pc + 4);
- }
-
- SetBranch();
-}
-
-static void recBEQ() {
-// Branch if Rs == Rt
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- 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_)) {
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
- } else if (IsConst(_Rt_)) {
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- }
-
- j32Ptr[4] = JE32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc += 4;
- }
-}
-
-static void recBNE() {
-// Branch if Rs != Rt
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_) && IsConst(_Rt_)) {
- if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
- iJump(bpc);
- return;
- } else {
- iJump(pc + 4);
- return;
- }
- } else if (IsConst(_Rs_)) {
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
- } else if (IsConst(_Rt_)) {
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
- } else {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
- CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- }
- j32Ptr[4] = JNE32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc += 4;
-}
-
-static void recBLEZ() {
-// Branch if Rs <= 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k <= 0) {
- iJump(bpc);
- return;
- } else {
- iJump(pc + 4);
- return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JLE32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc += 4;
-}
-
-static void recBGEZ() {
-// Branch if Rs >= 0
- u32 bpc = _Imm_ * 4 + pc;
-
-// iFlushRegs();
- if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
- return;
- }
-
- if (IsConst(_Rs_)) {
- if ((s32)iRegs[_Rs_].k >= 0) {
- iJump(bpc);
- return;
- } else {
- iJump(pc + 4);
- return;
- }
- }
-
- CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
- j32Ptr[4] = JGE32(0);
-
- iBranch(pc + 4, 1);
-
- x86SetJ32(j32Ptr[4]);
-
- iBranch(bpc, 0);
- pc += 4;
-}
-//#endif
-
-/*REC_FUNC(MFC0);
-REC_SYS(MTC0);
-REC_FUNC(CFC0);
-REC_SYS(CTC0);
-REC_FUNC(RFE);
-#if 0*/
-static void recMFC0() {
-// Rt = Cop0->Rd
- if (!_Rt_) return;
-
- iRegs[_Rt_].state = ST_UNK;
- MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]);
- MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
-}
-
-static void recCFC0() {
-// Rt = Cop0->Rd
-
- recMFC0();
-}
-
-void psxMTC0();
-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 {
- MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
- switch (_Rd_) {
- case 13:
- AND32ItoR(EAX, ~(0xfc00));
- break;
- }
- MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX);
- }
-
- if (_Rd_ == 12 || _Rd_ == 13) {
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
- CALLFunc((u32)psxTestSWInts);
- if (branch == 0) {
- branch = 2;
- iRet();
- }
- }
-}
-
-static void recCTC0() {
-// Cop0->Rd = Rt
-
- recMTC0();
-}
-
-static void recRFE() {
- MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
- MOV32RtoR(ECX, EAX);
- AND32ItoR(EAX, 0xfffffff0);
- AND32ItoR(ECX, 0x3c);
- SHR32ItoR(ECX, 2);
- OR32RtoR (EAX, ECX);
- MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX);
-
- iFlushRegs();
- MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
- CALLFunc((u32)psxTestSWInts);
- if (branch == 0) {
- branch = 2;
- iRet();
- }
-}
-//#endif
-
-#include "iGte.h"
-
-//
-
-static void recHLE() {
- iFlushRegs();
-
- MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xffff]);
- CALL32R(EAX);
- branch = 2;
- iRet();
-}
-
-//
-
-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() {
- char *p;
- char *ptr;
-
- dump = 0;
- resp = 0;
-
- /* if x86Ptr reached the mem limit reset whole mem */
- if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000))
- recReset();
-
- x86Align(32);
- ptr = x86Ptr;
-
- PC_REC32(psxRegs.pc) = (u32)x86Ptr;
- pc = psxRegs.pc;
- pcold = pc;
-
- for (count = 0; count < DYNAREC_BLOCK;) {
- p = (char *)PSXM(pc);
- if (p == NULL) recError();
- psxRegs.code = *(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++;
- recBSC[psxRegs.code >> 26]();
-
- if (branch) {
- branch = 0;
- if (dump) iDumpBlock(ptr);
- return;
- }
- }
-
- iFlushRegs();
-
- MOV32ItoM((u32)&psxRegs.pc, pc);
-
- iRet();
-}
-
-R3000Acpu psxRec = {
- recInit,
- recReset,
- recExecute,
- recExecuteBlock,
- recClear,
- recShutdown
-};
-
-#endif
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, 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. *
+ ***************************************************************************/
+
+/*
+* i386 assembly functions for R3000A core.
+*/
+
+#ifdef __i386__
+
+#include "ix86.h"
+#include <sys/mman.h>
+
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+u32 *psxRecLUT;
+
+#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 RECMEM_SIZE (8 * 1024 * 1024)
+
+static char *recMem; /* the recompiled blocks will be here */
+static char *recRAM; /* and the ptr to the blocks here */
+static char *recROM; /* and here */
+
+static u32 pc; /* recompiler pc */
+static u32 pcold; /* recompiler oldpc */
+static int count; /* recompiler intruction count */
+static int branch; /* set for branch */
+static u32 target; /* branch target */
+static u32 resp;
+
+typedef struct {
+ int state;
+ u32 k;
+ int reg;
+} iRegisters;
+
+static iRegisters iRegs[32];
+static iRegisters iRegsS[32];
+
+#define ST_UNK 0
+#define ST_CONST 1
+#define ST_MAPPED 2
+
+#define IsConst(reg) (iRegs[reg].state == ST_CONST)
+#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 DYNAREC_BLOCK 50
+
+static void MapConst(int reg, u32 _const) {
+ iRegs[reg].k = _const;
+ iRegs[reg].state = ST_CONST;
+}
+
+static void iFlushReg(int reg) {
+ if (IsConst(reg)) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[reg], iRegs[reg].k);
+ }
+ iRegs[reg].state = ST_UNK;
+}
+
+static void iFlushRegs() {
+ int i;
+
+ for (i=1; i<32; i++) {
+ iFlushReg(i);
+ }
+}
+
+static void iRet() {
+ /* store cycle */
+ count = ((pc - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+ RET();
+}
+
+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() {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc += 4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = ((pc - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32M((u32)&target);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+ switch( psxRegs.code >> 26 ) {
+ // Lode Runner (jr - beq)
+
+ // bltz - bgez - bltzal - bgezal / beq - bne - blez - bgtz
+ case 0x01:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ break;
+
+ default:
+ recBSC[psxRegs.code>>26]();
+ break;
+ }
+
+ iFlushRegs();
+ MOV32MtoR(EAX, (u32)&target);
+ MOV32RtoM((u32)&psxRegs.pc, EAX);
+ CALLFunc((u32)psxBranchTest);
+
+ iRet();
+}
+
+static void iJump(u32 branchPC) {
+ branch = 1;
+ psxRegs.code = PSXMu32(pc);
+ pc+=4;
+
+ if (iLoadTest() == 1) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = ((pc - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32I(branchPC);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, branchPC);
+ CALLFunc((u32)psxBranchTest);
+ /* store cycle */
+ count = ((pc - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ // maybe just happened an interruption, check so
+ CMP32ItoM((u32)&psxRegs.pc, branchPC);
+ j8Ptr[0] = JE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[0]);
+ MOV32MtoR(EAX, PC_REC(branchPC));
+ TEST32RtoR(EAX, EAX);
+ j8Ptr[1] = JNE8(0);
+ RET();
+
+ x86SetJ8(j8Ptr[1]);
+ RET();
+ JMP32R(EAX);
+}
+
+static void iBranch(u32 branchPC, int savectx) {
+ u32 respold=0;
+
+ if (savectx) {
+ respold = resp;
+ memcpy(iRegsS, iRegs, sizeof(iRegs));
+ }
+
+ 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();
+ MOV32ItoM((u32)&psxRegs.code, psxRegs.code);
+ /* store cycle */
+ count = (((pc+4) - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ PUSH32I(branchPC);
+ PUSH32I(_Rt_);
+ CALLFunc((u32)psxDelayTest);
+ ADD32ItoR(ESP, 2*4);
+
+ RET();
+ return;
+ }
+
+ pc+= 4;
+ recBSC[psxRegs.code>>26]();
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, branchPC);
+ CALLFunc((u32)psxBranchTest);
+ /* store cycle */
+ count = ((pc - pcold) / 4) * BIAS;
+ ADD32ItoM((u32)&psxRegs.cycle, count);
+ if (resp) ADD32ItoR(ESP, resp);
+
+ // 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));
+ }
+}
+
+
+char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
+char *txt1 = "EAX = %x\n";
+char *txt2 = "M32 = %x\n";
+
+void iLogX86() {
+ PUSHA32();
+
+ PUSH32R (EDX);
+ PUSH32R (ECX);
+ PUSH32R (EAX);
+ PUSH32M ((u32)&txt0);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*4);
+
+ POPA32();
+}
+
+void iLogEAX() {
+ PUSH32R (EAX);
+ PUSH32M ((u32)&txt1);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*2);
+}
+
+void iLogM32(u32 mem) {
+ PUSH32M (mem);
+ PUSH32M ((u32)&txt2);
+ CALLFunc ((u32)SysPrintf);
+ ADD32ItoR(ESP, 4*2);
+}
+
+static void iDumpRegs() {
+ int i, j;
+
+ printf("%x %x\n", psxRegs.pc, psxRegs.cycle);
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%x ", psxRegs.GPR.r[j * i]);
+ printf("\n");
+ }
+}
+
+void iDumpBlock(char *ptr) {
+ FILE *f;
+ u32 i;
+
+ SysPrintf("dump1 %x:%x, %x\n", psxRegs.pc, pc, psxRegs.cycle);
+
+ 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(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+/* branch = 2; */\
+}
+
+#define REC_SYS(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+#define REC_BRANCH(f) \
+void psx##f(); \
+static void rec##f() { \
+ iFlushRegs(); \
+ MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \
+ CALLFunc((u32)psx##f); \
+ branch = 2; \
+ iRet(); \
+}
+
+static void recRecompile();
+
+static int recInit() {
+ int i;
+
+ psxRecLUT = (u32 *)malloc(0x010000 * 4);
+
+ recMem = mmap(0, RECMEM_SIZE + 0x1000,
+ PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ recRAM = (char *)malloc(0x200000);
+ recROM = (char *)malloc(0x080000);
+ if (recRAM == NULL || recROM == NULL || recMem == NULL || psxRecLUT == NULL) {
+ 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 void recReset() {
+ memset(recRAM, 0, 0x200000);
+ memset(recROM, 0, 0x080000);
+
+ x86Init();
+
+ x86SetPtr(recMem);
+
+ branch = 0;
+ memset(iRegs, 0, sizeof(iRegs));
+ iRegs[0].state = ST_CONST;
+ iRegs[0].k = 0;
+}
+
+static void recShutdown() {
+ if (recMem == NULL) return;
+ free(psxRecLUT);
+ munmap(recMem, RECMEM_SIZE + 0x1000);
+ free(recRAM);
+ free(recROM);
+ x86Shutdown();
+}
+
+static void recError() {
+ SysReset();
+ ClosePlugins();
+ SysMessage("Unrecoverable error while running recompiler\n");
+ SysRunGui();
+}
+
+__inline static void execute() {
+ void (**recFunc)() = NULL;
+ char *p;
+
+ p = (char *)PC_REC(psxRegs.pc);
+ if (p != NULL) recFunc = (void (**)()) (u32)p;
+ else { recError(); return; }
+
+ if (*recFunc == 0) {
+ recRecompile();
+ }
+ (*recFunc)();
+}
+
+static void recExecute() {
+ for (;;) execute();
+}
+
+static void recExecuteBlock() {
+ execute();
+}
+
+static void recClear(u32 Addr, u32 Size) {
+ u32 bank,offset;
+
+ bank = Addr >> 24;
+ offset = Addr & 0xffffff;
+
+
+ // Pitfall 3D - clear dynarec slots that contain 'stale' ram data
+ // - fixes stage 1 loading crash
+ if( bank == 0x80 || bank == 0xa0 || bank == 0x00 ) {
+ offset &= 0x1fffff;
+
+ if( offset >= DYNAREC_BLOCK * 4 )
+ memset((void*)PC_REC(Addr - DYNAREC_BLOCK * 4), 0, DYNAREC_BLOCK * 4);
+ else
+ memset((void*)PC_REC(Addr - offset), 0, offset);
+ }
+
+
+ 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() {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
+ AND32ItoR(EAX, 0x40000000);
+ j8Ptr[31] = JZ8(0);
+
+ recCP2[_Funct_]();
+
+ x86SetJ8(j8Ptr[31]);
+}
+
+static void recBASIC() {
+ recCP2BSC[_Rs_]();
+}
+
+//end of Tables opcodes...
+
+/*********************************************************
+* Arithmetic with immediate operand *
+* Format: OP rt, rs, immediate *
+*********************************************************/
+
+/*REC_FUNC(ADDI);
+REC_FUNC(ADDIU);
+REC_FUNC(ANDI);
+REC_FUNC(ORI);
+REC_FUNC(XORI);
+REC_FUNC(SLTI);
+REC_FUNC(SLTIU);
+#if 0*/
+static void recADDIU() {
+// Rt = Rs + Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k+= _Imm_;
+ } else {
+ if (_Imm_ == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_ == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rt_]);
+ } else if (_Imm_) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_);
+ }
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k + _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_Imm_ == 1) {
+ INC32R(EAX);
+ } else if (_Imm_ == -1) {
+ DEC32R(EAX);
+ } else if (_Imm_) {
+ ADD32ItoR(EAX, _Imm_);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recADDI() {
+// Rt = Rs + Im
+ recADDIU();
+}
+
+static void recSLTI() {
+// Rt = Rs < Im (signed)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, (s32)iRegs[_Rs_].k < _Imm_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recSLTIU() {
+// Rt = Rs < Im (unsigned)
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k < _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, _Imm_);
+ SETB8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+}
+
+static void recANDI() {
+// Rt = Rs And Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k&= _ImmU_;
+ } else {
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k & _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recORI() {
+// Rt = Rs Or Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k|= _ImmU_;
+ } else {
+ OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k | _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (_ImmU_) OR32ItoR (EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+
+static void recXORI() {
+// Rt = Rs Xor Im
+ if (!_Rt_) return;
+
+// iFlushRegs();
+
+ if (_Rs_ == _Rt_) {
+ if (IsConst(_Rt_)) {
+ iRegs[_Rt_].k^= _ImmU_;
+ } else {
+ XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_);
+ }
+ } else {
+ if (IsConst(_Rs_)) {
+ MapConst(_Rt_, iRegs[_Rs_].k ^ _ImmU_);
+ } else {
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, _ImmU_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+ }
+}
+//#endif
+//end of * Arithmetic with immediate operand
+
+/*********************************************************
+* Load higher 16 bits of the first word in GPR with imm *
+* Format: OP rt, immediate *
+*********************************************************/
+/*REC_FUNC(LUI);
+#if 0*/
+static void recLUI() {
+// Rt = Imm << 16
+ if (!_Rt_) return;
+
+ MapConst(_Rt_, psxRegs.code << 16);
+}
+//#endif
+//End of Load Higher .....
+
+
+/*********************************************************
+* Register arithmetic *
+* Format: OP rd, rs, rt *
+*********************************************************/
+
+/*REC_FUNC(ADD);
+REC_FUNC(ADDU);
+REC_FUNC(SUB);
+REC_FUNC(SUBU);
+REC_FUNC(AND);
+REC_FUNC(OR);
+REC_FUNC(XOR);
+REC_FUNC(NOR);
+REC_FUNC(SLT);
+REC_FUNC(SLTU);
+
+#if 0*/
+static void recADDU() {
+// Rd = Rs + Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k + iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rt_ == _Rd_) {
+ if (iRegs[_Rs_].k == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (iRegs[_Rs_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rs_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rs_].k) {
+ ADD32ItoR(EAX, iRegs[_Rs_].k);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) {
+ if (iRegs[_Rt_].k == 1) {
+ INC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k == -1) {
+ DEC32M((u32)&psxRegs.GPR.r[_Rd_]);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ }
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ if (iRegs[_Rt_].k == 1) {
+ INC32R(EAX);
+ } else if (iRegs[_Rt_].k == 0xffffffff) {
+ DEC32R(EAX);
+ } else if (iRegs[_Rt_].k) {
+ ADD32ItoR(EAX, iRegs[_Rt_].k);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd+= Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd+= Rs
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs + Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recADD() {
+// Rd = Rs + Rt
+ recADDU();
+}
+
+static void recSUBU() {
+// Rd = Rs - Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k - iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SUB32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSUB() {
+// Rd = Rs - Rt
+ recSUBU();
+}
+
+static void recAND() {
+// Rd = Rs And Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k & iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rt_) { // Rd&= Rs
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rs_].k);
+ } else {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rd_ == _Rs_) { // Rd&= kRt
+ AND32ItoM((u32)&psxRegs.GPR.r[_Rd_], iRegs[_Rt_].k);
+ } else { // Rd = Rs & kRt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ if (_Rs_ == _Rd_) { // Rd&= Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (_Rt_ == _Rd_) { // Rd&= Rs
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else { // Rd = Rs & Rt
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+ }
+}
+
+static void recOR() {
+// Rd = Rs Or Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k | iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recXOR() {
+// Rd = Rs Xor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k ^ iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recNOR() {
+// Rd = Rs Nor Rt
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, ~(iRegs[_Rs_].k | iRegs[_Rt_].k));
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32ItoR (EAX, iRegs[_Rt_].k);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ NOT32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLT() {
+// Rd = Rs < Rt (signed)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rs_].k < (s32)iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SETL8R (EAX);
+ AND32ItoR(EAX, 0xff);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSLTU() {
+// Rd = Rs < Rt (unsigned)
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rs_].k < iRegs[_Rt_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rs_].k);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32ItoR(EAX, iRegs[_Rt_].k);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ SBB32RtoR(EAX, EAX);
+ NEG32R (EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+//End of * Register arithmetic
+
+/*********************************************************
+* Register mult/div & Register trap logic *
+* Format: OP rs, rt *
+*********************************************************/
+
+/*REC_FUNC(MULT);
+REC_FUNC(MULTU);
+REC_FUNC(DIV);
+REC_FUNC(DIVU);
+#if 0*/
+static void recMULT() {
+// Lo/Hi = Rs * Rt (signed)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multrtk %x\n", iRegs[_Rt_].k);
+ IMUL32R (EDX);
+ } else {
+ IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recMULTU() {
+// Lo/Hi = Rs * Rt (unsigned)
+
+// iFlushRegs();
+
+ if ((IsConst(_Rs_) && iRegs[_Rs_].k == 0) ||
+ (IsConst(_Rt_) && iRegs[_Rt_].k == 0)) {
+ XOR32RtoR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("multursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ if (IsConst(_Rt_)) {
+ MOV32ItoR(EDX, iRegs[_Rt_].k);// printf("multurtk %x\n", iRegs[_Rt_].k);
+ MUL32R (EDX);
+ } else {
+ MUL32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+}
+
+static void recDIV() {
+// Lo/Hi = Rs / Rt (signed)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+ return;
+ }
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divrtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divrsk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ CDQ();
+ IDIV32R (ECX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+
+ if (!IsConst(_Rt_)) {
+ j8Ptr[1] = JMP8(1);
+
+ x86SetJ8(j8Ptr[0]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+
+ x86SetJ8(j8Ptr[1]);
+ }
+}
+
+static void recDIVU() {
+// Lo/Hi = Rs / Rt (unsigned)
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ if (iRegs[_Rt_].k == 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+ return;
+ }
+ MOV32ItoR(ECX, iRegs[_Rt_].k);// printf("divurtk %x\n", iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]);
+ CMP32ItoR(ECX, 0);
+ j8Ptr[0] = JE8(0);
+ }
+ if (IsConst(_Rs_)) {
+ MOV32ItoR(EAX, iRegs[_Rs_].k);// printf("divursk %x\n", iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ XOR32RtoR(EDX, EDX);
+ DIV32R (ECX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX);
+
+ if (!IsConst(_Rt_)) {
+ j8Ptr[1] = JMP8(1);
+
+ x86SetJ8(j8Ptr[0]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, 0xffffffff);
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+
+ x86SetJ8(j8Ptr[1]);
+ }
+}
+//#endif
+//End of * Register mult/div & Register trap logic
+
+/*REC_FUNC(LB);
+REC_FUNC(LBU);
+REC_FUNC(LH);
+REC_FUNC(LHU);
+REC_FUNC(LW);
+
+REC_FUNC(SB);
+REC_FUNC(SH);
+REC_FUNC(SW);*/
+
+//REC_FUNC(LWL);
+//REC_FUNC(LWR);
+//REC_FUNC(SWL);
+//REC_FUNC(SWR);
+
+/* Push OfB for Stores/Loads */
+static void iPushOfB() {
+ if (IsConst(_Rs_)) {
+ PUSH32I (iRegs[_Rs_].k + _Imm_);
+ } else {
+ if (_Imm_) {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ ADD32ItoR(EAX, _Imm_);
+ PUSH32R (EAX);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rs_]);
+ }
+ }
+}
+
+//#if 0
+static void recLB() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ 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) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R8toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLBU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ 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) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M8toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r8u %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead8);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R8toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLH() {
+// Rt = mem[Rs + Im] (signed)
+
+// iFlushRegs();
+
+ 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) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVSX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+// SysPrintf("unhandled r16 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVSX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLHU() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ 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) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOVZX32M16toR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80) {
+ if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I (addr);
+ CALL32M ((u32)&SPU_readRegister);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+#ifndef __WIN32__
+ resp+= 4;
+#endif
+ return;
+ }
+ switch (addr) {
+ case 0x1f801100: case 0x1f801110: case 0x1f801120:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I((addr >> 4) & 0x3);
+ CALLFunc((u32)psxRcntRcount);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ resp+= 4;
+ return;
+
+ case 0x1f801104: case 0x1f801114: case 0x1f801124:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I((addr >> 4) & 0x3);
+ CALLFunc((u32)psxRcntRmode);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ resp+= 4;
+ return;
+
+ case 0x1f801108: case 0x1f801118: case 0x1f801128:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ PUSH32I((addr >> 4) & 0x3);
+ CALLFunc((u32)psxRcntRtarget);
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ resp+= 4;
+ return;
+ }
+ }
+// SysPrintf("unhandled r16u %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead16);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOVZX32R16toR(EAX, EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+static void recLW() {
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ 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) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1fffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xfff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ 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;
+ iRegs[_Rt_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxH[addr & 0xffff]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801810:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALL32M((u32)&GPU_readData);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+
+ case 0x1f801814:
+ if (!_Rt_) return;
+ iRegs[_Rt_].state = ST_UNK;
+
+ CALL32M((u32)&GPU_readStatus);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ return;
+ }
+ }
+// SysPrintf("unhandled r32 %x\n", addr);
+ }
+
+ iPushOfB();
+ CALLFunc((u32)psxMemRead32);
+ if (_Rt_) {
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+ }
+// ADD32ItoR(ESP, 4);
+ resp+= 4;
+}
+
+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) {
+ 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 = (u32 *)PSXM(pc);
+ int i, respsave;
+// Rt = mem[Rs + Im] (unsigned)
+
+// iFlushRegs();
+
+ 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) {
+ 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 = (u32 *)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) {
+ 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
+
+// iFlushRegs();
+
+ 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);
+ }
+
+ PUSH32I(1);
+ PUSH32I(addr & ~3);
+ CALLFunc((u32)&recClear);
+ resp += 8;
+ 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);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite8);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recSH() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ 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);
+ }
+
+ PUSH32I(1);
+ PUSH32I(addr & ~3);
+ CALLFunc((u32)&recClear);
+ resp += 8;
+ 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);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite16);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+
+static void recSW() {
+// mem[Rs + Im] = Rt
+
+// iFlushRegs();
+
+ if (IsConst(_Rs_)) {
+ u32 addr = iRegs[_Rs_].k + _Imm_;
+ int t = addr >> 16;
+
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxM[addr & 0x1fffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxM[addr & 0x1fffff], EAX);
+ }
+
+ PUSH32I(1);
+ PUSH32I(addr);
+ CALLFunc((u32)&recClear);
+ resp += 8;
+ return;
+ }
+
+ if (t == 0x1f80 && addr < 0x1f801000) {
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxH[addr & 0xfff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xfff], EAX);
+ }
+ 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:
+ if (IsConst(_Rt_)) {
+ MOV32ItoM((u32)&psxH[addr & 0xffff], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32RtoM((u32)&psxH[addr & 0xffff], EAX);
+ }
+ 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
+ return;
+ }
+ }
+// SysPrintf("unhandled w32 %x\n", addr);
+ }
+
+ if (IsConst(_Rt_)) {
+ PUSH32I (iRegs[_Rt_].k);
+ } else {
+ PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ iPushOfB();
+ CALLFunc((u32)psxMemWrite32);
+// ADD32ItoR(ESP, 8);
+ resp+= 8;
+}
+//#endif
+
+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 = (u32 *)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 = (u32 *)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 = (u32 *)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 0
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWLk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+#endif
+ 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 0
+ if ((t & 0x1fe0) == 0 && (t & 0x1fff) != 0) {
+ MOV32MtoR(EAX, (u32)&psxM[addr & 0x1ffffc]);
+ iSWRk(addr & 3);
+ MOV32RtoM((u32)&psxM[addr & 0x1ffffc], EAX);
+ return;
+ }
+#endif
+ 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;
+}
+
+/*REC_FUNC(SLL);
+REC_FUNC(SRL);
+REC_FUNC(SRA);
+#if 0*/
+static void recSLL() {
+// Rd = Rt << Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHL32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRL() {
+// Rd = Rt >> Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SHR32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRA() {
+// Rd = Rt >> Sa
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> _Sa_);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ if (_Sa_) SAR32ItoR(EAX, _Sa_);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+
+/*REC_FUNC(SLLV);
+REC_FUNC(SRLV);
+REC_FUNC(SRAV);
+#if 0*/
+static void recSLLV() {
+// Rd = Rt << Rs
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k << iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHL32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRLV() {
+// Rd = Rt >> Rs
+ if (!_Rd_) return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SHR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+
+static void recSRAV() {
+// Rd = Rt >> Rs
+ if (!_Rd_)
+ return;
+
+// iFlushRegs();
+
+ if (IsConst(_Rt_) && IsConst(_Rs_)) {
+ MapConst(_Rd_, (s32)iRegs[_Rt_].k >> iRegs[_Rs_].k);
+ } else if (IsConst(_Rs_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32ItoR(ECX, iRegs[_Rs_].k);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else if (IsConst(_Rt_)) {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32ItoR(EAX, iRegs[_Rt_].k);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ } else {
+ iRegs[_Rd_].state = ST_UNK;
+
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]);
+ SAR32CLtoR(EAX);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+ }
+}
+//#endif
+
+/*REC_SYS(SYSCALL);
+REC_SYS(BREAK);
+
+#if 0*/
+int dump;
+static void recSYSCALL() {
+// dump = 1;
+ iFlushRegs();
+
+ MOV32ItoR(EAX, pc - 4);
+ MOV32RtoM((u32)&psxRegs.pc, EAX);
+ PUSH32I (branch == 1 ? 1 : 0);
+ PUSH32I (0x20);
+ CALLFunc ((u32)psxException);
+ ADD32ItoR(ESP, 8);
+
+ branch = 2;
+ iRet();
+}
+
+static void recBREAK() {
+}
+//#endif
+
+/*REC_FUNC(MFHI);
+REC_FUNC(MTHI);
+REC_FUNC(MFLO);
+REC_FUNC(MTLO);
+#if 0*/
+static void recMFHI() {
+// Rd = Hi
+ if (!_Rd_)
+ return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTHI() {
+// Hi = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.hi, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX);
+ }
+}
+
+static void recMFLO() {
+// Rd = Lo
+ if (!_Rd_)
+ return;
+
+ iRegs[_Rd_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX);
+}
+
+static void recMTLO() {
+// Lo = Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&psxRegs.GPR.n.lo, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX);
+ }
+}
+//#endif
+
+/*REC_BRANCH(J);
+REC_BRANCH(JR);
+REC_BRANCH(JAL);
+REC_BRANCH(JALR);
+REC_BRANCH(BLTZ);
+REC_BRANCH(BGTZ);
+REC_BRANCH(BLTZAL);
+REC_BRANCH(BGEZAL);
+REC_BRANCH(BNE);
+REC_BRANCH(BEQ);
+REC_BRANCH(BLEZ);
+REC_BRANCH(BGEZ);*/
+
+//#if 0
+static void recBLTZ() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+
+ if (bpc == pc+4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGTZ() {
+// Branch if Rs > 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k > 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JG32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc+=4;
+}
+
+static void recBLTZAL() {
+// Branch if Rs < 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k < 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc + 4); return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JL32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGEZAL() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4);
+ iJump(bpc); return;
+ } else {
+ iJump(pc+4); return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc+4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ MOV32ItoM((u32)&psxRegs.GPR.r[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_)) {
+ MOV32ItoM((u32)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&target, EAX);
+ }
+
+ SetBranch();
+}
+
+static void recJALR() {
+// jalr Rs
+
+ if (IsConst(_Rs_)) {
+ MOV32ItoM((u32)&target, iRegs[_Rs_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ MOV32RtoM((u32)&target, EAX);
+ }
+
+ if (_Rd_) {
+ MapConst(_Rd_, pc + 4);
+ }
+
+ SetBranch();
+}
+
+static void recBEQ() {
+// Branch if Rs == Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ 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_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+
+ j32Ptr[4] = JE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+ }
+}
+
+static void recBNE() {
+// Branch if Rs != Rt
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_) && IsConst(_Rt_)) {
+ if (iRegs[_Rs_].k != iRegs[_Rt_].k) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ } else if (IsConst(_Rs_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rt_], iRegs[_Rs_].k);
+ } else if (IsConst(_Rt_)) {
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], iRegs[_Rt_].k);
+ } else {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+ CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ }
+ j32Ptr[4] = JNE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBLEZ() {
+// Branch if Rs <= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k <= 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JLE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+
+static void recBGEZ() {
+// Branch if Rs >= 0
+ u32 bpc = _Imm_ * 4 + pc;
+
+// iFlushRegs();
+ if (bpc == pc + 4 && psxTestLoadDelay(_Rs_, PSXMu32(bpc)) == 0) {
+ return;
+ }
+
+ if (IsConst(_Rs_)) {
+ if ((s32)iRegs[_Rs_].k >= 0) {
+ iJump(bpc);
+ return;
+ } else {
+ iJump(pc + 4);
+ return;
+ }
+ }
+
+ CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0);
+ j32Ptr[4] = JGE32(0);
+
+ iBranch(pc + 4, 1);
+
+ x86SetJ32(j32Ptr[4]);
+
+ iBranch(bpc, 0);
+ pc += 4;
+}
+//#endif
+
+/*REC_FUNC(MFC0);
+REC_SYS(MTC0);
+REC_FUNC(CFC0);
+REC_SYS(CTC0);
+REC_FUNC(RFE);
+#if 0*/
+static void recMFC0() {
+// Rt = Cop0->Rd
+ if (!_Rt_) return;
+
+ iRegs[_Rt_].state = ST_UNK;
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]);
+ MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX);
+}
+
+static void recCFC0() {
+// Rt = Cop0->Rd
+
+ recMFC0();
+}
+
+void psxMTC0();
+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 {
+ MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]);
+ switch (_Rd_) {
+ case 13:
+ AND32ItoR(EAX, ~(0xfc00));
+ break;
+ }
+ MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX);
+ }
+
+ if (_Rd_ == 12 || _Rd_ == 13) {
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
+ CALLFunc((u32)psxTestSWInts);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+ }
+}
+
+static void recCTC0() {
+// Cop0->Rd = Rt
+
+ recMTC0();
+}
+
+static void recRFE() {
+ MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status);
+ MOV32RtoR(ECX, EAX);
+ AND32ItoR(EAX, 0xfffffff0);
+ AND32ItoR(ECX, 0x3c);
+ SHR32ItoR(ECX, 2);
+ OR32RtoR (EAX, ECX);
+ MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX);
+
+ iFlushRegs();
+ MOV32ItoM((u32)&psxRegs.pc, (u32)pc);
+ CALLFunc((u32)psxTestSWInts);
+ if (branch == 0) {
+ branch = 2;
+ iRet();
+ }
+}
+//#endif
+
+#include "iGte.h"
+
+//
+
+static void recHLE() {
+ iFlushRegs();
+
+ MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xffff]);
+ CALL32R(EAX);
+ branch = 2;
+ iRet();
+}
+
+//
+
+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() {
+ char *p;
+ char *ptr;
+
+ dump = 0;
+ resp = 0;
+
+ /* if x86Ptr reached the mem limit reset whole mem */
+ if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000))
+ recReset();
+
+ x86Align(32);
+ ptr = x86Ptr;
+
+ PC_REC32(psxRegs.pc) = (u32)x86Ptr;
+ pc = psxRegs.pc;
+ pcold = pc;
+
+ for (count = 0; count < DYNAREC_BLOCK;) {
+ p = (char *)PSXM(pc);
+ if (p == NULL) recError();
+ psxRegs.code = *(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++;
+ recBSC[psxRegs.code >> 26]();
+
+ if (branch) {
+ branch = 0;
+ if (dump) iDumpBlock(ptr);
+ return;
+ }
+ }
+
+ iFlushRegs();
+
+ MOV32ItoM((u32)&psxRegs.pc, pc);
+
+ iRet();
+}
+
+R3000Acpu psxRec = {
+ recInit,
+ recReset,
+ recExecute,
+ recExecuteBlock,
+ recClear,
+ recShutdown
+};
+
+#endif
diff --git a/libpcsxcore/ix86/ix86.c b/libpcsxcore/ix86/ix86.c
index ef0e0d3a..3f8903ec 100644
--- a/libpcsxcore/ix86/ix86.c
+++ b/libpcsxcore/ix86/ix86.c
@@ -1,1727 +1,1727 @@
-/***************************************************************************
- * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, 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. *
- ***************************************************************************/
-
-/*
- * ix86 core v0.5.1
- * Authors: linuzappz <linuzappz@pcsx.net>
- * alexey silinov
- */
-
-#ifdef __i386__
-
-#include "ix86.h"
-
-s8 *x86Ptr;
-u8 *j8Ptr[32];
-u32 *j32Ptr[32];
-
-void x86Init() {
-}
-
-void x86SetPtr(char *ptr) {
- x86Ptr = ptr;
-}
-
-void x86Shutdown() {
-}
-
-void x86SetJ8(u8 *j8) {
- u32 jump = (x86Ptr - (s8*)j8) - 1;
-
- if (jump > 0x7f) printf("j8 greater than 0x7f!!\n");
- *j8 = (u8)jump;
-}
-
-void x86SetJ32(u32 *j32) {
- *j32 = (x86Ptr - (s8*)j32) - 4;
-}
-
-void x86Align(int bytes) {
- // fordward align
- x86Ptr = (s8*)(((u32)x86Ptr + bytes - 1) & ~(bytes - 1));
-}
-
-#define SIB 4
-#define DISP32 5
-
-/* macros helpers */
-
-#define ModRM(mod, rm, reg) \
- write8((mod << 6) | (rm << 3) | (reg));
-
-#define SibSB(ss, rm, index) \
- write8((ss << 6) | (rm << 3) | (index));
-
-#define SET8R(cc, to) { \
- write8(0x0F); write8(cc); \
- write8((0xC0) | (to)); }
-
-#define J8Rel(cc, to) { \
- write8(cc); write8(to); return x86Ptr - 1; }
-
-#define J32Rel(cc, to) { \
- write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); }
-
-#define CMOV32RtoR(cc, to, from) { \
- write8(0x0F); write8(cc); \
- ModRM(3, to, from); }
-
-#define CMOV32MtoR(cc, to, from) { \
- write8(0x0F); write8(cc); \
- ModRM(0, to, DISP32); \
- write32(from); }
-
-/********************/
-/* IX86 intructions */
-/********************/
-
-// mov instructions
-
-/* mov r32 to r32 */
-void MOV32RtoR(int to, int from) {
- write8(0x89);
- ModRM(3, from, to);
-}
-
-/* mov r32 to m32 */
-void MOV32RtoM(u32 to, int from) {
- write8(0x89);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* mov m32 to r32 */
-void MOV32MtoR(int to, u32 from) {
- write8(0x8B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* mov [r32] to r32 */
-void MOV32RmtoR(int to, int from) {
- write8(0x8B);
- ModRM(0, to, from);
-}
-
-/* mov [r32][r32*scale] to r32 */
-void MOV32RmStoR(int to, int from, int from2, int scale) {
- write8(0x8B);
- ModRM(0, to, 0x4);
- SibSB(scale, from2, from);
-}
-
-/* mov r32 to [r32] */
-void MOV32RtoRm(int to, int from) {
- write8(0x89);
- ModRM(0, from, to);
-}
-
-/* mov r32 to [r32][r32*scale] */
-void MOV32RtoRmS(int to, int to2, int scale, int from) {
- write8(0x89);
- ModRM(0, from, 0x4);
- SibSB(scale, to2, to);
-}
-
-/* mov imm32 to r32 */
-void MOV32ItoR(int to, u32 from) {
- write8(0xB8 | to);
- write32(from);
-}
-
-/* mov imm32 to m32 */
-void MOV32ItoM(u32 to, u32 from) {
- write8(0xC7);
- ModRM(0, 0, DISP32);
- write32(to);
- write32(from);
-}
-
-/* mov r16 to m16 */
-void MOV16RtoM(u32 to, int from) {
- write8(0x66);
- write8(0x89);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* mov m16 to r16 */
-void MOV16MtoR(int to, u32 from) {
- write8(0x66);
- write8(0x8B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* mov imm16 to m16 */
-void MOV16ItoM(u32 to, u16 from) {
- write8(0x66);
- write8(0xC7);
- ModRM(0, 0, DISP32);
- write32(to);
- write16(from);
-}
-
-/* mov r8 to m8 */
-void MOV8RtoM(u32 to, int from) {
- write8(0x88);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* mov m8 to r8 */
-void MOV8MtoR(int to, u32 from) {
- write8(0x8A);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* mov imm8 to m8 */
-void MOV8ItoM(u32 to, u8 from) {
- write8(0xC6);
- ModRM(0, 0, DISP32);
- write32(to);
- write8(from);
-}
-
-/* movsx r8 to r32 */
-void MOVSX32R8toR(int to, int from) {
- write16(0xBE0F);
- ModRM(3, to, from);
-}
-
-/* movsx m8 to r32 */
-void MOVSX32M8toR(int to, u32 from) {
- write16(0xBE0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movsx r16 to r32 */
-void MOVSX32R16toR(int to, int from) {
- write16(0xBF0F);
- ModRM(3, to, from);
-}
-
-/* movsx m16 to r32 */
-void MOVSX32M16toR(int to, u32 from) {
- write16(0xBF0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movzx r8 to r32 */
-void MOVZX32R8toR(int to, int from) {
- write16(0xB60F);
- ModRM(3, to, from);
-}
-
-/* movzx m8 to r32 */
-void MOVZX32M8toR(int to, u32 from) {
- write16(0xB60F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movzx r16 to r32 */
-void MOVZX32R16toR(int to, int from) {
- write16(0xB70F);
- ModRM(3, to, from);
-}
-
-/* movzx m16 to r32 */
-void MOVZX32M16toR(int to, u32 from) {
- write16(0xB70F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* cmovne r32 to r32 */
-void CMOVNE32RtoR(int to, int from) {
- CMOV32RtoR(0x45, to, from);
-}
-
-/* cmovne m32 to r32*/
-void CMOVNE32MtoR(int to, u32 from) {
- CMOV32MtoR(0x45, to, from);
-}
-
-/* cmove r32 to r32*/
-void CMOVE32RtoR(int to, int from) {
- CMOV32RtoR(0x44, to, from);
-}
-
-/* cmove m32 to r32*/
-void CMOVE32MtoR(int to, u32 from) {
- CMOV32MtoR(0x44, to, from);
-}
-
-/* cmovg r32 to r32*/
-void CMOVG32RtoR(int to, int from) {
- CMOV32RtoR(0x4F, to, from);
-}
-
-/* cmovg m32 to r32*/
-void CMOVG32MtoR(int to, u32 from) {
- CMOV32MtoR(0x4F, to, from);
-}
-
-/* cmovge r32 to r32*/
-void CMOVGE32RtoR(int to, int from) {
- CMOV32RtoR(0x4D, to, from);
-}
-
-/* cmovge m32 to r32*/
-void CMOVGE32MtoR(int to, u32 from) {
- CMOV32MtoR(0x4D, to, from);
-}
-
-/* cmovl r32 to r32*/
-void CMOVL32RtoR(int to, int from) {
- CMOV32RtoR(0x4C, to, from);
-}
-
-/* cmovl m32 to r32*/
-void CMOVL32MtoR(int to, u32 from) {
- CMOV32MtoR(0x4C, to, from);
-}
-
-/* cmovle r32 to r32*/
-void CMOVLE32RtoR(int to, int from) {
- CMOV32RtoR(0x4E, to, from);
-}
-
-/* cmovle m32 to r32*/
-void CMOVLE32MtoR(int to, u32 from) {
- CMOV32MtoR(0x4E, to, from);
-}
-
-// arithmic instructions
-
-/* add imm32 to r32 */
-void ADD32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x05);
- } else {
- write8(0x81);
- ModRM(3, 0, to);
- }
- write32(from);
-}
-
-/* add imm32 to m32 */
-void ADD32ItoM(u32 to, u32 from) {
- write8(0x81);
- ModRM(0, 0, DISP32);
- write32(to);
- write32(from);
-}
-
-/* add r32 to r32 */
-void ADD32RtoR(int to, int from) {
- write8(0x01);
- ModRM(3, from, to);
-}
-
-/* add r32 to m32 */
-void ADD32RtoM(u32 to, int from) {
- write8(0x01);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* add m32 to r32 */
-void ADD32MtoR(int to, u32 from) {
- write8(0x03);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* adc imm32 to r32 */
-void ADC32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x15);
- } else {
- write8(0x81);
- ModRM(3, 2, to);
- }
- write32(from);
-}
-
-/* adc r32 to r32 */
-void ADC32RtoR(int to, int from) {
- write8(0x11);
- ModRM(3, from, to);
-}
-
-/* adc m32 to r32 */
-void ADC32MtoR(int to, u32 from) {
- write8(0x13);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* inc r32 */
-void INC32R(int to) {
- write8(0x40 + to);
-}
-
-/* inc m32 */
-void INC32M(u32 to) {
- write8(0xFF);
- ModRM(0, 0, DISP32);
- write32(to);
-}
-
-/* sub imm32 to r32 */
-void SUB32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x2D);
- } else {
- write8(0x81);
- ModRM(3, 5, to);
- }
- write32(from);
-}
-
-/* sub r32 to r32 */
-void SUB32RtoR(int to, int from) {
- write8(0x29);
- ModRM(3, from, to);
-}
-
-/* sub m32 to r32 */
-void SUB32MtoR(int to, u32 from) {
- write8(0x2B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* sbb imm32 to r32 */
-void SBB32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x1D);
- } else {
- write8(0x81);
- ModRM(3, 3, to);
- }
- write32(from);
-}
-
-/* sbb r32 to r32 */
-void SBB32RtoR(int to, int from) {
- write8(0x19);
- ModRM(3, from, to);
-}
-
-/* sbb m32 to r32 */
-void SBB32MtoR(int to, u32 from) {
- write8(0x1B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* dec r32 */
-void DEC32R(int to) {
- write8(0x48 + to);
-}
-
-/* dec m32 */
-void DEC32M(u32 to) {
- write8(0xFF);
- ModRM(0, 1, DISP32);
- write32(to);
-}
-
-/* mul eax by r32 to edx:eax */
-void MUL32R(int from) {
- write8(0xF7);
- ModRM(3, 4, from);
-}
-
-/* imul eax by r32 to edx:eax */
-void IMUL32R(int from) {
- write8(0xF7);
- ModRM(3, 5, from);
-}
-
-/* mul eax by m32 to edx:eax */
-void MUL32M(u32 from) {
- write8(0xF7);
- ModRM(0, 4, DISP32);
- write32(from);
-}
-
-/* imul eax by m32 to edx:eax */
-void IMUL32M(u32 from) {
- write8(0xF7);
- ModRM(0, 5, DISP32);
- write32(from);
-}
-
-/* imul r32 by r32 to r32 */
-void IMUL32RtoR(int to, int from) {
- write16(0xAF0F);
- ModRM(3, to, from);
-}
-
-/* div eax by r32 to edx:eax */
-void DIV32R(int from) {
- write8(0xF7);
- ModRM(3, 6, from);
-}
-
-/* idiv eax by r32 to edx:eax */
-void IDIV32R(int from) {
- write8(0xF7);
- ModRM(3, 7, from);
-}
-
-/* div eax by m32 to edx:eax */
-void DIV32M(u32 from) {
- write8(0xF7);
- ModRM(0, 6, DISP32);
- write32(from);
-}
-
-/* idiv eax by m32 to edx:eax */
-void IDIV32M(u32 from) {
- write8(0xF7);
- ModRM(0, 7, DISP32);
- write32(from);
-}
-
-// shifting instructions
-
-void RCR32ItoR(int to,int from)
-{
- if (from==1)
- {
- write8(0xd1);
- write8(0xd8 | to);
- }
- else
- {
- write8(0xc1);
- write8(0xd8 | to);
- write8(from);
- }
-}
-
-/* shl imm8 to r32 */
-void SHL32ItoR(int to, u8 from) {
- if (from==1)
- {
- write8(0xd1);
- write8(0xe0 | to);
- return;
- }
- write8(0xC1);
- ModRM(3, 4, to);
- write8(from);
-}
-
-/* shl cl to r32 */
-void SHL32CLtoR(int to) {
- write8(0xD3);
- ModRM(3, 4, to);
-}
-
-/* shr imm8 to r32 */
-void SHR32ItoR(int to, u8 from) {
- if (from==1)
- {
- write8(0xd1);
- write8(0xe8 | to);
- return;
- }
- write8(0xC1);
- ModRM(3, 5, to);
- write8(from);
-}
-
-/* shr cl to r32 */
-void SHR32CLtoR(int to) {
- write8(0xD3);
- ModRM(3, 5, to);
-}
-
-/* sar imm8 to r32 */
-void SAR32ItoR(int to, u8 from) {
- write8(0xC1);
- ModRM(3, 7, to);
- write8(from);
-}
-
-/* sar cl to r32 */
-void SAR32CLtoR(int to) {
- write8(0xD3);
- ModRM(3, 7, to);
-}
-
-
-// logical instructions
-
-/* or imm32 to r32 */
-void OR32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x0D);
- } else {
- write8(0x81);
- ModRM(3, 1, to);
- }
- write32(from);
-}
-
-/* or imm32 to m32 */
-void OR32ItoM(u32 to, u32 from) {
- write8(0x81);
- ModRM(0, 1, DISP32);
- write32(to);
- write32(from);
-}
-
-/* or r32 to r32 */
-void OR32RtoR(int to, int from) {
- write8(0x09);
- ModRM(3, from, to);
-}
-
-/* or r32 to m32 */
-void OR32RtoM(u32 to, int from) {
- write8(0x09);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* or m32 to r32 */
-void OR32MtoR(int to, u32 from) {
- write8(0x0B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* xor imm32 to r32 */
-void XOR32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x35);
- } else {
- write8(0x81);
- ModRM(3, 6, to);
- }
- write32(from);
-}
-
-/* xor imm32 to m32 */
-void XOR32ItoM(u32 to, u32 from) {
- write8(0x81);
- ModRM(0, 6, DISP32);
- write32(to);
- write32(from);
-}
-
-/* xor r32 to r32 */
-void XOR32RtoR(int to, int from) {
- write8(0x31);
- ModRM(3, from, to);
-}
-
-/* xor r32 to m32 */
-void XOR32RtoM(u32 to, int from) {
- write8(0x31);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* xor m32 to r32 */
-void XOR32MtoR(int to, u32 from) {
- write8(0x33);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* and imm32 to r32 */
-void AND32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x25);
- } else {
- write8(0x81);
- ModRM(3, 0x4, to);
- }
- write32(from);
-}
-
-/* and imm32 to m32 */
-void AND32ItoM(u32 to, u32 from) {
- write8(0x81);
- ModRM(0, 0x4, DISP32);
- write32(to);
- write32(from);
-}
-
-/* and r32 to r32 */
-void AND32RtoR(int to, int from) {
- write8(0x21);
- ModRM(3, from, to);
-}
-
-/* and r32 to m32 */
-void AND32RtoM(u32 to, int from) {
- write8(0x21);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* and m32 to r32 */
-void AND32MtoR(int to, u32 from) {
- write8(0x23);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* not r32 */
-void NOT32R(int from) {
- write8(0xF7);
- ModRM(3, 2, from);
-}
-
-/* neg r32 */
-void NEG32R(int from) {
- write8(0xF7);
- ModRM(3, 3, from);
-}
-
-// jump instructions
-
-/* jmp rel8 */
-u8* JMP8(u8 to) {
- write8(0xEB);
- write8(to);
- return x86Ptr - 1;
-}
-
-/* jmp rel32 */
-u32* JMP32(u32 to) {
- write8(0xE9);
- write32(to);
- return (u32*)(x86Ptr - 4);
-}
-
-/* jmp r32 */
-void JMP32R(int to) {
- write8(0xFF);
- ModRM(3, 4, to);
-}
-
-/* je rel8 */
-u8* JE8(u8 to) {
- J8Rel(0x74, to);
-}
-
-/* jz rel8 */
-u8* JZ8(u8 to) {
- J8Rel(0x74, to);
-}
-
-/* jg rel8 */
-u8* JG8(u8 to) {
- J8Rel(0x7F, to);
-}
-
-/* jge rel8 */
-u8* JGE8(u8 to) {
- J8Rel(0x7D, to);
-}
-
-/* jl rel8 */
-u8* JL8(u8 to) {
- J8Rel(0x7C, to);
-}
-
-/* jle rel8 */
-u8* JLE8(u8 to) {
- J8Rel(0x7E, to);
-}
-
-/* jne rel8 */
-u8* JNE8(u8 to) {
- J8Rel(0x75, to);
-}
-
-/* jnz rel8 */
-u8* JNZ8(u8 to) {
- J8Rel(0x75, to);
-}
-
-/* jng rel8 */
-u8* JNG8(u8 to) {
- J8Rel(0x7E, to);
-}
-
-/* jnge rel8 */
-u8* JNGE8(u8 to) {
- J8Rel(0x7C, to);
-}
-
-/* jnl rel8 */
-u8* JNL8(u8 to) {
- J8Rel(0x7D, to);
-}
-
-/* jnle rel8 */
-u8* JNLE8(u8 to) {
- J8Rel(0x7F, to);
-}
-
-/* jo rel8 */
-u8* JO8(u8 to) {
- J8Rel(0x70, to);
-}
-
-/* jno rel8 */
-u8* JNO8(u8 to) {
- J8Rel(0x71, to);
-}
-
-/* je rel32 */
-u32* JE32(u32 to) {
- J32Rel(0x84, to);
-}
-
-/* jz rel32 */
-u32* JZ32(u32 to) {
- J32Rel(0x84, to);
-}
-
-/* jg rel32 */
-u32* JG32(u32 to) {
- J32Rel(0x8F, to);
-}
-
-/* jge rel32 */
-u32* JGE32(u32 to) {
- J32Rel(0x8D, to);
-}
-
-/* jl rel32 */
-u32* JL32(u32 to) {
- J32Rel(0x8C, to);
-}
-
-/* jle rel32 */
-u32* JLE32(u32 to) {
- J32Rel(0x8E, to);
-}
-
-/* jne rel32 */
-u32* JNE32(u32 to) {
- J32Rel(0x85, to);
-}
-
-/* jnz rel32 */
-u32* JNZ32(u32 to) {
- J32Rel(0x85, to);
-}
-
-/* jng rel32 */
-u32* JNG32(u32 to) {
- J32Rel(0x8E, to);
-}
-
-/* jnge rel32 */
-u32* JNGE32(u32 to) {
- J32Rel(0x8C, to);
-}
-
-/* jnl rel32 */
-u32* JNL32(u32 to) {
- J32Rel(0x8D, to);
-}
-
-/* jnle rel32 */
-u32* JNLE32(u32 to) {
- J32Rel(0x8F, to);
-}
-
-/* jo rel32 */
-u32* JO32(u32 to) {
- J32Rel(0x80, to);
-}
-
-/* jno rel32 */
-u32* JNO32(u32 to) {
- J32Rel(0x81, to);
-}
-
-/* call func */
-void CALLFunc(u32 func) {
- CALL32(func - ((u32)x86Ptr + 5));
-}
-
-/* call rel32 */
-void CALL32(u32 to) {
- write8(0xE8);
- write32(to);
-}
-
-/* call r32 */
-void CALL32R(int to) {
- write8(0xFF);
- ModRM(3, 2, to);
-}
-
-/* call m32 */
-void CALL32M(u32 to) {
- write8(0xFF);
- ModRM(0, 2, DISP32);
- write32(to);
-}
-
-// misc instructions
-
-/* cmp imm32 to r32 */
-void CMP32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0x3D);
- } else {
- write8(0x81);
- ModRM(3, 7, to);
- }
- write32(from);
-}
-
-/* cmp imm32 to m32 */
-void CMP32ItoM(u32 to, u32 from) {
- write8(0x81);
- ModRM(0, 7, DISP32);
- write32(to);
- write32(from);
-}
-
-/* cmp r32 to r32 */
-void CMP32RtoR(int to, int from) {
- write8(0x39);
- ModRM(3, from, to);
-}
-
-/* cmp m32 to r32 */
-void CMP32MtoR(int to, u32 from) {
- write8(0x3B);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* test imm32 to r32 */
-void TEST32ItoR(int to, u32 from) {
- if (to == EAX) {
- write8(0xA9);
- } else {
- write8(0xF7);
- ModRM(3, 0, to);
- }
- write32(from);
-}
-
-/* test r32 to r32 */
-void TEST32RtoR(int to, int from) {
- write8(0x85);
- ModRM(3, from, to);
-}
-
-void BT32ItoR(int to,int from)
-{
- write16(0xba0f);
- write8(0xe0 | to);
- write8(from);
-}
-
-/* sets r8 */
-void SETS8R(int to) {
- SET8R(0x98, to);
-}
-/* setl r8 */
-void SETL8R(int to) {
- SET8R(0x9C, to);
-}
-
-/* setb r8 */
-void SETB8R(int to) {
- SET8R(0x92, to);
-}
-
-/* setnz r8 */
-void SETNZ8R(int to) {
- SET8R(0x95,to);
-}
-
-/* cbw */
-void CBW() {
- write16(0x9866);
-}
-
-/* cwd */
-void CWD() {
- write8(0x98);
-}
-
-/* cdq */
-void CDQ() {
- write8(0x99);
-}
-
-/* push r32 */
-void PUSH32R(int from) {
- write8(0x50 | from);
-}
-
-/* push m32 */
-void PUSH32M(u32 from) {
- write8(0xFF);
- ModRM(0, 6, DISP32);
- write32(from);
-}
-
-/* push imm32 */
-void PUSH32I(u32 from) {
- write8(0x68); write32(from);
-}
-
-/* pop r32 */
-void POP32R(int from) {
- write8(0x58 | from);
-}
-
-/* pushad */
-void PUSHA32() {
- write8(0x60);
-}
-
-/* popad */
-void POPA32() {
- write8(0x61);
-}
-
-/* ret */
-void RET() {
- write8(0xC3);
-}
-
-/********************/
-/* FPU instructions */
-/********************/
-
-//Added:basara 14.01.2003
-/* compare m32 to fpu reg stack */
-void FCOMP32(u32 from) {
- write8(0xD8);
- ModRM(0, 0x3, DISP32);
- write32(from);
-}
-
-void FNSTSWtoAX() {
- write16(0xE0DF);
-}
-
-/* fild m32 to fpu reg stack */
-void FILD32(u32 from) {
- write8(0xDB);
- ModRM(0, 0x0, DISP32);
- write32(from);
-}
-
-/* fistp m32 from fpu reg stack */
-void FISTP32(u32 from) {
- write8(0xDB);
- ModRM(0, 0x3, DISP32);
- write32(from);
-}
-
-/* fld m32 to fpu reg stack */
-void FLD32(u32 from) {
- write8(0xD9);
- ModRM(0, 0x0, DISP32);
- write32(from);
-}
-
-/* fstp m32 from fpu reg stack */
-void FSTP32(u32 to) {
- write8(0xD9);
- ModRM(0, 0x3, DISP32);
- write32(to);
-}
-
-//
-
-/* fldcw fpu control word from m16 */
-void FLDCW(u32 from) {
- write8(0xD9);
- ModRM(0, 0x5, DISP32);
- write32(from);
-}
-
-/* fnstcw fpu control word to m16 */
-void FNSTCW(u32 to) {
- write8(0xD9);
- ModRM(0, 0x7, DISP32);
- write32(to);
-}
-
-//
-
-/* fadd m32 to fpu reg stack */
-void FADD32(u32 from) {
- write8(0xD8);
- ModRM(0, 0x0, DISP32);
- write32(from);
-}
-
-/* fsub m32 to fpu reg stack */
-void FSUB32(u32 from) {
- write8(0xD8);
- ModRM(0, 0x4, DISP32);
- write32(from);
-}
-
-/* fmul m32 to fpu reg stack */
-void FMUL32(u32 from) {
- write8(0xD8);
- ModRM(0, 0x1, DISP32);
- write32(from);
-}
-
-/* fdiv m32 to fpu reg stack */
-void FDIV32(u32 from) {
- write8(0xD8);
- ModRM(0, 0x6, DISP32);
- write32(from);
-}
-
-/* fabs fpu reg stack */
-void FABS() {
- write16(0xE1D9);
-}
-
-/* fsqrt fpu reg stack */
-void FSQRT() {
- write16(0xFAD9);
-}
-
-/* fchs fpu reg stack */
-void FCHS() {
- write16(0xE0D9);
-}
-
-/********************/
-/* MMX instructions */
-/********************/
-
-// r64 = mm
-
-/* movq m64 to r64 */
-void MOVQMtoR(int to, u32 from) {
- write16(0x6F0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movq r64 to m64 */
-void MOVQRtoM(u32 to, int from) {
- write16(0x7F0F);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* pand r64 to r64 */
-void PANDRtoR(int to, int from) {
- write16(0xDB0F);
- ModRM(3, to, from);
-}
-
-/* pand r64 to r64 */
-void PANDNRtoR(int to, int from) {
- write16(0xDF0F);
- ModRM(3, to, from);
-}
-
-/* por r64 to r64 */
-void PORRtoR(int to, int from) {
- write16(0xEB0F);
- ModRM(3, to, from);
-}
-
-/* pxor r64 to r64 */
-void PXORRtoR(int to, int from) {
- write16(0xEF0F);
- ModRM(3, to, from);
-}
-
-/* psllq r64 to r64 */
-void PSLLQRtoR(int to, int from) {
- write16(0xF30F);
- ModRM(3, to, from);
-}
-
-/* psllq m64 to r64 */
-void PSLLQMtoR(int to, u32 from) {
- write16(0xF30F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* psllq imm8 to r64 */
-void PSLLQItoR(int to, u8 from) {
- write16(0x730F);
- ModRM(3, 6, to);
- write8(from);
-}
-
-/* psrlq r64 to r64 */
-void PSRLQRtoR(int to, int from) {
- write16(0xD30F);
- ModRM(3, to, from);
-}
-
-/* psrlq m64 to r64 */
-void PSRLQMtoR(int to, u32 from) {
- write16(0xD30F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* psrlq imm8 to r64 */
-void PSRLQItoR(int to, u8 from) {
- write16(0x730F);
- ModRM(3, 2, to);
- write8(from);
-}
-
-/* paddusb r64 to r64 */
-void PADDUSBRtoR(int to, int from) {
- write16(0xDC0F);
- ModRM(3, to, from);
-}
-
-/* paddusb m64 to r64 */
-void PADDUSBMtoR(int to, u32 from) {
- write16(0xDC0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* paddusw r64 to r64 */
-void PADDUSWRtoR(int to, int from) {
- write16(0xDD0F);
- ModRM(3, to, from);
-}
-
-/* paddusw m64 to r64 */
-void PADDUSWMtoR(int to, u32 from) {
- write16(0xDD0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* paddb r64 to r64 */
-void PADDBRtoR(int to, int from) {
- write16(0xFC0F);
- ModRM(3, to, from);
-}
-
-/* paddb m64 to r64 */
-void PADDBMtoR(int to, u32 from) {
- write16(0xFC0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* paddw r64 to r64 */
-void PADDWRtoR(int to, int from) {
- write16(0xFD0F);
- ModRM(3, to, from);
-}
-
-/* paddw m64 to r64 */
-void PADDWMtoR(int to, u32 from) {
- write16(0xFD0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* paddd r64 to r64 */
-void PADDDRtoR(int to, int from) {
- write16(0xFE0F);
- ModRM(3, to, from);
-}
-
-/* paddd m64 to r64 */
-void PADDDMtoR(int to, u32 from) {
- write16(0xFE0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* emms */
-void EMMS() {
- //use femms if we have 3dnow
- write16(0x0e0f);
- return;
-}
-
-/* femms */
-void FEMMS() {
- write16(0x770F);
- return;
-}
-
-//Basara:changed
-void PADDSBRtoR(int to, int from) {
- write16(0xEC0F);
- ModRM(3, to, from);
-}
-
-void PADDSWRtoR(int to, int from) {
- write16(0xED0F);
- ModRM(3, to, from);
-}
-
-void PADDSDRtoR(int to, int from) {
- write16(0xEE0F);
- ModRM(3, to, from);
-}
-
-void PSUBSBRtoR(int to, int from) {
- write16(0xE80F);
- ModRM(3, to, from);
-}
-
-void PSUBSWRtoR(int to, int from) {
- write16(0xE90F);
- ModRM(3, to, from);
-}
-
-void PSUBSDRtoR(int to, int from) {
- write16(0xEA0F);
- ModRM(3, to, from);
-}
-
-void PSUBBRtoR(int to, int from) {
- write16(0xF80F);
- ModRM(3, to, from);
-}
-
-void PSUBWRtoR(int to, int from) {
- write16(0xF90F);
- ModRM(3, to, from);
-}
-
-void PSUBDRtoR(int to, int from) {
- write16(0xFA0F);
- ModRM(3, to, from);
-}
-
-//changed:basara
-//P.s.It's sux.Don't use it offten.
-void MOVQ64ItoR(int reg,u64 i)
-{
- MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
- JMP8(8);
- write64(i);
-}
-
-void PSUBUSBRtoR(int to, int from) {
- write16(0xD80F);
- ModRM(3, to, from);
-}
-
-void PSUBUSWRtoR(int to, int from) {
- write16(0xD90F);
- ModRM(3, to, from);
-}
-
-void PMAXSWRtoR(int to,int from)
-{
- write16(0xEE0F);
- ModRM(3, to, from);
-}
-
-void PMINSWRtoR(int to,int from)
-{
- write16(0xEA0F);
- ModRM(3, to, from);
-}
-
-void PCMPEQBRtoR(int to,int from)
-{
- write16(0x740F);
- ModRM(3, to, from);
-}
-
-void PCMPEQWRtoR(int to,int from)
-{
- write16(0x750F);
- ModRM(3, to, from);
-}
-
-void PCMPEQDRtoR(int to,int from)
-{
- write16(0x760F);
- ModRM(3, to, from);
-}
-
-void PCMPGTBRtoR(int to,int from)
-{
- write16(0x640F);
- ModRM(3, to, from);
-}
-
-void PCMPGTWRtoR(int to,int from)
-{
- write16(0x650F);
- ModRM(3, to, from);
-}
-
-void PCMPGTDRtoR(int to,int from)
-{
- write16(0x660F);
- ModRM(3, to, from);
-}
-
-//Basara:Added 10.01.2003
-void PSRLWItoR(int to,int from)
-{
- write16(0x710f);
- ModRM(2, 2 , to);
- write8(from);
-}
-void PSRLDItoR(int to,int from)
-{
- write16(0x720f);
- ModRM(2, 2 , to);
- write8(from);
-}
-
-void PSLLWItoR(int to,int from)
-{
- write16(0x710f);
- ModRM(3, 6 , to);
- write8(from);
-}
-
-void PSLLDItoR(int to,int from)
-{
- write16(0x720f);
- ModRM(3, 6 , to);
- write8(from);
-}
-
-void PSRAWItoR(int to,int from)
-{
- write16(0x710f);
- ModRM(3, 4 , to);
- write8(from);
-}
-
-void PSRADItoR(int to,int from)
-{
- write16(0x720f);
- ModRM(3, 4 , to);
- write8(from);
-}
-
-/* por m64 to r64 */
-void PORMtoR(int to, u32 from) {
- write16(0xEB0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* pxor m64 to r64 */
-void PXORMtoR(int to, u32 from) {
- write16(0xEF0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* pand m64 to r64 */
-void PANDMtoR(int to, u32 from) {
- write16(0xDB0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* pandn m64 to r64 */
-void PANDNMtoR(int to, u32 from) {
- write16(0xDF0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movd m32 to r64 */
-void MOVDMtoR(int to, u32 from) {
- write16(0x6E0F);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-/* movq r64 to m32 */
-void MOVDRtoM(u32 to, int from) {
- write16(0x7E0F);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-/* movd r32 to r64 */
-void MOVD32RtoR(int to, int from) {
- write16(0x6E0F);
- ModRM(3, to,from);
-}
-
-/* movq r64 to r32 */
-void MOVD64RtoR(int to, int from) {
- write16(0x7E0F);
- ModRM(3, from,to);
-}
-
-void MOVQRtoR(int to, int from) {
- write16(0x6F0F);
- ModRM(3, to,from);
-}
-
-void PUNPCKHDQRtoR(int to, int from) {
- write16(0x6A0F);
- ModRM(3, to,from);
-}
-
-void PUNPCKLDQRtoR(int to, int from) {
- write16(0x620F);
- ModRM(3, to,from);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// SSE intructions
-//////////////////////////////////////////////////////////////////////////
-
-void MOVAPSMtoR(int to, int from) {
- write16(0x280f);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-void MOVAPSRtoM(int to, int from) {
- write16(0x2b0f);
- ModRM(0, from, DISP32);
- write32(to);
-}
-
-void MOVAPSRtoR(int to, int from) {
- write16(0x290f);
- ModRM(3, to,from);
-}
-
-void ORPSMtoR(int to, int from) {
- write16(0x560f);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-void ORPSRtoR(int to, int from) {
- write16(0x560f);
- ModRM(3, to,from);
-}
-
-void XORPSMtoR(int to, int from) {
- write16(0x570f);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-void XORPSRtoR(int to, int from) {
- write16(0x570f);
- ModRM(3, to,from);
-}
-
-void ANDPSMtoR(int to, int from) {
- write16(0x540f);
- ModRM(0, to, DISP32);
- write32(from);
-}
-
-void ANDPSRtoR(int to, int from) {
- write16(0x540f);
- ModRM(3, to,from);
-}
-
-/*
- 3DNOW intructions
-*/
-
-void PFCMPEQMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0xb0);
-}
-
-void PFCMPGTMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0xa0);
-}
-
-void PFCMPGEMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x90);
-}
-
-void PFADDMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x9e);
-}
-
-void PFADDRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0x9e);
-}
-
-void PFSUBMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x9a);
-}
-
-void PFSUBRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0x9a);
-}
-
-void PFMULMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0xb4);
-}
-
-void PFMULRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0xb4);
-}
-
-void PFRCPMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x96);
-}
-
-void PFRCPRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0x96);
-}
-
-void PFRCPIT1RtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0xa6);
-}
-
-void PFRCPIT2RtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0xb6);
-}
-
-void PFRSQRTRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0x97);
-}
-
-void PFRSQIT1RtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to,from);
- write8(0xa7);
-}
-
-void PF2IDMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x1d);
-}
-
-void PF2IDRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0x1d);
-}
-
-void PI2FDMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x0d);
-}
-
-void PI2FDRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0x0d);
-}
-
-/*
- 3DNOW Extension intructions
-*/
-
-void PFMAXMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0xa4);
-}
-
-void PFMAXRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0xa4);
-}
-
-void PFMINMtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(0, to, DISP32);
- write32(from);
- write8(0x94);
-}
-
-void PFMINRtoR(int to, int from) {
- write16(0x0f0f);
- ModRM(3, to, from);
- write8(0x94);
-}
-
-#endif
+/***************************************************************************
+ * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, 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. *
+ ***************************************************************************/
+
+/*
+ * ix86 core v0.5.1
+ * Authors: linuzappz <linuzappz@pcsx.net>
+ * alexey silinov
+ */
+
+#ifdef __i386__
+
+#include "ix86.h"
+
+s8 *x86Ptr;
+u8 *j8Ptr[32];
+u32 *j32Ptr[32];
+
+void x86Init() {
+}
+
+void x86SetPtr(char *ptr) {
+ x86Ptr = ptr;
+}
+
+void x86Shutdown() {
+}
+
+void x86SetJ8(u8 *j8) {
+ u32 jump = (x86Ptr - (s8*)j8) - 1;
+
+ if (jump > 0x7f) printf("j8 greater than 0x7f!!\n");
+ *j8 = (u8)jump;
+}
+
+void x86SetJ32(u32 *j32) {
+ *j32 = (x86Ptr - (s8*)j32) - 4;
+}
+
+void x86Align(int bytes) {
+ // fordward align
+ x86Ptr = (s8*)(((u32)x86Ptr + bytes) & ~(bytes - 1));
+}
+
+#define SIB 4
+#define DISP32 5
+
+/* macros helpers */
+
+#define ModRM(mod, rm, reg) \
+ write8((mod << 6) | (rm << 3) | (reg));
+
+#define SibSB(ss, rm, index) \
+ write8((ss << 6) | (rm << 3) | (index));
+
+#define SET8R(cc, to) { \
+ write8(0x0F); write8(cc); \
+ write8((0xC0) | (to)); }
+
+#define J8Rel(cc, to) { \
+ write8(cc); write8(to); return x86Ptr - 1; }
+
+#define J32Rel(cc, to) { \
+ write8(0x0F); write8(cc); write32(to); return (u32*)(x86Ptr - 4); }
+
+#define CMOV32RtoR(cc, to, from) { \
+ write8(0x0F); write8(cc); \
+ ModRM(3, to, from); }
+
+#define CMOV32MtoR(cc, to, from) { \
+ write8(0x0F); write8(cc); \
+ ModRM(0, to, DISP32); \
+ write32(from); }
+
+/********************/
+/* IX86 intructions */
+/********************/
+
+// mov instructions
+
+/* mov r32 to r32 */
+void MOV32RtoR(int to, int from) {
+ write8(0x89);
+ ModRM(3, from, to);
+}
+
+/* mov r32 to m32 */
+void MOV32RtoM(u32 to, int from) {
+ write8(0x89);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m32 to r32 */
+void MOV32MtoR(int to, u32 from) {
+ write8(0x8B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov [r32] to r32 */
+void MOV32RmtoR(int to, int from) {
+ write8(0x8B);
+ ModRM(0, to, from);
+}
+
+/* mov [r32][r32*scale] to r32 */
+void MOV32RmStoR(int to, int from, int from2, int scale) {
+ write8(0x8B);
+ ModRM(0, to, 0x4);
+ SibSB(scale, from2, from);
+}
+
+/* mov r32 to [r32] */
+void MOV32RtoRm(int to, int from) {
+ write8(0x89);
+ ModRM(0, from, to);
+}
+
+/* mov r32 to [r32][r32*scale] */
+void MOV32RtoRmS(int to, int to2, int scale, int from) {
+ write8(0x89);
+ ModRM(0, from, 0x4);
+ SibSB(scale, to2, to);
+}
+
+/* mov imm32 to r32 */
+void MOV32ItoR(int to, u32 from) {
+ write8(0xB8 | to);
+ write32(from);
+}
+
+/* mov imm32 to m32 */
+void MOV32ItoM(u32 to, u32 from) {
+ write8(0xC7);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* mov r16 to m16 */
+void MOV16RtoM(u32 to, int from) {
+ write8(0x66);
+ write8(0x89);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m16 to r16 */
+void MOV16MtoR(int to, u32 from) {
+ write8(0x66);
+ write8(0x8B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov imm16 to m16 */
+void MOV16ItoM(u32 to, u16 from) {
+ write8(0x66);
+ write8(0xC7);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write16(from);
+}
+
+/* mov r8 to m8 */
+void MOV8RtoM(u32 to, int from) {
+ write8(0x88);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* mov m8 to r8 */
+void MOV8MtoR(int to, u32 from) {
+ write8(0x8A);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* mov imm8 to m8 */
+void MOV8ItoM(u32 to, u8 from) {
+ write8(0xC6);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write8(from);
+}
+
+/* movsx r8 to r32 */
+void MOVSX32R8toR(int to, int from) {
+ write16(0xBE0F);
+ ModRM(3, to, from);
+}
+
+/* movsx m8 to r32 */
+void MOVSX32M8toR(int to, u32 from) {
+ write16(0xBE0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movsx r16 to r32 */
+void MOVSX32R16toR(int to, int from) {
+ write16(0xBF0F);
+ ModRM(3, to, from);
+}
+
+/* movsx m16 to r32 */
+void MOVSX32M16toR(int to, u32 from) {
+ write16(0xBF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movzx r8 to r32 */
+void MOVZX32R8toR(int to, int from) {
+ write16(0xB60F);
+ ModRM(3, to, from);
+}
+
+/* movzx m8 to r32 */
+void MOVZX32M8toR(int to, u32 from) {
+ write16(0xB60F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movzx r16 to r32 */
+void MOVZX32R16toR(int to, int from) {
+ write16(0xB70F);
+ ModRM(3, to, from);
+}
+
+/* movzx m16 to r32 */
+void MOVZX32M16toR(int to, u32 from) {
+ write16(0xB70F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* cmovne r32 to r32 */
+void CMOVNE32RtoR(int to, int from) {
+ CMOV32RtoR(0x45, to, from);
+}
+
+/* cmovne m32 to r32*/
+void CMOVNE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x45, to, from);
+}
+
+/* cmove r32 to r32*/
+void CMOVE32RtoR(int to, int from) {
+ CMOV32RtoR(0x44, to, from);
+}
+
+/* cmove m32 to r32*/
+void CMOVE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x44, to, from);
+}
+
+/* cmovg r32 to r32*/
+void CMOVG32RtoR(int to, int from) {
+ CMOV32RtoR(0x4F, to, from);
+}
+
+/* cmovg m32 to r32*/
+void CMOVG32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4F, to, from);
+}
+
+/* cmovge r32 to r32*/
+void CMOVGE32RtoR(int to, int from) {
+ CMOV32RtoR(0x4D, to, from);
+}
+
+/* cmovge m32 to r32*/
+void CMOVGE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4D, to, from);
+}
+
+/* cmovl r32 to r32*/
+void CMOVL32RtoR(int to, int from) {
+ CMOV32RtoR(0x4C, to, from);
+}
+
+/* cmovl m32 to r32*/
+void CMOVL32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4C, to, from);
+}
+
+/* cmovle r32 to r32*/
+void CMOVLE32RtoR(int to, int from) {
+ CMOV32RtoR(0x4E, to, from);
+}
+
+/* cmovle m32 to r32*/
+void CMOVLE32MtoR(int to, u32 from) {
+ CMOV32MtoR(0x4E, to, from);
+}
+
+// arithmic instructions
+
+/* add imm32 to r32 */
+void ADD32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x05);
+ } else {
+ write8(0x81);
+ ModRM(3, 0, to);
+ }
+ write32(from);
+}
+
+/* add imm32 to m32 */
+void ADD32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 0, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* add r32 to r32 */
+void ADD32RtoR(int to, int from) {
+ write8(0x01);
+ ModRM(3, from, to);
+}
+
+/* add r32 to m32 */
+void ADD32RtoM(u32 to, int from) {
+ write8(0x01);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* add m32 to r32 */
+void ADD32MtoR(int to, u32 from) {
+ write8(0x03);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* adc imm32 to r32 */
+void ADC32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x15);
+ } else {
+ write8(0x81);
+ ModRM(3, 2, to);
+ }
+ write32(from);
+}
+
+/* adc r32 to r32 */
+void ADC32RtoR(int to, int from) {
+ write8(0x11);
+ ModRM(3, from, to);
+}
+
+/* adc m32 to r32 */
+void ADC32MtoR(int to, u32 from) {
+ write8(0x13);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* inc r32 */
+void INC32R(int to) {
+ write8(0x40 + to);
+}
+
+/* inc m32 */
+void INC32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 0, DISP32);
+ write32(to);
+}
+
+/* sub imm32 to r32 */
+void SUB32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x2D);
+ } else {
+ write8(0x81);
+ ModRM(3, 5, to);
+ }
+ write32(from);
+}
+
+/* sub r32 to r32 */
+void SUB32RtoR(int to, int from) {
+ write8(0x29);
+ ModRM(3, from, to);
+}
+
+/* sub m32 to r32 */
+void SUB32MtoR(int to, u32 from) {
+ write8(0x2B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* sbb imm32 to r32 */
+void SBB32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x1D);
+ } else {
+ write8(0x81);
+ ModRM(3, 3, to);
+ }
+ write32(from);
+}
+
+/* sbb r32 to r32 */
+void SBB32RtoR(int to, int from) {
+ write8(0x19);
+ ModRM(3, from, to);
+}
+
+/* sbb m32 to r32 */
+void SBB32MtoR(int to, u32 from) {
+ write8(0x1B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* dec r32 */
+void DEC32R(int to) {
+ write8(0x48 + to);
+}
+
+/* dec m32 */
+void DEC32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 1, DISP32);
+ write32(to);
+}
+
+/* mul eax by r32 to edx:eax */
+void MUL32R(int from) {
+ write8(0xF7);
+ ModRM(3, 4, from);
+}
+
+/* imul eax by r32 to edx:eax */
+void IMUL32R(int from) {
+ write8(0xF7);
+ ModRM(3, 5, from);
+}
+
+/* mul eax by m32 to edx:eax */
+void MUL32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 4, DISP32);
+ write32(from);
+}
+
+/* imul eax by m32 to edx:eax */
+void IMUL32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 5, DISP32);
+ write32(from);
+}
+
+/* imul r32 by r32 to r32 */
+void IMUL32RtoR(int to, int from) {
+ write16(0xAF0F);
+ ModRM(3, to, from);
+}
+
+/* div eax by r32 to edx:eax */
+void DIV32R(int from) {
+ write8(0xF7);
+ ModRM(3, 6, from);
+}
+
+/* idiv eax by r32 to edx:eax */
+void IDIV32R(int from) {
+ write8(0xF7);
+ ModRM(3, 7, from);
+}
+
+/* div eax by m32 to edx:eax */
+void DIV32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 6, DISP32);
+ write32(from);
+}
+
+/* idiv eax by m32 to edx:eax */
+void IDIV32M(u32 from) {
+ write8(0xF7);
+ ModRM(0, 7, DISP32);
+ write32(from);
+}
+
+// shifting instructions
+
+void RCR32ItoR(int to,int from)
+{
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xd8 | to);
+ }
+ else
+ {
+ write8(0xc1);
+ write8(0xd8 | to);
+ write8(from);
+ }
+}
+
+/* shl imm8 to r32 */
+void SHL32ItoR(int to, u8 from) {
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xe0 | to);
+ return;
+ }
+ write8(0xC1);
+ ModRM(3, 4, to);
+ write8(from);
+}
+
+/* shl cl to r32 */
+void SHL32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 4, to);
+}
+
+/* shr imm8 to r32 */
+void SHR32ItoR(int to, u8 from) {
+ if (from==1)
+ {
+ write8(0xd1);
+ write8(0xe8 | to);
+ return;
+ }
+ write8(0xC1);
+ ModRM(3, 5, to);
+ write8(from);
+}
+
+/* shr cl to r32 */
+void SHR32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 5, to);
+}
+
+/* sar imm8 to r32 */
+void SAR32ItoR(int to, u8 from) {
+ write8(0xC1);
+ ModRM(3, 7, to);
+ write8(from);
+}
+
+/* sar cl to r32 */
+void SAR32CLtoR(int to) {
+ write8(0xD3);
+ ModRM(3, 7, to);
+}
+
+
+// logical instructions
+
+/* or imm32 to r32 */
+void OR32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x0D);
+ } else {
+ write8(0x81);
+ ModRM(3, 1, to);
+ }
+ write32(from);
+}
+
+/* or imm32 to m32 */
+void OR32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 1, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* or r32 to r32 */
+void OR32RtoR(int to, int from) {
+ write8(0x09);
+ ModRM(3, from, to);
+}
+
+/* or r32 to m32 */
+void OR32RtoM(u32 to, int from) {
+ write8(0x09);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* or m32 to r32 */
+void OR32MtoR(int to, u32 from) {
+ write8(0x0B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* xor imm32 to r32 */
+void XOR32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x35);
+ } else {
+ write8(0x81);
+ ModRM(3, 6, to);
+ }
+ write32(from);
+}
+
+/* xor imm32 to m32 */
+void XOR32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 6, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* xor r32 to r32 */
+void XOR32RtoR(int to, int from) {
+ write8(0x31);
+ ModRM(3, from, to);
+}
+
+/* xor r32 to m32 */
+void XOR32RtoM(u32 to, int from) {
+ write8(0x31);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* xor m32 to r32 */
+void XOR32MtoR(int to, u32 from) {
+ write8(0x33);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* and imm32 to r32 */
+void AND32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x25);
+ } else {
+ write8(0x81);
+ ModRM(3, 0x4, to);
+ }
+ write32(from);
+}
+
+/* and imm32 to m32 */
+void AND32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 0x4, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* and r32 to r32 */
+void AND32RtoR(int to, int from) {
+ write8(0x21);
+ ModRM(3, from, to);
+}
+
+/* and r32 to m32 */
+void AND32RtoM(u32 to, int from) {
+ write8(0x21);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* and m32 to r32 */
+void AND32MtoR(int to, u32 from) {
+ write8(0x23);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* not r32 */
+void NOT32R(int from) {
+ write8(0xF7);
+ ModRM(3, 2, from);
+}
+
+/* neg r32 */
+void NEG32R(int from) {
+ write8(0xF7);
+ ModRM(3, 3, from);
+}
+
+// jump instructions
+
+/* jmp rel8 */
+u8* JMP8(u8 to) {
+ write8(0xEB);
+ write8(to);
+ return x86Ptr - 1;
+}
+
+/* jmp rel32 */
+u32* JMP32(u32 to) {
+ write8(0xE9);
+ write32(to);
+ return (u32*)(x86Ptr - 4);
+}
+
+/* jmp r32 */
+void JMP32R(int to) {
+ write8(0xFF);
+ ModRM(3, 4, to);
+}
+
+/* je rel8 */
+u8* JE8(u8 to) {
+ J8Rel(0x74, to);
+}
+
+/* jz rel8 */
+u8* JZ8(u8 to) {
+ J8Rel(0x74, to);
+}
+
+/* jg rel8 */
+u8* JG8(u8 to) {
+ J8Rel(0x7F, to);
+}
+
+/* jge rel8 */
+u8* JGE8(u8 to) {
+ J8Rel(0x7D, to);
+}
+
+/* jl rel8 */
+u8* JL8(u8 to) {
+ J8Rel(0x7C, to);
+}
+
+/* jle rel8 */
+u8* JLE8(u8 to) {
+ J8Rel(0x7E, to);
+}
+
+/* jne rel8 */
+u8* JNE8(u8 to) {
+ J8Rel(0x75, to);
+}
+
+/* jnz rel8 */
+u8* JNZ8(u8 to) {
+ J8Rel(0x75, to);
+}
+
+/* jng rel8 */
+u8* JNG8(u8 to) {
+ J8Rel(0x7E, to);
+}
+
+/* jnge rel8 */
+u8* JNGE8(u8 to) {
+ J8Rel(0x7C, to);
+}
+
+/* jnl rel8 */
+u8* JNL8(u8 to) {
+ J8Rel(0x7D, to);
+}
+
+/* jnle rel8 */
+u8* JNLE8(u8 to) {
+ J8Rel(0x7F, to);
+}
+
+/* jo rel8 */
+u8* JO8(u8 to) {
+ J8Rel(0x70, to);
+}
+
+/* jno rel8 */
+u8* JNO8(u8 to) {
+ J8Rel(0x71, to);
+}
+
+/* je rel32 */
+u32* JE32(u32 to) {
+ J32Rel(0x84, to);
+}
+
+/* jz rel32 */
+u32* JZ32(u32 to) {
+ J32Rel(0x84, to);
+}
+
+/* jg rel32 */
+u32* JG32(u32 to) {
+ J32Rel(0x8F, to);
+}
+
+/* jge rel32 */
+u32* JGE32(u32 to) {
+ J32Rel(0x8D, to);
+}
+
+/* jl rel32 */
+u32* JL32(u32 to) {
+ J32Rel(0x8C, to);
+}
+
+/* jle rel32 */
+u32* JLE32(u32 to) {
+ J32Rel(0x8E, to);
+}
+
+/* jne rel32 */
+u32* JNE32(u32 to) {
+ J32Rel(0x85, to);
+}
+
+/* jnz rel32 */
+u32* JNZ32(u32 to) {
+ J32Rel(0x85, to);
+}
+
+/* jng rel32 */
+u32* JNG32(u32 to) {
+ J32Rel(0x8E, to);
+}
+
+/* jnge rel32 */
+u32* JNGE32(u32 to) {
+ J32Rel(0x8C, to);
+}
+
+/* jnl rel32 */
+u32* JNL32(u32 to) {
+ J32Rel(0x8D, to);
+}
+
+/* jnle rel32 */
+u32* JNLE32(u32 to) {
+ J32Rel(0x8F, to);
+}
+
+/* jo rel32 */
+u32* JO32(u32 to) {
+ J32Rel(0x80, to);
+}
+
+/* jno rel32 */
+u32* JNO32(u32 to) {
+ J32Rel(0x81, to);
+}
+
+/* call func */
+void CALLFunc(u32 func) {
+ CALL32(func - ((u32)x86Ptr + 5));
+}
+
+/* call rel32 */
+void CALL32(u32 to) {
+ write8(0xE8);
+ write32(to);
+}
+
+/* call r32 */
+void CALL32R(int to) {
+ write8(0xFF);
+ ModRM(3, 2, to);
+}
+
+/* call m32 */
+void CALL32M(u32 to) {
+ write8(0xFF);
+ ModRM(0, 2, DISP32);
+ write32(to);
+}
+
+// misc instructions
+
+/* cmp imm32 to r32 */
+void CMP32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0x3D);
+ } else {
+ write8(0x81);
+ ModRM(3, 7, to);
+ }
+ write32(from);
+}
+
+/* cmp imm32 to m32 */
+void CMP32ItoM(u32 to, u32 from) {
+ write8(0x81);
+ ModRM(0, 7, DISP32);
+ write32(to);
+ write32(from);
+}
+
+/* cmp r32 to r32 */
+void CMP32RtoR(int to, int from) {
+ write8(0x39);
+ ModRM(3, from, to);
+}
+
+/* cmp m32 to r32 */
+void CMP32MtoR(int to, u32 from) {
+ write8(0x3B);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* test imm32 to r32 */
+void TEST32ItoR(int to, u32 from) {
+ if (to == EAX) {
+ write8(0xA9);
+ } else {
+ write8(0xF7);
+ ModRM(3, 0, to);
+ }
+ write32(from);
+}
+
+/* test r32 to r32 */
+void TEST32RtoR(int to, int from) {
+ write8(0x85);
+ ModRM(3, from, to);
+}
+
+void BT32ItoR(int to,int from)
+{
+ write16(0xba0f);
+ write8(0xe0 | to);
+ write8(from);
+}
+
+/* sets r8 */
+void SETS8R(int to) {
+ SET8R(0x98, to);
+}
+/* setl r8 */
+void SETL8R(int to) {
+ SET8R(0x9C, to);
+}
+
+/* setb r8 */
+void SETB8R(int to) {
+ SET8R(0x92, to);
+}
+
+/* setnz r8 */
+void SETNZ8R(int to) {
+ SET8R(0x95,to);
+}
+
+/* cbw */
+void CBW() {
+ write16(0x9866);
+}
+
+/* cwd */
+void CWD() {
+ write8(0x98);
+}
+
+/* cdq */
+void CDQ() {
+ write8(0x99);
+}
+
+/* push r32 */
+void PUSH32R(int from) {
+ write8(0x50 | from);
+}
+
+/* push m32 */
+void PUSH32M(u32 from) {
+ write8(0xFF);
+ ModRM(0, 6, DISP32);
+ write32(from);
+}
+
+/* push imm32 */
+void PUSH32I(u32 from) {
+ write8(0x68); write32(from);
+}
+
+/* pop r32 */
+void POP32R(int from) {
+ write8(0x58 | from);
+}
+
+/* pushad */
+void PUSHA32() {
+ write8(0x60);
+}
+
+/* popad */
+void POPA32() {
+ write8(0x61);
+}
+
+/* ret */
+void RET() {
+ write8(0xC3);
+}
+
+/********************/
+/* FPU instructions */
+/********************/
+
+//Added:basara 14.01.2003
+/* compare m32 to fpu reg stack */
+void FCOMP32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x3, DISP32);
+ write32(from);
+}
+
+void FNSTSWtoAX() {
+ write16(0xE0DF);
+}
+
+/* fild m32 to fpu reg stack */
+void FILD32(u32 from) {
+ write8(0xDB);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fistp m32 from fpu reg stack */
+void FISTP32(u32 from) {
+ write8(0xDB);
+ ModRM(0, 0x3, DISP32);
+ write32(from);
+}
+
+/* fld m32 to fpu reg stack */
+void FLD32(u32 from) {
+ write8(0xD9);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fstp m32 from fpu reg stack */
+void FSTP32(u32 to) {
+ write8(0xD9);
+ ModRM(0, 0x3, DISP32);
+ write32(to);
+}
+
+//
+
+/* fldcw fpu control word from m16 */
+void FLDCW(u32 from) {
+ write8(0xD9);
+ ModRM(0, 0x5, DISP32);
+ write32(from);
+}
+
+/* fnstcw fpu control word to m16 */
+void FNSTCW(u32 to) {
+ write8(0xD9);
+ ModRM(0, 0x7, DISP32);
+ write32(to);
+}
+
+//
+
+/* fadd m32 to fpu reg stack */
+void FADD32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x0, DISP32);
+ write32(from);
+}
+
+/* fsub m32 to fpu reg stack */
+void FSUB32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x4, DISP32);
+ write32(from);
+}
+
+/* fmul m32 to fpu reg stack */
+void FMUL32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x1, DISP32);
+ write32(from);
+}
+
+/* fdiv m32 to fpu reg stack */
+void FDIV32(u32 from) {
+ write8(0xD8);
+ ModRM(0, 0x6, DISP32);
+ write32(from);
+}
+
+/* fabs fpu reg stack */
+void FABS() {
+ write16(0xE1D9);
+}
+
+/* fsqrt fpu reg stack */
+void FSQRT() {
+ write16(0xFAD9);
+}
+
+/* fchs fpu reg stack */
+void FCHS() {
+ write16(0xE0D9);
+}
+
+/********************/
+/* MMX instructions */
+/********************/
+
+// r64 = mm
+
+/* movq m64 to r64 */
+void MOVQMtoR(int to, u32 from) {
+ write16(0x6F0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movq r64 to m64 */
+void MOVQRtoM(u32 to, int from) {
+ write16(0x7F0F);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* pand r64 to r64 */
+void PANDRtoR(int to, int from) {
+ write16(0xDB0F);
+ ModRM(3, to, from);
+}
+
+/* pand r64 to r64 */
+void PANDNRtoR(int to, int from) {
+ write16(0xDF0F);
+ ModRM(3, to, from);
+}
+
+/* por r64 to r64 */
+void PORRtoR(int to, int from) {
+ write16(0xEB0F);
+ ModRM(3, to, from);
+}
+
+/* pxor r64 to r64 */
+void PXORRtoR(int to, int from) {
+ write16(0xEF0F);
+ ModRM(3, to, from);
+}
+
+/* psllq r64 to r64 */
+void PSLLQRtoR(int to, int from) {
+ write16(0xF30F);
+ ModRM(3, to, from);
+}
+
+/* psllq m64 to r64 */
+void PSLLQMtoR(int to, u32 from) {
+ write16(0xF30F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* psllq imm8 to r64 */
+void PSLLQItoR(int to, u8 from) {
+ write16(0x730F);
+ ModRM(3, 6, to);
+ write8(from);
+}
+
+/* psrlq r64 to r64 */
+void PSRLQRtoR(int to, int from) {
+ write16(0xD30F);
+ ModRM(3, to, from);
+}
+
+/* psrlq m64 to r64 */
+void PSRLQMtoR(int to, u32 from) {
+ write16(0xD30F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* psrlq imm8 to r64 */
+void PSRLQItoR(int to, u8 from) {
+ write16(0x730F);
+ ModRM(3, 2, to);
+ write8(from);
+}
+
+/* paddusb r64 to r64 */
+void PADDUSBRtoR(int to, int from) {
+ write16(0xDC0F);
+ ModRM(3, to, from);
+}
+
+/* paddusb m64 to r64 */
+void PADDUSBMtoR(int to, u32 from) {
+ write16(0xDC0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddusw r64 to r64 */
+void PADDUSWRtoR(int to, int from) {
+ write16(0xDD0F);
+ ModRM(3, to, from);
+}
+
+/* paddusw m64 to r64 */
+void PADDUSWMtoR(int to, u32 from) {
+ write16(0xDD0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddb r64 to r64 */
+void PADDBRtoR(int to, int from) {
+ write16(0xFC0F);
+ ModRM(3, to, from);
+}
+
+/* paddb m64 to r64 */
+void PADDBMtoR(int to, u32 from) {
+ write16(0xFC0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddw r64 to r64 */
+void PADDWRtoR(int to, int from) {
+ write16(0xFD0F);
+ ModRM(3, to, from);
+}
+
+/* paddw m64 to r64 */
+void PADDWMtoR(int to, u32 from) {
+ write16(0xFD0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* paddd r64 to r64 */
+void PADDDRtoR(int to, int from) {
+ write16(0xFE0F);
+ ModRM(3, to, from);
+}
+
+/* paddd m64 to r64 */
+void PADDDMtoR(int to, u32 from) {
+ write16(0xFE0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* emms */
+void EMMS() {
+ //use femms if we have 3dnow
+ write16(0x0e0f);
+ return;
+}
+
+/* femms */
+void FEMMS() {
+ write16(0x770F);
+ return;
+}
+
+//Basara:changed
+void PADDSBRtoR(int to, int from) {
+ write16(0xEC0F);
+ ModRM(3, to, from);
+}
+
+void PADDSWRtoR(int to, int from) {
+ write16(0xED0F);
+ ModRM(3, to, from);
+}
+
+void PADDSDRtoR(int to, int from) {
+ write16(0xEE0F);
+ ModRM(3, to, from);
+}
+
+void PSUBSBRtoR(int to, int from) {
+ write16(0xE80F);
+ ModRM(3, to, from);
+}
+
+void PSUBSWRtoR(int to, int from) {
+ write16(0xE90F);
+ ModRM(3, to, from);
+}
+
+void PSUBSDRtoR(int to, int from) {
+ write16(0xEA0F);
+ ModRM(3, to, from);
+}
+
+void PSUBBRtoR(int to, int from) {
+ write16(0xF80F);
+ ModRM(3, to, from);
+}
+
+void PSUBWRtoR(int to, int from) {
+ write16(0xF90F);
+ ModRM(3, to, from);
+}
+
+void PSUBDRtoR(int to, int from) {
+ write16(0xFA0F);
+ ModRM(3, to, from);
+}
+
+//changed:basara
+//P.s.It's sux.Don't use it offten.
+void MOVQ64ItoR(int reg,u64 i)
+{
+ MOVQMtoR(reg,(u32)(x86Ptr)+2+7);
+ JMP8(8);
+ write64(i);
+}
+
+void PSUBUSBRtoR(int to, int from) {
+ write16(0xD80F);
+ ModRM(3, to, from);
+}
+
+void PSUBUSWRtoR(int to, int from) {
+ write16(0xD90F);
+ ModRM(3, to, from);
+}
+
+void PMAXSWRtoR(int to,int from)
+{
+ write16(0xEE0F);
+ ModRM(3, to, from);
+}
+
+void PMINSWRtoR(int to,int from)
+{
+ write16(0xEA0F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQBRtoR(int to,int from)
+{
+ write16(0x740F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQWRtoR(int to,int from)
+{
+ write16(0x750F);
+ ModRM(3, to, from);
+}
+
+void PCMPEQDRtoR(int to,int from)
+{
+ write16(0x760F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTBRtoR(int to,int from)
+{
+ write16(0x640F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTWRtoR(int to,int from)
+{
+ write16(0x650F);
+ ModRM(3, to, from);
+}
+
+void PCMPGTDRtoR(int to,int from)
+{
+ write16(0x660F);
+ ModRM(3, to, from);
+}
+
+//Basara:Added 10.01.2003
+void PSRLWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(2, 2 , to);
+ write8(from);
+}
+void PSRLDItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(2, 2 , to);
+ write8(from);
+}
+
+void PSLLWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(3, 6 , to);
+ write8(from);
+}
+
+void PSLLDItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(3, 6 , to);
+ write8(from);
+}
+
+void PSRAWItoR(int to,int from)
+{
+ write16(0x710f);
+ ModRM(3, 4 , to);
+ write8(from);
+}
+
+void PSRADItoR(int to,int from)
+{
+ write16(0x720f);
+ ModRM(3, 4 , to);
+ write8(from);
+}
+
+/* por m64 to r64 */
+void PORMtoR(int to, u32 from) {
+ write16(0xEB0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pxor m64 to r64 */
+void PXORMtoR(int to, u32 from) {
+ write16(0xEF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pand m64 to r64 */
+void PANDMtoR(int to, u32 from) {
+ write16(0xDB0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* pandn m64 to r64 */
+void PANDNMtoR(int to, u32 from) {
+ write16(0xDF0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movd m32 to r64 */
+void MOVDMtoR(int to, u32 from) {
+ write16(0x6E0F);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+/* movq r64 to m32 */
+void MOVDRtoM(u32 to, int from) {
+ write16(0x7E0F);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+/* movd r32 to r64 */
+void MOVD32RtoR(int to, int from) {
+ write16(0x6E0F);
+ ModRM(3, to,from);
+}
+
+/* movq r64 to r32 */
+void MOVD64RtoR(int to, int from) {
+ write16(0x7E0F);
+ ModRM(3, from,to);
+}
+
+void MOVQRtoR(int to, int from) {
+ write16(0x6F0F);
+ ModRM(3, to,from);
+}
+
+void PUNPCKHDQRtoR(int to, int from) {
+ write16(0x6A0F);
+ ModRM(3, to,from);
+}
+
+void PUNPCKLDQRtoR(int to, int from) {
+ write16(0x620F);
+ ModRM(3, to,from);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SSE intructions
+//////////////////////////////////////////////////////////////////////////
+
+void MOVAPSMtoR(int to, int from) {
+ write16(0x280f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void MOVAPSRtoM(int to, int from) {
+ write16(0x2b0f);
+ ModRM(0, from, DISP32);
+ write32(to);
+}
+
+void MOVAPSRtoR(int to, int from) {
+ write16(0x290f);
+ ModRM(3, to,from);
+}
+
+void ORPSMtoR(int to, int from) {
+ write16(0x560f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void ORPSRtoR(int to, int from) {
+ write16(0x560f);
+ ModRM(3, to,from);
+}
+
+void XORPSMtoR(int to, int from) {
+ write16(0x570f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void XORPSRtoR(int to, int from) {
+ write16(0x570f);
+ ModRM(3, to,from);
+}
+
+void ANDPSMtoR(int to, int from) {
+ write16(0x540f);
+ ModRM(0, to, DISP32);
+ write32(from);
+}
+
+void ANDPSRtoR(int to, int from) {
+ write16(0x540f);
+ ModRM(3, to,from);
+}
+
+/*
+ 3DNOW intructions
+*/
+
+void PFCMPEQMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xb0);
+}
+
+void PFCMPGTMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xa0);
+}
+
+void PFCMPGEMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x90);
+}
+
+void PFADDMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x9e);
+}
+
+void PFADDRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x9e);
+}
+
+void PFSUBMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x9a);
+}
+
+void PFSUBRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x9a);
+}
+
+void PFMULMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xb4);
+}
+
+void PFMULRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xb4);
+}
+
+void PFRCPMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x96);
+}
+
+void PFRCPRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0x96);
+}
+
+void PFRCPIT1RtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xa6);
+}
+
+void PFRCPIT2RtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xb6);
+}
+
+void PFRSQRTRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0x97);
+}
+
+void PFRSQIT1RtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to,from);
+ write8(0xa7);
+}
+
+void PF2IDMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x1d);
+}
+
+void PF2IDRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x1d);
+}
+
+void PI2FDMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x0d);
+}
+
+void PI2FDRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x0d);
+}
+
+/*
+ 3DNOW Extension intructions
+*/
+
+void PFMAXMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0xa4);
+}
+
+void PFMAXRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0xa4);
+}
+
+void PFMINMtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(0, to, DISP32);
+ write32(from);
+ write8(0x94);
+}
+
+void PFMINRtoR(int to, int from) {
+ write16(0x0f0f);
+ ModRM(3, to, from);
+ write8(0x94);
+}
+
+#endif