diff options
Diffstat (limited to 'libpcsxcore/ix86')
| -rwxr-xr-x[-rw-r--r--] | libpcsxcore/ix86/iR3000A.c | 6030 | ||||
| -rwxr-xr-x[-rw-r--r--] | libpcsxcore/ix86/ix86.c | 3454 |
2 files changed, 4742 insertions, 4742 deletions
diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c index 029b8bab..942429b2 100644..100755 --- a/libpcsxcore/ix86/iR3000A.c +++ b/libpcsxcore/ix86/iR3000A.c @@ -1,3015 +1,3015 @@ -/***************************************************************************
- * 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 02110-1301 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);
-}
-
-#if 0
-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");
- }
-}
-#endif
-
-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;
- }
-}
-
-#if 0
-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;
-}
-#endif
-
-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
-
-#if 0
-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;
-}
-#endif
-
-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
+/*************************************************************************** + * 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 02110-1301 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); +} + +#if 0 +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"); + } +} +#endif + +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; + } +} + +#if 0 +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; +} +#endif + +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 + +#if 0 +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; +} +#endif + +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 ef615820..06275ffa 100644..100755 --- 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 02110-1301 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
+/*************************************************************************** + * 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 02110-1301 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 |
