Cleaned up and streamlined the namespaces quite a bit, split some code into separate modules, and cleaned up the Common.h header file by removing all the unnecessary not-so-common pieces parts.

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@620 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2009-01-22 05:50:24 +00:00 committed by Gregory Hainaut
parent e312e9d25c
commit 3fc08b659b
103 changed files with 1502 additions and 1666 deletions

View File

@ -22,8 +22,6 @@
#include "R5900.h"
#include "InterTables.h"
namespace R5900
{
u32 s_iLastCOP0Cycle = 0;
u32 s_iLastPERFCycle[2] = { 0, 0 };
@ -150,6 +148,7 @@ void WriteTLB(int i)
MapTLB(i);
}
namespace R5900 {
namespace Interpreter {
namespace OpcodeImpl {
namespace COP0 {

View File

@ -19,13 +19,10 @@
#ifndef __COP0_H__
#define __COP0_H__
namespace R5900
{
void WriteCP0Status(u32 value);
void UpdateCP0Status();
void WriteTLB(int i);
void UnmapTLB(int i);
void MapTLB(int i);
}
void WriteCP0Status(u32 value);
void UpdateCP0Status();
void WriteTLB(int i);
void UnmapTLB(int i);
void MapTLB(int i);
#endif /* __COP0_H__ */

View File

@ -18,9 +18,10 @@
#include "PrecompiledHeader.h"
//THIS ALL IS FOR THE CDROM REGISTERS HANDLING
#include "PsxCommon.h"
//THIS ALL IS FOR THE CDROM REGISTERS HANDLING
#define CdlSync 0
#define CdlNop 1
#define CdlSetloc 2

View File

@ -69,18 +69,9 @@ extern TESTRUNARGS g_TestRun;
#include "Memory.h"
#include "Elfheader.h"
#include "Hw.h"
#include "Vif.h"
#include "SPR.h"
#include "Sif.h"
// Moving this before one of the other includes causes compilation issues.
#include "Misc.h"
#include "Counters.h"
#include "Patch.h"
#include "COP0.h"
#include "VifDma.h"
#if defined(__i386__)
#include "x86/ix86/ix86.h"
#endif
#define PCSX2_VERSION "Playground (beta)"

View File

@ -21,7 +21,11 @@
#include <time.h>
#include <cmath>
#include "Common.h"
#include "PsxCommon.h"
#include "Counters.h"
#include "R3000A.h"
#include "PsxCounters.h"
#include "GS.h"
#include "VUmicro.h"
@ -30,9 +34,6 @@ using namespace Threading;
extern u8 psxhblankgate;
u32 g_vu1SkipCount; // number of frames to disable/skip VU1
namespace R5900
{
static const uint EECNT_FUTURE_TARGET = 0x10000000;
u64 profile_starttick = 0;
@ -835,10 +836,6 @@ u32 rcntCycle(int index)
return counters[index].count;
}
} // End namespace R5900!
using namespace R5900;
void SaveState::rcntFreeze()
{
Freeze(counters);

View File

@ -19,8 +19,6 @@
#ifndef __COUNTERS_H__
#define __COUNTERS_H__
namespace R5900
{
struct EECNT_MODE
{
// 0 - BUSCLK
@ -147,6 +145,4 @@ u32 rcntCycle(int index);
u32 UpdateVSyncRate();
void frameLimitReset();
} // End namespace R5900!
#endif /* __COUNTERS_H__ */

View File

@ -24,9 +24,6 @@
extern FILE *emuLog;
extern char* disR3000Fasm(u32 code, u32 pc);
extern char* disR3000AF(u32 code, u32 pc);
extern char* disVU0MicroUF(u32 code, u32 pc);
extern char* disVU0MicroLF(u32 code, u32 pc);
extern char* disVU1MicroUF(u32 code, u32 pc);
@ -65,9 +62,13 @@ namespace R5900
extern DisR5900CurrentState disR5900Current;
}
namespace R3000a
namespace R3000A
{
extern void (*IOP_DEBUG_BSC[64])(char *buf);
extern const char * const disRNameGPR[];
extern char* disR3000Fasm(u32 code, u32 pc);
extern char* disR3000AF(u32 code, u32 pc);
}
#ifdef PCSX2_DEVBUILD

View File

@ -19,8 +19,6 @@
#include <stdio.h>
#include <string.h>
#include "R5900.h"
//DECODE PROCUDURES
//cop0

View File

@ -18,13 +18,14 @@
#include "PrecompiledHeader.h"
#include "R3000A.h"
#include "Debug.h"
static char ostr[1024];
namespace R3000A
{
static char ostr[1024];
// Names of registers
namespace R3000a
{
const char * const disRNameGPR[] = {
"r0", "at", "v0", "v1", "a0", "a1","a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5","t6", "t7",
@ -36,9 +37,6 @@ namespace R3000a
"BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" ,
"Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" ,
"*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" };
}
using namespace R3000a;
// Type definition of our functions
@ -53,8 +51,6 @@ typedef char* (*TdisR3000AF)(u32 code, u32 pc);
}
#include "R3000A.h"
#undef _Funct_
#undef _Rd_
#undef _Rt_
@ -322,3 +318,5 @@ TdisR3000AF disR3000A[] = {
disNULL , disNULL , disSWC2 , disNULL , disNULL, disNULL, disNULL , disNULL };
MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc))
}

View File

@ -19,10 +19,11 @@
#include "PrecompiledHeader.h"
#include "Debug.h"
#include "R5900.h"
#include "R3000A.h"
#include "DisASM.h"
namespace R3000A {
unsigned long IOP_opcode_addr;
const char *GPR_IOP_REG[32] = {
@ -358,3 +359,5 @@ void IOPD_MTC2(char *buf){strcpy(buf, "mtc2");}
void IOPD_CTC2(char *buf){strcpy(buf, "ctc2");}
//null
void IOPD_NULL(char *buf){strcpy(buf, "????");}
} // end Namespace R3000A

View File

@ -22,7 +22,6 @@
#include "CDVDisodrv.h"
using namespace std;
using namespace R5900;
#ifdef _MSC_VER
#pragma warning(disable:4996) //ignore the stricmp deprecated warning
@ -492,7 +491,7 @@ struct ElfObject
for( uint i = 1; i < ( secthead[ i_st ].sh_size / sizeof( Elf32_Sym ) ); i++ ) {
if ( ( eS[ i ].st_value != 0 ) && ( ELF32_ST_TYPE( eS[ i ].st_info ) == 2 ) ) {
disR5900AddSym( eS[i].st_value, &SymNames[ eS[ i ].st_name ] );
R5900::disR5900AddSym( eS[i].st_value, &SymNames[ eS[ i ].st_name ] );
}
}
}

View File

@ -22,7 +22,8 @@
#include "Hw.h"
#include "GS.h"
#include <assert.h>
#include "Vif.h"
#include "VifDma.h"
//////////////////////////////////////////////////////////////////////////
/////////////////////////// Quick & dirty FIFO :D ////////////////////////

View File

@ -24,6 +24,9 @@
#include "VU.h"
#include "GS.h"
#include "iR5900.h"
#include "Counters.h"
#include "VifDma.h"
using namespace Threading;
using namespace std;

View File

@ -270,20 +270,17 @@ u16 gsRead16(u32 mem);
u32 gsRead32(u32 mem);
u64 gsRead64(u32 mem);
namespace Dynarec
{
void gsConstWrite8(u32 mem, int mmreg);
void gsConstWrite16(u32 mem, int mmreg);
void gsConstWrite32(u32 mem, int mmreg);
void gsConstWrite64(u32 mem, int mmreg);
void gsConstWrite128(u32 mem, int mmreg);
void gsConstWrite8(u32 mem, int mmreg);
void gsConstWrite16(u32 mem, int mmreg);
void gsConstWrite32(u32 mem, int mmreg);
void gsConstWrite64(u32 mem, int mmreg);
void gsConstWrite128(u32 mem, int mmreg);
int gsConstRead8(u32 x86reg, u32 mem, u32 sign);
int gsConstRead16(u32 x86reg, u32 mem, u32 sign);
int gsConstRead32(u32 x86reg, u32 mem);
void gsConstRead64(u32 mem, int mmreg);
void gsConstRead128(u32 mem, int xmmreg);
}
int gsConstRead8(u32 x86reg, u32 mem, u32 sign);
int gsConstRead16(u32 x86reg, u32 mem, u32 sign);
int gsConstRead32(u32 x86reg, u32 mem);
void gsConstRead64(u32 mem, int mmreg);
void gsConstRead128(u32 mem, int xmmreg);
void gsIrq();
extern void gsInterrupt();

View File

@ -23,13 +23,17 @@
#include "iR5900.h"
#include "VUmicro.h"
#include "PsxMem.h"
// The full suite of hardware APIs:
#include "IPU/IPU.h"
#include "GS.h"
#include "Counters.h"
#include "Vif.h"
#include "Vifdma.h"
#include "SPR.h"
#include "Sif.h"
#include <assert.h>
using namespace Dynarec;
using namespace Dynarec::R5900;
using namespace R5900;
#ifndef PCSX2_VIRTUAL_MEM
u8 *psH; // hw mem

View File

@ -19,9 +19,6 @@
#ifndef __HW_H__
#define __HW_H__
#include "PS2Etypes.h"
#include <assert.h>
#ifndef PCSX2_VIRTUAL_MEM
extern u8 *psH; // hw mem
#endif
@ -35,11 +32,7 @@ extern u8 *psH; // hw mem
#define psHu32(mem) (*(u32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu64(mem) (*(u64*)&PS2MEM_HW[(mem) & 0xffff])
namespace R5900{
extern void CPU_INT( u32 n, s32 ecycle );
}
using R5900::CPU_INT;
// VIF0 -- 0x10004000 -- psH[0x4000]
// VIF1 -- 0x10005000 -- psH[0x5000]

View File

@ -25,8 +25,9 @@
#include "yuv2rgb.h"
#include "coroutine.h"
#include "Vif.h"
using namespace std; // for min / max
using R5900::cpuRegs;
// Zero cycle IRQ schedules aren't really good, but the IPU uses them.
// Better to throw the IRQ inline:

View File

@ -238,13 +238,10 @@ u64 ipuRead64(u32 mem);
void ipuWrite32(u32 mem,u32 value);
void ipuWrite64(u32 mem,u64 value);
namespace Dynarec
{
int ipuConstRead32(u32 x86reg, u32 mem);
void ipuConstRead64(u32 mem, int mmreg);
void ipuConstWrite32(u32 mem, int mmreg);
void ipuConstWrite64(u32 mem, int mmreg);
}
int ipuConstRead32(u32 x86reg, u32 mem);
void ipuConstRead64(u32 mem, int mmreg);
void ipuConstWrite32(u32 mem, int mmreg);
void ipuConstWrite64(u32 mem, int mmreg);
extern void IPUCMD_WRITE(u32 val);
extern void ipuSoftReset();

View File

@ -46,7 +46,7 @@ namespace R5900
cycles, \
NULL, \
::R5900::Interpreter::OpcodeImpl::name, \
::Dynarec::R5900::OpcodeImpl::rec##name, \
::R5900::Dynarec::OpcodeImpl::rec##name, \
::R5900::OpcodeDisasm::name \
}
@ -56,7 +56,7 @@ namespace R5900
cycles, \
NULL, \
::R5900::Interpreter::OpcodeImpl::MMI::name, \
::Dynarec::R5900::OpcodeImpl::MMI::rec##name, \
::R5900::Dynarec::OpcodeImpl::MMI::rec##name, \
::R5900::OpcodeDisasm::name \
}
@ -66,7 +66,7 @@ namespace R5900
cycles, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP0::name, \
::Dynarec::R5900::OpcodeImpl::COP0::rec##name, \
::R5900::Dynarec::OpcodeImpl::COP0::rec##name, \
::R5900::OpcodeDisasm::name \
}
@ -76,7 +76,7 @@ namespace R5900
cycles, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP1::name, \
::Dynarec::R5900::OpcodeImpl::COP1::rec##name, \
::R5900::Dynarec::OpcodeImpl::COP1::rec##name, \
::R5900::OpcodeDisasm::name \
}

View File

@ -34,9 +34,9 @@ void COP2_SPECIAL2();
void COP2_Unknown();
namespace Dynarec
namespace R5900
{
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{
void recUnknown();
@ -70,11 +70,8 @@ namespace Dynarec
void recTEQI();
void recTNEI();
}
} } // end namespace Dynarec::OpcodeImpl::EE
} }
namespace R5900
{
///////////////////////////////////////////////////////////////////////////
// Encapsulates information about every opcode on the Emotion Engine and
// it's many co-processors.
@ -150,10 +147,7 @@ namespace R5900
const OPCODE& Class_COP1_S();
const OPCODE& Class_COP1_W();
}
}
namespace R5900
{
namespace OpcodeDisasm
{
//****************************************************************
@ -444,10 +438,7 @@ namespace R5900
void CVT_S( std::string& output );
//**********************END OF COP1***********************
}
}
namespace R5900
{
namespace Interpreter {
namespace OpcodeImpl
{
@ -745,8 +736,8 @@ namespace R5900
void C_LE();
void CVT_S();
}
} } // end namespace R5900::Interpreter::OpcodeImpl::R5900
} // End namespace Interpreter
} }
} // End namespace R5900
//****************************************************************************
//** COP2 - (VU0) **

View File

@ -21,78 +21,16 @@
#include "Common.h"
#include "R5900.h"
#include "InterTables.h"
#include "VUmicro.h"
#include "ix86/ix86.h"
#include <float.h>
using namespace R5900; // for OPCODE and OpcodeImpl
extern int vu0branch, vu1branch;
namespace R5900
{
const char * const bios[256]=
{
//0x00
"RFU000_FullReset", "ResetEE", "SetGsCrt", "RFU003",
"Exit", "RFU005", "LoadExecPS2", "ExecPS2",
"RFU008", "RFU009", "AddSbusIntcHandler", "RemoveSbusIntcHandler",
"Interrupt2Iop", "SetVTLBRefillHandler", "SetVCommonHandler", "SetVInterruptHandler",
//0x10
"AddIntcHandler", "RemoveIntcHandler", "AddDmacHandler", "RemoveDmacHandler",
"_EnableIntc", "_DisableIntc", "_EnableDmac", "_DisableDmac",
"_SetAlarm", "_ReleaseAlarm", "_iEnableIntc", "_iDisableIntc",
"_iEnableDmac", "_iDisableDmac", "_iSetAlarm", "_iReleaseAlarm",
//0x20
"CreateThread", "DeleteThread", "StartThread", "ExitThread",
"ExitDeleteThread", "TerminateThread", "iTerminateThread", "DisableDispatchThread",
"EnableDispatchThread", "ChangeThreadPriority", "iChangeThreadPriority", "RotateThreadReadyQueue",
"iRotateThreadReadyQueue", "ReleaseWaitThread", "iReleaseWaitThread", "GetThreadId",
//0x30
"ReferThreadStatus","iReferThreadStatus", "SleepThread", "WakeupThread",
"_iWakeupThread", "CancelWakeupThread", "iCancelWakeupThread", "SuspendThread",
"iSuspendThread", "ResumeThread", "iResumeThread", "JoinThread",
"RFU060", "RFU061", "EndOfHeap", "RFU063",
//0x40
"CreateSema", "DeleteSema", "SignalSema", "iSignalSema",
"WaitSema", "PollSema", "iPollSema", "ReferSemaStatus",
"iReferSemaStatus", "RFU073", "SetOsdConfigParam", "GetOsdConfigParam",
"GetGsHParam", "GetGsVParam", "SetGsHParam", "SetGsVParam",
//0x50
"RFU080_CreateEventFlag", "RFU081_DeleteEventFlag",
"RFU082_SetEventFlag", "RFU083_iSetEventFlag",
"RFU084_ClearEventFlag", "RFU085_iClearEventFlag",
"RFU086_WaitEventFlag", "RFU087_PollEventFlag",
"RFU088_iPollEventFlag", "RFU089_ReferEventFlagStatus",
"RFU090_iReferEventFlagStatus", "RFU091_GetEntryAddress",
"EnableIntcHandler_iEnableIntcHandler",
"DisableIntcHandler_iDisableIntcHandler",
"EnableDmacHandler_iEnableDmacHandler",
"DisableDmacHandler_iDisableDmacHandler",
//0x60
"KSeg0", "EnableCache", "DisableCache", "GetCop0",
"FlushCache", "RFU101", "CpuConfig", "iGetCop0",
"iFlushCache", "RFU105", "iCpuConfig", "sceSifStopDma",
"SetCPUTimerHandler", "SetCPUTimer", "SetOsdConfigParam2", "SetOsdConfigParam2",
//0x70
"GsGetIMR_iGsGetIMR", "GsGetIMR_iGsPutIMR", "SetPgifHandler", "SetVSyncFlag",
"RFU116", "print", "sceSifDmaStat_isceSifDmaStat", "sceSifSetDma_isceSifSetDma",
"sceSifSetDChain_isceSifSetDChain", "sceSifSetReg", "sceSifGetReg", "ExecOSD",
"Deci2Call", "PSMode", "MachineType", "GetMemorySize",
};
const OPCODE& GetCurrentInstruction()
{
const OPCODE* opcode = &R5900::OpcodeTables::tbl_Standard[_Opcode_];
while( opcode->getsubclass != NULL )
opcode = &opcode->getsubclass();
return *opcode;
}
namespace Interpreter
{
static int branch2 = 0;
static u32 cpuBlockCycles = 0; // 3 bit fixed point version of cycle count
static std::string disOut;
// These macros are used to assemble the repassembler functions
@ -106,10 +44,6 @@ static void debugI()
static void debugI() {}
#endif
static u32 cpuBlockCycles = 0; // 3 bit fixed point version of cycle count
static std::string disOut;
//long int runs=0;
static void execI()
@ -178,66 +112,17 @@ void intSetBranch() {
branch2 = /*cpuRegs.branch =*/ 1;
}
void COP1_Unknown() {
FPU_LOG("Unknown FPU opcode called\n");
}
////////////////////////////////////////////////////////////////////
// R5900 Branching Instructions!
// These are the interpreter versions of the branch instructions. Unlike other
// types of interpreter instructions which can be called safely from the recompilers,
// these instructions are not "recSafe" because they may not invoke the
// necessary branch test logic that the recs need to maintain sync with the
// cpuRegs.pc and delaySlot instruction and such.
void COP0_Unknown(){
CPU_LOG("COP0 Unknown opcode called\n");
}
namespace OpcodeImpl
{
void COP2()
{
//std::string disOut;
//disR5900Fasm(disOut, cpuRegs.code, cpuRegs.pc);
//VU0_LOG("%s\n", disOut.c_str());
Int_COP2PrintTable[_Rs_]();
}
void Unknown() {
CPU_LOG("%8.8lx: Unknown opcode called\n", cpuRegs.pc);
}
void MMI_Unknown() { Console::Notice("Unknown MMI opcode called"); }
void COP0_Unknown() { Console::Notice("Unknown COP0 opcode called"); }
void COP1_Unknown() { Console::Notice("Unknown FPU/COP1 opcode called"); }
/*********************************************************
* Arithmetic with immediate operand *
* Format: OP rt, rs, immediate *
*********************************************************/
void ADDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + _Imm_; }// Rt = Rs + Im signed!!!!
void ADDIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + _Imm_; }// Rt = Rs + Im signed !!!
void DADDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + _Imm_; }// Rt = Rs + Im
void DADDIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + _Imm_; }// Rt = Rs + Im
void ANDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] & (u64)_ImmU_; } // Rt = Rs And Im (zero-extended)
void ORI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] | (u64)_ImmU_; } // Rt = Rs Or Im (zero-extended)
void XORI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] ^ (u64)_ImmU_; } // Rt = Rs Xor Im (zero-extended)
void SLTI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] < (s64)(_Imm_); } // Rt = Rs < Im (signed)
void SLTIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] < (u64)(_Imm_); } // Rt = Rs < Im (unsigned)
/*********************************************************
* Register arithmetic *
* Format: OP rd, rs, rt *
*********************************************************/
void ADD() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs + Rt (Exception on Integer Overflow)
void ADDU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs + Rt
void DADD() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + cpuRegs.GPR.r[_Rt_].SD[0]; }
void DADDU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + cpuRegs.GPR.r[_Rt_].SD[0]; }
void SUB() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] - cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs - Rt (Exception on Integer Overflow)
void SUBU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] - cpuRegs.GPR.r[_Rt_].SL[0]; } // Rd = Rs - Rt
void DSUB() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] - cpuRegs.GPR.r[_Rt_].SD[0];}
void DSUBU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] - cpuRegs.GPR.r[_Rt_].SD[0]; }
void AND() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] & cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs And Rt
void OR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs Or Rt
void XOR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] ^ cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs Xor Rt
void NOR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] =~(cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0]); }// Rd = Rs Nor Rt
void SLT() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]; } // Rd = Rs < Rt (signed)
void SLTU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs < Rt (unsigned)
namespace R5900 {
namespace Interpreter {
namespace OpcodeImpl {
/*********************************************************
* Jump to target *
@ -245,145 +130,13 @@ void SLTU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_
*********************************************************/
void J() {
#ifdef _DEBUG
u32 temp = _JumpTarget_;
u32 pc = cpuRegs.pc;
#endif
doBranch(_JumpTarget_);
#ifdef _DEBUG
JumpCheckSym(temp, pc);
#endif
}
void JAL() {
#ifdef _DEBUG
u32 temp = _JumpTarget_;
u32 pc = cpuRegs.pc;
#endif
_SetLink(31); doBranch(_JumpTarget_);
#ifdef _DEBUG
JumpCheckSym(temp, pc);
#endif
}
/*********************************************************
* Register jump *
* Format: OP rs, rd *
*********************************************************/
void JR() {
#ifdef _DEBUG
u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
u32 pc = cpuRegs.pc;
int rs = _Rs_;
#endif
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
#ifdef _DEBUG
JumpCheckSym(temp, pc);
if (rs == 31) JumpCheckSymRet(pc);
#endif
}
void JALR() {
u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
#ifdef _DEBUG
u32 pc = cpuRegs.pc;
#endif
if (_Rd_) { _SetLink(_Rd_); }
doBranch(temp);
#ifdef _DEBUG
JumpCheckSym(temp, pc);
#endif
}
/*********************************************************
* Register mult/div & Register trap logic *
* Format: OP rs, rt *
*********************************************************/
void DIV() {
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0) {
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
}
}
void DIVU() {
if (cpuRegs.GPR.r[_Rt_].UL[0] != 0) {
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0];
}
}
void MULT() { //different in ps2...
s64 res = (s64)cpuRegs.GPR.r[_Rs_].SL[0] * (s64)cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.LO.UD[0] = (s32)(res & 0xffffffff);
cpuRegs.HI.UD[0] = (s32)(res >> 32);
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].UD[0]= cpuRegs.LO.UD[0]; //that is the difference
}
void MULTU() { //different in ps2..
u64 res = (u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0];
cpuRegs.LO.UD[0] = (s32)(res & 0xffffffff);
cpuRegs.HI.UD[0] = (s32)(res >> 32);
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].UD[0]= cpuRegs.LO.UD[0]; //that is the difference
}
/*********************************************************
* Load higher 16 bits of the first word in GPR with imm *
* Format: OP rt, immediate *
*********************************************************/
void LUI() {
if (!_Rt_) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (s32)(cpuRegs.code << 16);
}
/*********************************************************
* Move from HI/LO to GPR *
* Format: OP rd *
*********************************************************/
void MFHI() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.HI.UD[0]; } // Rd = Hi
void MFLO() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[0]; } // Rd = Lo
/*********************************************************
* Move to GPR to HI/LO & Register jump *
* Format: OP rs *
*********************************************************/
void MTHI() { cpuRegs.HI.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0]; } // Hi = Rs
void MTLO() { cpuRegs.LO.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0]; } // Lo = Rs
/*********************************************************
* Shift arithmetic with constant shift *
* Format: OP rd, rt, sa *
*********************************************************/
void SLL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] << _Sa_); } // Rd = Rt << sa
void DSLL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << _Sa_); }
void DSLL32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << (_Sa_+32));}
void SRA() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].SL[0] >> _Sa_); } // Rd = Rt >> sa (arithmetic)
void DSRA() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (u64)(cpuRegs.GPR.r[_Rt_].SD[0] >> _Sa_); }
void DSRA32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (u64)(cpuRegs.GPR.r[_Rt_].SD[0] >> (_Sa_+32));}
void SRL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] >> _Sa_); } // Rd = Rt >> sa (logical)
void DSRL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> _Sa_); }
void DSRL32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> (_Sa_+32));}
/*********************************************************
* Shift arithmetic with variant register shift *
* Format: OP rd, rt, rs *
*********************************************************/
void SLLV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] << (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt << rs
void SRAV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].SL[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt >> rs (arithmetic)
void SRLV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt >> rs (logical)
void DSLLV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
void DSRAV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s64)(cpuRegs.GPR.r[_Rt_].SD[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
void DSRLV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
/*********************************************************
* Register branch logic *
* Format: OP rs, rt, offset *
@ -450,562 +203,20 @@ void BLTZALL() { RepZBranchLinki32Likely(<) } // Branch if Rs < 0 and link
void BGEZALL() { RepZBranchLinki32Likely(>=) } // Branch if Rs >= 0 and link
/*********************************************************
* Load and store for GPR *
* Format: OP rt, offset(base) *
* Register jump *
* Format: OP rs, rd *
*********************************************************/
void LB() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s8)temp;
}
void JR() {
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
}
void LBU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
void JALR() {
u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
if (_Rd_) { _SetLink(_Rd_); }
doBranch(temp);
}
void LH() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s16)temp;
}
}
void LHU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
void LW() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s32)temp;
}
}
void LWU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
void LWL() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (!_Rt_) return;
if (memRead32(addr & ~3, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWL_MASK[shift]) |
(mem << LWL_SHIFT[shift]);
/*
Mem = 1234. Reg = abcd
0 4bcd (mem << 24) | (reg & 0x00ffffff)
1 34cd (mem << 16) | (reg & 0x0000ffff)
2 234d (mem << 8) | (reg & 0x000000ff)
3 1234 (mem ) | (reg & 0x00000000)
*/
}
u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
void LWR() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (!_Rt_) return;
if (memRead32(addr & ~3, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWR_MASK[shift]) |
(mem >> LWR_SHIFT[shift]);
/*
Mem = 1234. Reg = abcd
0 1234 (mem ) | (reg & 0x00000000)
1 a123 (mem >> 8) | (reg & 0xff000000)
2 ab12 (mem >> 16) | (reg & 0xffff0000)
3 abc1 (mem >> 24) | (reg & 0xffffff00)
*/
}
void LD() {
s32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead64(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead64(addr, &dummy);
}
}
u64 LDL_MASK[8] = { 0x00ffffffffffffffLL, 0x0000ffffffffffffLL, 0x000000ffffffffffLL, 0x00000000ffffffffLL,
0x0000000000ffffffLL, 0x000000000000ffffLL, 0x00000000000000ffLL, 0x0000000000000000LL };
u32 LDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void LDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (!_Rt_) return;
if (memRead64(addr & ~7, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDL_MASK[shift]) |
(mem << LDL_SHIFT[shift]);
}
u64 LDR_MASK[8] = { 0x0000000000000000LL, 0xff00000000000000LL, 0xffff000000000000LL, 0xffffff0000000000LL,
0xffffffff00000000LL, 0xffffffffff000000LL, 0xffffffffffff0000LL, 0xffffffffffffff00LL };
u32 LDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void LDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (!_Rt_) return;
if (memRead64(addr & ~7, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDR_MASK[shift]) |
(mem >> LDR_SHIFT[shift]);
}
void LQ() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
addr&=~0xf;
if (_Rt_) {
memRead128(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 val[2];
memRead128(addr, val);
}
}
void SB() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite8(addr, cpuRegs.GPR.r[_Rt_].UC[0]);
}
void SH() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite16(addr, cpuRegs.GPR.r[_Rt_].US[0]);
}
void SW(){
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite32(addr, cpuRegs.GPR.r[_Rt_].UL[0]);
}
u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
void SWL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (memRead32(addr & ~3, &mem) == -1) return;
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) |
( mem & SWL_MASK[shift]) );
/*
Mem = 1234. Reg = abcd
0 123a (reg >> 24) | (mem & 0xffffff00)
1 12ab (reg >> 16) | (mem & 0xffff0000)
2 1abc (reg >> 8) | (mem & 0xff000000)
3 abcd (reg ) | (mem & 0x00000000)
*/
}
u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
void SWR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (memRead32(addr & ~3, &mem) == -1) return;
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] << SWR_SHIFT[shift]) |
( mem & SWR_MASK[shift]) );
/*
Mem = 1234. Reg = abcd
0 abcd (reg ) | (mem & 0x00000000)
1 bcd4 (reg << 8) | (mem & 0x000000ff)
2 cd34 (reg << 16) | (mem & 0x0000ffff)
3 d234 (reg << 24) | (mem & 0x00ffffff)
*/
}
void SD() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite64(addr,&cpuRegs.GPR.r[_Rt_].UD[0]);
}
u64 SDL_MASK[8] = { 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL,
0xffffff0000000000LL, 0xffff000000000000LL, 0xff00000000000000LL, 0x0000000000000000LL };
u32 SDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void SDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
( mem & SDL_MASK[shift]);
memWrite64(addr & ~7, &mem);
}
u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
0x00000000ffffffffLL, 0x000000ffffffffffLL, 0x0000ffffffffffffLL, 0x00ffffffffffffffLL };
u32 SDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void SDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
( mem & SDR_MASK[shift]);
memWrite64(addr & ~7, &mem );
}
void SQ() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
addr&=~0xf;
memWrite128(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
}
/*********************************************************
* Conditional Move *
* Format: OP rd, rs, rt *
*********************************************************/
void MOVZ() {
if (!_Rd_) return;
if (cpuRegs.GPR.r[_Rt_].UD[0] == 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
}
}
void MOVN() {
if (!_Rd_) return;
if (cpuRegs.GPR.r[_Rt_].UD[0] != 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
}
}
/*********************************************************
* Special purpose instructions *
* Format: OP *
*********************************************************/
#include "Sifcmd.h"
/*
int __Deci2Call(int call, u32 *addr);
*/
u32 *deci2addr = NULL;
u32 deci2handler;
char deci2buffer[256];
/*
* int Deci2Call(int, u_int *);
*/
int __Deci2Call(int call, u32 *addr) {
if (call > 0x10) {
return -1;
}
switch (call) {
case 1: // open
deci2addr = (u32*)PSM(addr[1]);
BIOS_LOG("deci2open: %x,%x,%x,%x\n",
addr[3], addr[2], addr[1], addr[0]);
deci2handler = addr[2];
return 1;
case 2: // close
return 1;
case 3: // reqsend
BIOS_LOG("deci2reqsend: %x,%x,%x,%x: deci2addr: %x,%x,%x,buf=%x %x,%x,len=%x,%x\n",
addr[3], addr[2], addr[1], addr[0],
deci2addr[7], deci2addr[6], deci2addr[5], deci2addr[4],
deci2addr[3], deci2addr[2], deci2addr[1], deci2addr[0]);
// cpuRegs.pc = deci2handler;
// SysPrintf("deci2msg: %s", (char*)PSM(deci2addr[4]+0xc));
if (deci2addr == NULL) return 1;
if (deci2addr[1]>0xc){
u8* pdeciaddr = (u8*)dmaGetAddr(deci2addr[4]+0xc);
if( pdeciaddr == NULL ) pdeciaddr = (u8*)PSM(deci2addr[4]+0xc);
else pdeciaddr += (deci2addr[4]+0xc)%16;
memcpy(deci2buffer, pdeciaddr, deci2addr[1]-0xc);
deci2buffer[deci2addr[1]-0xc>=255?255:deci2addr[1]-0xc]='\0';
Console::Write( Color_Cyan, deci2buffer );
}
deci2addr[3] = 0;
return 1;
case 4: // poll
BIOS_LOG("deci2poll: %x,%x,%x,%x\n",
addr[3], addr[2], addr[1], addr[0]);
return 1;
case 5: // exrecv
return 1;
case 6: // exsend
return 1;
case 0x10://kputs
Console::Write( Color_Cyan, "%s", params PSM(*addr));
return 1;
}
return 0;
}
void SYSCALL() {
#ifdef BIOS_LOG
u8 call;
if (cpuRegs.GPR.n.v1.SL[0] < 0)
call = (u8)(-cpuRegs.GPR.n.v1.SL[0]);
else call = cpuRegs.GPR.n.v1.UC[0];
BIOS_LOG("Bios call: %s (%x)\n", bios[call], call);
if (call == 0x7c && cpuRegs.GPR.n.a0.UL[0] == 0x10) {
Console::Write( Color_Cyan, "%s", params PSM(PSMu32(cpuRegs.GPR.n.a1.UL[0])));
} else
//if (call == 0x7c) SysPrintf("Deci2Call: %x\n", cpuRegs.GPR.n.a0.UL[0]);
if (call == 0x7c) __Deci2Call(cpuRegs.GPR.n.a0.UL[0], (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]));
if (call == 0x77) {
struct t_sif_dma_transfer *dmat;
// struct t_sif_cmd_header *hdr;
// struct t_sif_rpc_bind *bind;
// struct t_rpc_server_data *server;
int n_transfer;
u32 addr;
// int sid;
n_transfer = cpuRegs.GPR.n.a1.UL[0] - 1;
if (n_transfer >= 0) {
addr = cpuRegs.GPR.n.a0.UL[0] + n_transfer * sizeof(struct t_sif_dma_transfer);
dmat = (struct t_sif_dma_transfer*)PSM(addr);
BIOS_LOG("bios_%s: n_transfer=%d, size=%x, attr=%x, dest=%x, src=%x\n",
bios[cpuRegs.GPR.n.v1.UC[0]], n_transfer,
dmat->size, dmat->attr,
dmat->dest, dmat->src);
}
//Log=1;
}
#endif
// if (cpuRegs.GPR.n.v1.UD[0] == 0x77) Log=1;
cpuRegs.pc -= 4;
cpuException(0x20, cpuRegs.branch);
}
void BREAK(void) {
cpuRegs.pc -= 4;
cpuException(0x24, cpuRegs.branch);
}
void MFSA( void ) {
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].SD[0] = (s64)cpuRegs.sa;
}
void MTSA( void ) {
cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0];
}
void SYNC( void )
{
}
void PREF( void )
{
}
/*********************************************************
* Register trap *
* Format: OP rs, rt *
*********************************************************/
void TGE() {
if (cpuRegs.GPR.r[_Rs_].SD[0]>= cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGE\n" );
}
void TGEU() {
if (cpuRegs.GPR.r[_Rs_].UD[0]>= cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGEU\n" );
}
void TLT() {
if (cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLT\n" );
}
void TLTU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLTU\n" );
}
void TEQ() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TEQ\n" );
}
void TNE() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TNE\n" );
}
/*********************************************************
* Trap with immediate operand *
* Format: OP rs, rt *
*********************************************************/
void TGEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] >= _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TGEIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] >= _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTI() {
if(cpuRegs.GPR.r[_Rs_].SD[0] < _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TEQI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TNEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
/*********************************************************
* Sa intructions *
* Format: OP rs, rt *
*********************************************************/
void MTSAB() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3;
}
void MTSAH() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4;
}
} // end namespace R5900::Interpreter::OpcodeImpl
} } } // end namespace R5900::Interpreter::OpcodeImpl
////////////////////////////////////////////////////////
@ -1049,23 +260,19 @@ static void intExecuteBlock()
while (!branch2) execI();
}
void intStep()
static void intStep()
{
g_EEFreezeRegs = false;
execI();
}
void intClear(u32 Addr, u32 Size)
static void intClear(u32 Addr, u32 Size)
{
}
void intShutdown() {
static void intShutdown() {
}
}
using namespace Interpreter;
R5900cpu intCpu = {
intAlloc,
intReset,
@ -1075,5 +282,3 @@ R5900cpu intCpu = {
intClear,
intShutdown
};
}

View File

@ -25,6 +25,7 @@
#include "VU.h"
#include "GS.h"
#include "iR5900.h"
#include "VifDma.h"
#include "SamplProf.h"

View File

@ -56,9 +56,6 @@ BIOS
#include "vtlb.h"
#include "ipu/IPU.h"
using namespace Dynarec;
using namespace Dynarec::R5900;
#ifdef ENABLECACHE
#include "Cache.h"
#endif

View File

@ -43,7 +43,6 @@
#include "Paths.h"
using namespace std;
using namespace Dynarec;
using namespace R5900;
PcsxConfig Config;
@ -554,7 +553,7 @@ void ProcessFKeys(int fkey, int shift)
{
SaveState::GetFilename( Text, StatesC );
gzLoadingState joe( Text ); // throws exception on version mismatch
R5900::cpuReset();
cpuReset();
joe.FreezeAll();
}
catch( Exception::StateLoadError_Recoverable& )

View File

@ -567,14 +567,14 @@ void patchFunc_xkickdelay( char * cmd, char * param )
void patchFunc_fastmemory( char * cmd, char * param )
{
// only valid for recompilers
Dynarec::SetFastMemory(1);
SetFastMemory(1);
}
void patchFunc_vunanmode( char * cmd, char * param )
{
// only valid for recompilers
Dynarec::SetVUNanMode(param != NULL ? atoi(param) : 1);
SetVUNanMode(param != NULL ? atoi(param) : 1);
}
void patchFunc_path3hack( char * cmd, char * param )

View File

@ -117,10 +117,8 @@ void resetpatch( void );
int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
namespace Dynarec {
extern void SetFastMemory(int); // iR5900LoadStore.c
extern void SetVUNanMode(int mode);
}
extern void SetFastMemory(int); // iR5900LoadStore.c
extern void SetVUNanMode(int mode);
extern int path3hack;
extern int g_FFXHack;

View File

@ -21,6 +21,8 @@
#include <ctype.h>
#include "PsxCommon.h"
namespace R3000A {
const char *biosA0n[256] = {
// 0x00
"open", "lseek", "read", "write",
@ -287,3 +289,4 @@ void psxBiosInit() {
void psxBiosShutdown() {
}
} // end namespace R3000A

View File

@ -19,17 +19,23 @@
#ifndef __PSXBIOS_H__
#define __PSXBIOS_H__
extern const char *biosA0n[256];
extern const char *biosB0n[256];
extern const char *biosC0n[256];
namespace R3000A
{
extern const char *biosA0n[256];
extern const char *biosB0n[256];
extern const char *biosC0n[256];
void psxBiosInit();
void psxBiosShutdown();
void psxBiosException();
void psxBiosFreeze(int Mode);
void psxBiosInit();
void psxBiosShutdown();
void psxBiosException();
void psxBiosFreeze(int Mode);
extern void (*biosA0[256])();
extern void (*biosB0[256])();
extern void (*biosC0[256])();
extern void (*biosA0[256])();
extern void (*biosB0[256])();
extern void (*biosC0[256])();
extern void bios_write();
extern void bios_printf();
}
#endif /* __PSXBIOS_H__ */

View File

@ -20,6 +20,8 @@
#include "PsxCommon.h"
using namespace R3000A;
// Dma0/1 in Mdec.c
// Dma3 in CdRom.c
// Dma8 in PsxSpd.c

View File

@ -22,7 +22,6 @@
#include "Misc.h"
#include "iR5900.h"
// NOTE: Any modifications to read/write fns should also go into their const counterparts
// found in iPsxHw.cpp.

View File

@ -115,16 +115,13 @@ void psxDmaInterrupt2(int n);
int psxHwFreeze(gzFile f, int Mode);
namespace Dynarec
{
int psxHwConstRead8(u32 x86reg, u32 add, u32 sign);
int psxHwConstRead16(u32 x86reg, u32 add, u32 sign);
int psxHwConstRead32(u32 x86reg, u32 add);
void psxHwConstWrite8(u32 add, int mmreg);
void psxHwConstWrite16(u32 add, int mmreg);
void psxHwConstWrite32(u32 add, int mmreg);
int psxHw4ConstRead8 (u32 x86reg, u32 add, u32 sign);
void psxHw4ConstWrite8(u32 add, int mmreg);
}
int psxHwConstRead8(u32 x86reg, u32 add, u32 sign);
int psxHwConstRead16(u32 x86reg, u32 add, u32 sign);
int psxHwConstRead32(u32 x86reg, u32 add);
void psxHwConstWrite8(u32 add, int mmreg);
void psxHwConstWrite16(u32 add, int mmreg);
void psxHwConstWrite32(u32 add, int mmreg);
int psxHw4ConstRead8 (u32 x86reg, u32 add, u32 sign);
void psxHw4ConstWrite8(u32 add, int mmreg);
#endif /* __PSXHW_H__ */

View File

@ -22,6 +22,8 @@
#include "PsxCommon.h"
#include "Common.h"
using namespace R3000A;
static int branch = 0;
static int branch2 = 0;
static u32 branchPC;
@ -36,9 +38,6 @@ extern void (*psxCP0[32])();
extern void (*psxCP2[64])();
extern void (*psxCP2BSC[32])();
extern void bios_write();
extern void bios_printf();
struct irxlib {
char name[16];
char names[64][64];

View File

@ -96,26 +96,23 @@ void psxMemWrite8 (u32 mem, u8 value);
void psxMemWrite16(u32 mem, u16 value);
void psxMemWrite32(u32 mem, u32 value);
namespace Dynarec
{
// x86reg and mmreg are always x86 regs
void psxRecMemRead8();
int psxRecMemConstRead8(u32 x86reg, u32 mem, u32 sign);
// x86reg and mmreg are always x86 regs
void psxRecMemRead8();
int psxRecMemConstRead8(u32 x86reg, u32 mem, u32 sign);
void psxRecMemRead16();
int psxRecMemConstRead16(u32 x86reg, u32 mem, u32 sign);
void psxRecMemRead16();
int psxRecMemConstRead16(u32 x86reg, u32 mem, u32 sign);
void psxRecMemRead32();
int psxRecMemConstRead32(u32 x86reg, u32 mem);
void psxRecMemRead32();
int psxRecMemConstRead32(u32 x86reg, u32 mem);
void psxRecMemWrite8();
int psxRecMemConstWrite8(u32 mem, int mmreg);
void psxRecMemWrite8();
int psxRecMemConstWrite8(u32 mem, int mmreg);
void psxRecMemWrite16();
int psxRecMemConstWrite16(u32 mem, int mmreg);
void psxRecMemWrite16();
int psxRecMemConstWrite16(u32 mem, int mmreg);
void psxRecMemWrite32();
int psxRecMemConstWrite32(u32 mem, int mmreg);
}
void psxRecMemWrite32();
int psxRecMemConstWrite32(u32 mem, int mmreg);
#endif /* __PSXMEMORY_H__ */

View File

@ -21,6 +21,8 @@
#include "PsxCommon.h"
#include "Misc.h"
using namespace R3000A;
R3000Acpu *psxCpu;
// used for constant propagation
@ -182,7 +184,7 @@ __forceinline void PSX_INT( IopEventId n, s32 ecycle )
// fixme - this doesn't take into account EE/IOP sync (the IOP may be running
// ahead or behind the EE as per the EEsCycles value)
s32 iopDelta = (g_psxNextBranchCycle-psxRegs.cycle)*8;
R5900::cpuSetNextBranchDelta( iopDelta );
cpuSetNextBranchDelta( iopDelta );
}
}
@ -257,12 +259,12 @@ void iopTestIntc()
if( psxHu32(0x1078) == 0 ) return;
if( (psxHu32(0x1070) & psxHu32(0x1074)) == 0 ) return;
if( !R5900::EventTestIsActive )
if( !eeEventTestIsActive )
{
// An iop exception has occured while the EE is running code.
// Inform the EE to branch so the IOP can handle it promptly:
R5900::cpuSetNextBranchDelta( 16 );
cpuSetNextBranchDelta( 16 );
iopBranchAction = true;
//Console::Error( "** IOP Needs an EE EventText, kthx ** %d", params psxCycleEE );
@ -279,4 +281,3 @@ void psxExecuteBios() {
PSX_LOG("*BIOS END*\n");
*/
}

View File

@ -21,21 +21,6 @@
#include <stdio.h>
extern u32 g_psxNextBranchCycle;
struct R3000Acpu {
void (*Allocate)();
void (*Reset)();
void (*Execute)();
s32 (*ExecuteBlock)( s32 eeCycles ); // executes the given number of EE cycles.
void (*Clear)(u32 Addr, u32 Size);
void (*Shutdown)();
};
extern R3000Acpu *psxCpu;
extern R3000Acpu psxInt;
extern R3000Acpu psxRec;
union GPRRegs {
struct {
u32 r0, at, v0, v1, a0, a1, a2, a3,
@ -135,22 +120,7 @@ struct psxRegisters {
extern PCSX2_ALIGNED16_DECL(psxRegisters psxRegs);
#define PSX_IS_CONST1(reg) ((reg)<32 && (g_psxHasConstReg&(1<<(reg))))
#define PSX_IS_CONST2(reg1, reg2) ((g_psxHasConstReg&(1<<(reg1)))&&(g_psxHasConstReg&(1<<(reg2))))
#define PSX_SET_CONST(reg) { \
if( (reg) < 32 ) { \
g_psxHasConstReg |= (1<<(reg)); \
g_psxFlushedConstReg &= ~(1<<(reg)); \
} \
}
#define PSX_DEL_CONST(reg) { \
if( (reg) < 32 ) g_psxHasConstReg &= ~(1<<(reg)); \
}
extern u32 g_psxConstRegs[32];
extern u32 g_psxHasConstReg, g_psxFlushedConstReg;
extern u32 g_psxNextBranchCycle;
extern s32 psxBreak; // used when the IOP execution is broken and control returned to the EE
extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
@ -205,16 +175,32 @@ extern u32 EEoCycle;
#endif
void psxMemReset();
void psxReset();
void psxShutdown();
void psxException(u32 code, u32 step);
void psxBranchTest();
void psxExecuteBios();
extern s32 psxNextCounter;
extern u32 psxNextsCounter;
extern bool iopBranchAction;
extern bool iopEventTestIsActive;
////////////////////////////////////////////////////////////////////
// R3000A Public Interface / API
struct R3000Acpu {
void (*Allocate)();
void (*Reset)();
void (*Execute)();
s32 (*ExecuteBlock)( s32 eeCycles ); // executes the given number of EE cycles.
void (*Clear)(u32 Addr, u32 Size);
void (*Shutdown)();
};
extern R3000Acpu *psxCpu;
extern R3000Acpu psxInt;
extern R3000Acpu psxRec;
void psxReset();
void psxShutdown();
void psxException(u32 code, u32 step);
void psxBranchTest();
void psxExecuteBios();
void psxMemReset();
#endif /* __R3000A_H__ */

View File

@ -19,18 +19,25 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include "Counters.h"
#include "Memory.h"
#include "Hw.h"
#include "DebugTools/Debug.h"
#include "R3000A.h"
#include "VUmicro.h"
#include "COP0.h"
#include "GS.h"
#include "IPU/IPU.h"
#include "Vif.h"
#include "VifDma.h"
#include "SPR.h"
#include "Sif.h"
#include "Paths.h"
namespace R5900
{
using namespace R5900; // for R5900 disasm tools
s32 EEsCycle; // used to sync the IOP to the EE
u32 EEoCycle;
@ -40,9 +47,6 @@ static int inter;
PCSX2_ALIGNED16(cpuRegisters cpuRegs);
PCSX2_ALIGNED16(fpuRegisters fpuRegs);
PCSX2_ALIGNED16(tlbs tlb[48]);
PCSX2_ALIGNED16(GPR_reg64 g_cpuConstRegs[32]) = {0};
u32 g_cpuHasConstReg = 0, g_cpuFlushedConstReg = 0;
R5900cpu *Cpu = NULL;
u32 bExecBIOS = 0; // set if the BIOS has already been executed
@ -50,7 +54,7 @@ u32 bExecBIOS = 0; // set if the BIOS has already been executed
static bool cpuIsInitialized = false;
static uint eeWaitCycles = 1024;
bool EventTestIsActive = false;
bool eeEventTestIsActive = false;
// A run-once procedure for initializing the emulation state.
// Can be done anytime after allocating memory, and before calling Cpu->Execute().
@ -108,7 +112,6 @@ void cpuReset()
vif1Reset();
rcntInit();
psxReset();
}
void cpuShutdown()
@ -438,7 +441,7 @@ u32 g_nextBranchCycle = 0;
// and the recompiler. (moved here to help alleviate redundant code)
__forceinline bool _cpuBranchTest_Shared()
{
EventTestIsActive = true;
eeEventTestIsActive = true;
g_nextBranchCycle = cpuRegs.cycle + eeWaitCycles;
EEsCycle += cpuRegs.cycle - EEoCycle;
@ -552,7 +555,7 @@ __forceinline bool _cpuBranchTest_Shared()
// Apply vsync and other counter nextCycles
cpuSetNextBranch( nextsCounter, nextCounter );
EventTestIsActive = false;
eeEventTestIsActive = false;
// ---- INTC / DMAC Exceptions -----------------
// Raise the INTC and DMAC interrupts here, which usually throw exceptions.
@ -582,7 +585,7 @@ void cpuTestINTCInts()
// only set the next branch delta if the exception won't be handled for
// the current branch...
if( !EventTestIsActive )
if( !eeEventTestIsActive )
cpuSetNextBranchDelta( 4 );
else if(psxCycleEE > 0)
{
@ -605,7 +608,7 @@ __forceinline void cpuTestDMACInts()
// only set the next branch delta if the exception won't be handled for
// the current branch...
if( !EventTestIsActive )
if( !eeEventTestIsActive )
cpuSetNextBranchDelta( 4 );
else if(psxCycleEE > 0)
{
@ -682,5 +685,3 @@ __forceinline void CPU_INT( u32 n, s32 ecycle)
cpuSetNextBranchDelta( cpuRegs.eCycle[n] );
}
} // end namespace R5900

View File

@ -21,27 +21,13 @@
extern bool g_EEFreezeRegs;
namespace R5900
{
// EE Bios function name tables.
extern const char* const bios[256];
struct R5900cpu {
void (*Allocate)(); // throws exceptions on failure.
void (*Reset)();
void (*Step)();
void (*Execute)(); /* executes up to a break */
void (*ExecuteBlock)();
void (*Clear)(u32 Addr, u32 Size);
void (*Shutdown)(); // deallocates memory reserved by Allocate
};
// EE Bios function name tables.
namespace R5900 {
extern const char* const bios[256];
}
extern s32 EEsCycle;
extern u32 EEoCycle;
extern R5900cpu *Cpu;
extern R5900cpu intCpu;
extern R5900cpu recCpu;
extern u32 bExecBIOS;
union GPR_reg { // Declare union type GPR register
@ -139,19 +125,6 @@ union GPR_reg64 {
s8 SC[8];
};
#define GPR_IS_CONST1(reg) ((reg)<32 && (g_cpuHasConstReg&(1<<(reg))))
#define GPR_IS_CONST2(reg1, reg2) ((g_cpuHasConstReg&(1<<(reg1)))&&(g_cpuHasConstReg&(1<<(reg2))))
#define GPR_SET_CONST(reg) { \
if( (reg) < 32 ) { \
g_cpuHasConstReg |= (1<<(reg)); \
g_cpuFlushedConstReg &= ~(1<<(reg)); \
} \
}
#define GPR_DEL_CONST(reg) { \
if( (reg) < 32 ) g_cpuHasConstReg &= ~(1<<(reg)); \
}
union FPRreg {
float f;
u32 UL;
@ -192,7 +165,9 @@ struct tlbs
#define _i8(x) (s8)x
#define _u8(x) (u8)x
/**** R5900 Instruction Macros ****/
////////////////////////////////////////////////////////////////////
// R5900 Instruction Macros
#define _PC_ cpuRegs.pc // The next PC to be executed
#define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register
@ -216,56 +191,66 @@ struct tlbs
#endif
void cpuInit();
void cpuReset(); // can throw Exception::FileNotFound.
void cpuShutdown();
void cpuExecuteBios();
void cpuException(u32 code, u32 bd);
void cpuTlbMissR(u32 addr, u32 bd);
void cpuTlbMissW(u32 addr, u32 bd);
void JumpCheckSym(u32 addr, u32 pc);
void JumpCheckSymRet(u32 addr);
extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs);
extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs);
extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]);
extern u32 g_nextBranchCycle;
extern bool eeEventTestIsActive;
extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2];
bool intEventTest();
void intSetBranch();
// This is a special form of the interpreter's doBranch that is run from various
// parts of the Recs (namely COP0's branch codes and stuff).
void __fastcall intDoBranch(u32 target);
////////////////////////////////////////////////////////////////////
// R5900 Public Interface / API
struct R5900cpu
{
void (*Allocate)(); // throws exceptions on failure.
void (*Reset)();
void (*Step)();
void (*Execute)(); /* executes up to a break */
void (*ExecuteBlock)();
void (*Clear)(u32 Addr, u32 Size);
void (*Shutdown)(); // deallocates memory reserved by Allocate
};
extern R5900cpu *Cpu;
extern R5900cpu intCpu;
extern R5900cpu recCpu;
extern void cpuInit();
extern void cpuReset(); // can throw Exception::FileNotFound.
extern void cpuShutdown();
extern void cpuExecuteBios();
extern void cpuException(u32 code, u32 bd);
extern void cpuTlbMissR(u32 addr, u32 bd);
extern void cpuTlbMissW(u32 addr, u32 bd);
extern void cpuTestHwInts();
extern int cpuSetNextBranch( u32 startCycle, s32 delta );
extern int cpuSetNextBranchDelta( s32 delta );
extern int cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetBranch();
extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:
extern void cpuTestINTCInts();
extern void cpuTestDMACInts();
extern void cpuTestTIMRInts();
//u32 VirtualToPhysicalR(u32 addr);
//u32 VirtualToPhysicalW(u32 addr);
////////////////////////////////////////////////////////////////////
// Exception Codes
namespace Interpreter
{
bool intEventTest();
void intSetBranch();
void intExecuteVU0Block();
void intExecuteVU1Block();
// This is a special form of the interpreter's doBranch that is run from various
// parts of the Recs (namely COP0's branch codes and stuff).
void __fastcall intDoBranch(u32 target);
}
void JumpCheckSym(u32 addr, u32 pc);
void JumpCheckSymRet(u32 addr);
extern int cpuSetNextBranch( u32 startCycle, s32 delta );
extern int cpuSetNextBranchDelta( s32 delta );
extern int cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetBranch();
extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs);
extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs);
extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]);
extern PCSX2_ALIGNED16_DECL(GPR_reg64 g_cpuConstRegs[32]);
extern u32 g_nextBranchCycle;
extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg;
extern bool EventTestIsActive;
extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2];
//exception code
#define EXC_CODE(x) ((x)<<2)
#define EXC_CODE_Int EXC_CODE(0)
@ -290,6 +275,4 @@ extern u32 s_iLastPERFCycle[2];
#define EXC_TLB_STORE 1
#define EXC_TLB_LOAD 0
} // End Namespace R5900
#endif /* __R5900_H__ */

785
pcsx2/R5900OpcodeImpl.cpp Normal file
View File

@ -0,0 +1,785 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2008 Pcsx2 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
*/
#include "PrecompiledHeader.h"
#include "Common.h"
#include "R5900.h"
#include "InterTables.h"
#include <float.h>
namespace R5900
{
const OPCODE& GetCurrentInstruction()
{
const OPCODE* opcode = &R5900::OpcodeTables::tbl_Standard[_Opcode_];
while( opcode->getsubclass != NULL )
opcode = &opcode->getsubclass();
return *opcode;
}
const char * const bios[256]=
{
//0x00
"RFU000_FullReset", "ResetEE", "SetGsCrt", "RFU003",
"Exit", "RFU005", "LoadExecPS2", "ExecPS2",
"RFU008", "RFU009", "AddSbusIntcHandler", "RemoveSbusIntcHandler",
"Interrupt2Iop", "SetVTLBRefillHandler", "SetVCommonHandler", "SetVInterruptHandler",
//0x10
"AddIntcHandler", "RemoveIntcHandler", "AddDmacHandler", "RemoveDmacHandler",
"_EnableIntc", "_DisableIntc", "_EnableDmac", "_DisableDmac",
"_SetAlarm", "_ReleaseAlarm", "_iEnableIntc", "_iDisableIntc",
"_iEnableDmac", "_iDisableDmac", "_iSetAlarm", "_iReleaseAlarm",
//0x20
"CreateThread", "DeleteThread", "StartThread", "ExitThread",
"ExitDeleteThread", "TerminateThread", "iTerminateThread", "DisableDispatchThread",
"EnableDispatchThread", "ChangeThreadPriority", "iChangeThreadPriority", "RotateThreadReadyQueue",
"iRotateThreadReadyQueue", "ReleaseWaitThread", "iReleaseWaitThread", "GetThreadId",
//0x30
"ReferThreadStatus","iReferThreadStatus", "SleepThread", "WakeupThread",
"_iWakeupThread", "CancelWakeupThread", "iCancelWakeupThread", "SuspendThread",
"iSuspendThread", "ResumeThread", "iResumeThread", "JoinThread",
"RFU060", "RFU061", "EndOfHeap", "RFU063",
//0x40
"CreateSema", "DeleteSema", "SignalSema", "iSignalSema",
"WaitSema", "PollSema", "iPollSema", "ReferSemaStatus",
"iReferSemaStatus", "RFU073", "SetOsdConfigParam", "GetOsdConfigParam",
"GetGsHParam", "GetGsVParam", "SetGsHParam", "SetGsVParam",
//0x50
"RFU080_CreateEventFlag", "RFU081_DeleteEventFlag",
"RFU082_SetEventFlag", "RFU083_iSetEventFlag",
"RFU084_ClearEventFlag", "RFU085_iClearEventFlag",
"RFU086_WaitEventFlag", "RFU087_PollEventFlag",
"RFU088_iPollEventFlag", "RFU089_ReferEventFlagStatus",
"RFU090_iReferEventFlagStatus", "RFU091_GetEntryAddress",
"EnableIntcHandler_iEnableIntcHandler",
"DisableIntcHandler_iDisableIntcHandler",
"EnableDmacHandler_iEnableDmacHandler",
"DisableDmacHandler_iDisableDmacHandler",
//0x60
"KSeg0", "EnableCache", "DisableCache", "GetCop0",
"FlushCache", "RFU101", "CpuConfig", "iGetCop0",
"iFlushCache", "RFU105", "iCpuConfig", "sceSifStopDma",
"SetCPUTimerHandler", "SetCPUTimer", "SetOsdConfigParam2", "SetOsdConfigParam2",
//0x70
"GsGetIMR_iGsGetIMR", "GsGetIMR_iGsPutIMR", "SetPgifHandler", "SetVSyncFlag",
"RFU116", "print", "sceSifDmaStat_isceSifDmaStat", "sceSifSetDma_isceSifSetDma",
"sceSifSetDChain_isceSifSetDChain", "sceSifSetReg", "sceSifGetReg", "ExecOSD",
"Deci2Call", "PSMode", "MachineType", "GetMemorySize",
};
namespace Interpreter {
namespace OpcodeImpl {
void COP2()
{
//std::string disOut;
//disR5900Fasm(disOut, cpuRegs.code, cpuRegs.pc);
//VU0_LOG("%s\n", disOut.c_str());
Int_COP2PrintTable[_Rs_]();
}
void Unknown() {
CPU_LOG("%8.8lx: Unknown opcode called\n", cpuRegs.pc);
}
void MMI_Unknown() { Console::Notice("Unknown MMI opcode called"); }
void COP0_Unknown() { Console::Notice("Unknown COP0 opcode called"); }
void COP1_Unknown() { Console::Notice("Unknown FPU/COP1 opcode called"); }
/*********************************************************
* Arithmetic with immediate operand *
* Format: OP rt, rs, immediate *
*********************************************************/
void ADDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + _Imm_; }// Rt = Rs + Im signed!!!!
void ADDIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + _Imm_; }// Rt = Rs + Im signed !!!
void DADDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + _Imm_; }// Rt = Rs + Im
void DADDIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + _Imm_; }// Rt = Rs + Im
void ANDI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] & (u64)_ImmU_; } // Rt = Rs And Im (zero-extended)
void ORI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] | (u64)_ImmU_; } // Rt = Rs Or Im (zero-extended)
void XORI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] ^ (u64)_ImmU_; } // Rt = Rs Xor Im (zero-extended)
void SLTI() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] < (s64)(_Imm_); } // Rt = Rs < Im (signed)
void SLTIU() { if (!_Rt_) return; cpuRegs.GPR.r[_Rt_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] < (u64)(_Imm_); } // Rt = Rs < Im (unsigned)
/*********************************************************
* Register arithmetic *
* Format: OP rd, rs, rt *
*********************************************************/
void ADD() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs + Rt (Exception on Integer Overflow)
void ADDU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] + cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs + Rt
void DADD() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + cpuRegs.GPR.r[_Rt_].SD[0]; }
void DADDU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] + cpuRegs.GPR.r[_Rt_].SD[0]; }
void SUB() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] - cpuRegs.GPR.r[_Rt_].SL[0];} // Rd = Rs - Rt (Exception on Integer Overflow)
void SUBU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SL[0] - cpuRegs.GPR.r[_Rt_].SL[0]; } // Rd = Rs - Rt
void DSUB() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] - cpuRegs.GPR.r[_Rt_].SD[0];}
void DSUBU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] - cpuRegs.GPR.r[_Rt_].SD[0]; }
void AND() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] & cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs And Rt
void OR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs Or Rt
void XOR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] ^ cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs Xor Rt
void NOR() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] =~(cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0]); }// Rd = Rs Nor Rt
void SLT() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]; } // Rd = Rs < Rt (signed)
void SLTU() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]; } // Rd = Rs < Rt (unsigned)
/*********************************************************
* Register mult/div & Register trap logic *
* Format: OP rs, rt *
*********************************************************/
void DIV() {
if (cpuRegs.GPR.r[_Rt_].SL[0] != 0) {
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
}
}
void DIVU() {
if (cpuRegs.GPR.r[_Rt_].UL[0] != 0) {
cpuRegs.LO.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0];
cpuRegs.HI.SD[0] = cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0];
}
}
void MULT() { //different in ps2...
s64 res = (s64)cpuRegs.GPR.r[_Rs_].SL[0] * (s64)cpuRegs.GPR.r[_Rt_].SL[0];
cpuRegs.LO.UD[0] = (s32)(res & 0xffffffff);
cpuRegs.HI.UD[0] = (s32)(res >> 32);
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].UD[0]= cpuRegs.LO.UD[0]; //that is the difference
}
void MULTU() { //different in ps2..
u64 res = (u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0];
cpuRegs.LO.UD[0] = (s32)(res & 0xffffffff);
cpuRegs.HI.UD[0] = (s32)(res >> 32);
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].UD[0]= cpuRegs.LO.UD[0]; //that is the difference
}
/*********************************************************
* Load higher 16 bits of the first word in GPR with imm *
* Format: OP rt, immediate *
*********************************************************/
void LUI() {
if (!_Rt_) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (s32)(cpuRegs.code << 16);
}
/*********************************************************
* Move from HI/LO to GPR *
* Format: OP rd *
*********************************************************/
void MFHI() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.HI.UD[0]; } // Rd = Hi
void MFLO() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[0]; } // Rd = Lo
/*********************************************************
* Move to GPR to HI/LO & Register jump *
* Format: OP rs *
*********************************************************/
void MTHI() { cpuRegs.HI.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0]; } // Hi = Rs
void MTLO() { cpuRegs.LO.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0]; } // Lo = Rs
/*********************************************************
* Shift arithmetic with constant shift *
* Format: OP rd, rt, sa *
*********************************************************/
void SLL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] << _Sa_); } // Rd = Rt << sa
void DSLL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << _Sa_); }
void DSLL32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << (_Sa_+32));}
void SRA() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].SL[0] >> _Sa_); } // Rd = Rt >> sa (arithmetic)
void DSRA() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (u64)(cpuRegs.GPR.r[_Rt_].SD[0] >> _Sa_); }
void DSRA32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (u64)(cpuRegs.GPR.r[_Rt_].SD[0] >> (_Sa_+32));}
void SRL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] >> _Sa_); } // Rd = Rt >> sa (logical)
void DSRL() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> _Sa_); }
void DSRL32(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> (_Sa_+32));}
/*********************************************************
* Shift arithmetic with variant register shift *
* Format: OP rd, rt, rs *
*********************************************************/
void SLLV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] << (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt << rs
void SRAV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].SL[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt >> rs (arithmetic)
void SRLV() { if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s32)(cpuRegs.GPR.r[_Rt_].UL[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x1f));} // Rd = Rt >> rs (logical)
void DSLLV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] << (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
void DSRAV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].SD[0] = (s64)(cpuRegs.GPR.r[_Rt_].SD[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
void DSRLV(){ if (!_Rd_) return; cpuRegs.GPR.r[_Rd_].UD[0] = (u64)(cpuRegs.GPR.r[_Rt_].UD[0] >> (cpuRegs.GPR.r[_Rs_].UL[0] &0x3f));}
/*********************************************************
* Load and store for GPR *
* Format: OP rt, offset(base) *
*********************************************************/
void LB() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s8)temp;
}
}
void LBU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
void LH() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s16)temp;
}
}
void LHU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
void LW() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s32)temp;
}
}
void LWU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
u32 LWL_MASK[4] = { 0xffffff, 0xffff, 0xff, 0 };
u32 LWL_SHIFT[4] = { 24, 16, 8, 0 };
void LWL() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (!_Rt_) return;
if (memRead32(addr & ~3, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWL_MASK[shift]) |
(mem << LWL_SHIFT[shift]);
/*
Mem = 1234. Reg = abcd
0 4bcd (mem << 24) | (reg & 0x00ffffff)
1 34cd (mem << 16) | (reg & 0x0000ffff)
2 234d (mem << 8) | (reg & 0x000000ff)
3 1234 (mem ) | (reg & 0x00000000)
*/
}
u32 LWR_MASK[4] = { 0, 0xff000000, 0xffff0000, 0xffffff00 };
u32 LWR_SHIFT[4] = { 0, 8, 16, 24 };
void LWR() {
s32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (!_Rt_) return;
if (memRead32(addr & ~3, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWR_MASK[shift]) |
(mem >> LWR_SHIFT[shift]);
/*
Mem = 1234. Reg = abcd
0 1234 (mem ) | (reg & 0x00000000)
1 a123 (mem >> 8) | (reg & 0xff000000)
2 ab12 (mem >> 16) | (reg & 0xffff0000)
3 abc1 (mem >> 24) | (reg & 0xffffff00)
*/
}
void LD() {
s32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead64(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead64(addr, &dummy);
}
}
u64 LDL_MASK[8] = { 0x00ffffffffffffffLL, 0x0000ffffffffffffLL, 0x000000ffffffffffLL, 0x00000000ffffffffLL,
0x0000000000ffffffLL, 0x000000000000ffffLL, 0x00000000000000ffLL, 0x0000000000000000LL };
u32 LDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void LDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (!_Rt_) return;
if (memRead64(addr & ~7, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDL_MASK[shift]) |
(mem << LDL_SHIFT[shift]);
}
u64 LDR_MASK[8] = { 0x0000000000000000LL, 0xff00000000000000LL, 0xffff000000000000LL, 0xffffff0000000000LL,
0xffffffff00000000LL, 0xffffffffff000000LL, 0xffffffffffff0000LL, 0xffffffffffffff00LL };
u32 LDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void LDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (!_Rt_) return;
if (memRead64(addr & ~7, &mem) == -1) return;
cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDR_MASK[shift]) |
(mem >> LDR_SHIFT[shift]);
}
void LQ() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
addr&=~0xf;
if (_Rt_) {
memRead128(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 val[2];
memRead128(addr, val);
}
}
void SB() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite8(addr, cpuRegs.GPR.r[_Rt_].UC[0]);
}
void SH() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite16(addr, cpuRegs.GPR.r[_Rt_].US[0]);
}
void SW(){
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite32(addr, cpuRegs.GPR.r[_Rt_].UL[0]);
}
u32 SWL_MASK[4] = { 0xffffff00, 0xffff0000, 0xff000000, 0x00000000 };
u32 SWL_SHIFT[4] = { 24, 16, 8, 0 };
void SWL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (memRead32(addr & ~3, &mem) == -1) return;
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) |
( mem & SWL_MASK[shift]) );
/*
Mem = 1234. Reg = abcd
0 123a (reg >> 24) | (mem & 0xffffff00)
1 12ab (reg >> 16) | (mem & 0xffff0000)
2 1abc (reg >> 8) | (mem & 0xff000000)
3 abcd (reg ) | (mem & 0x00000000)
*/
}
u32 SWR_MASK[4] = { 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
u32 SWR_SHIFT[4] = { 0, 8, 16, 24 };
void SWR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 3;
u32 mem;
if (memRead32(addr & ~3, &mem) == -1) return;
memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] << SWR_SHIFT[shift]) |
( mem & SWR_MASK[shift]) );
/*
Mem = 1234. Reg = abcd
0 abcd (reg ) | (mem & 0x00000000)
1 bcd4 (reg << 8) | (mem & 0x000000ff)
2 cd34 (reg << 16) | (mem & 0x0000ffff)
3 d234 (reg << 24) | (mem & 0x00ffffff)
*/
}
void SD() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite64(addr,&cpuRegs.GPR.r[_Rt_].UD[0]);
}
u64 SDL_MASK[8] = { 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL,
0xffffff0000000000LL, 0xffff000000000000LL, 0xff00000000000000LL, 0x0000000000000000LL };
u32 SDL_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
void SDL() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
( mem & SDL_MASK[shift]);
memWrite64(addr & ~7, &mem);
}
u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
0x00000000ffffffffLL, 0x000000ffffffffffLL, 0x0000ffffffffffffLL, 0x00ffffffffffffffLL };
u32 SDR_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
void SDR() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
u32 shift = addr & 7;
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
( mem & SDR_MASK[shift]);
memWrite64(addr & ~7, &mem );
}
void SQ() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
addr&=~0xf;
memWrite128(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
}
/*********************************************************
* Conditional Move *
* Format: OP rd, rs, rt *
*********************************************************/
void MOVZ() {
if (!_Rd_) return;
if (cpuRegs.GPR.r[_Rt_].UD[0] == 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
}
}
void MOVN() {
if (!_Rd_) return;
if (cpuRegs.GPR.r[_Rt_].UD[0] != 0) {
cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
}
}
/*********************************************************
* Special purpose instructions *
* Format: OP *
*********************************************************/
#include "Sifcmd.h"
/*
int __Deci2Call(int call, u32 *addr);
*/
u32 *deci2addr = NULL;
u32 deci2handler;
char deci2buffer[256];
/*
* int Deci2Call(int, u_int *);
*/
int __Deci2Call(int call, u32 *addr) {
if (call > 0x10) {
return -1;
}
switch (call) {
case 1: // open
deci2addr = (u32*)PSM(addr[1]);
BIOS_LOG("deci2open: %x,%x,%x,%x\n",
addr[3], addr[2], addr[1], addr[0]);
deci2handler = addr[2];
return 1;
case 2: // close
return 1;
case 3: // reqsend
BIOS_LOG("deci2reqsend: %x,%x,%x,%x: deci2addr: %x,%x,%x,buf=%x %x,%x,len=%x,%x\n",
addr[3], addr[2], addr[1], addr[0],
deci2addr[7], deci2addr[6], deci2addr[5], deci2addr[4],
deci2addr[3], deci2addr[2], deci2addr[1], deci2addr[0]);
// cpuRegs.pc = deci2handler;
// SysPrintf("deci2msg: %s", (char*)PSM(deci2addr[4]+0xc));
if (deci2addr == NULL) return 1;
if (deci2addr[1]>0xc){
u8* pdeciaddr = (u8*)dmaGetAddr(deci2addr[4]+0xc);
if( pdeciaddr == NULL ) pdeciaddr = (u8*)PSM(deci2addr[4]+0xc);
else pdeciaddr += (deci2addr[4]+0xc)%16;
memcpy(deci2buffer, pdeciaddr, deci2addr[1]-0xc);
deci2buffer[deci2addr[1]-0xc>=255?255:deci2addr[1]-0xc]='\0';
Console::Write( Color_Cyan, deci2buffer );
}
deci2addr[3] = 0;
return 1;
case 4: // poll
BIOS_LOG("deci2poll: %x,%x,%x,%x\n",
addr[3], addr[2], addr[1], addr[0]);
return 1;
case 5: // exrecv
return 1;
case 6: // exsend
return 1;
case 0x10://kputs
Console::Write( Color_Cyan, "%s", params PSM(*addr));
return 1;
}
return 0;
}
void SYSCALL() {
#ifdef BIOS_LOG
u8 call;
if (cpuRegs.GPR.n.v1.SL[0] < 0)
call = (u8)(-cpuRegs.GPR.n.v1.SL[0]);
else call = cpuRegs.GPR.n.v1.UC[0];
BIOS_LOG("Bios call: %s (%x)\n", bios[call], call);
if (call == 0x7c && cpuRegs.GPR.n.a0.UL[0] == 0x10) {
Console::Write( Color_Cyan, "%s", params PSM(PSMu32(cpuRegs.GPR.n.a1.UL[0])));
} else
//if (call == 0x7c) SysPrintf("Deci2Call: %x\n", cpuRegs.GPR.n.a0.UL[0]);
if (call == 0x7c) __Deci2Call(cpuRegs.GPR.n.a0.UL[0], (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]));
if (call == 0x77) {
struct t_sif_dma_transfer *dmat;
// struct t_sif_cmd_header *hdr;
// struct t_sif_rpc_bind *bind;
// struct t_rpc_server_data *server;
int n_transfer;
u32 addr;
// int sid;
n_transfer = cpuRegs.GPR.n.a1.UL[0] - 1;
if (n_transfer >= 0) {
addr = cpuRegs.GPR.n.a0.UL[0] + n_transfer * sizeof(struct t_sif_dma_transfer);
dmat = (struct t_sif_dma_transfer*)PSM(addr);
BIOS_LOG("bios_%s: n_transfer=%d, size=%x, attr=%x, dest=%x, src=%x\n",
bios[cpuRegs.GPR.n.v1.UC[0]], n_transfer,
dmat->size, dmat->attr,
dmat->dest, dmat->src);
}
//Log=1;
}
#endif
// if (cpuRegs.GPR.n.v1.UD[0] == 0x77) Log=1;
cpuRegs.pc -= 4;
cpuException(0x20, cpuRegs.branch);
}
void BREAK(void) {
cpuRegs.pc -= 4;
cpuException(0x24, cpuRegs.branch);
}
void MFSA( void ) {
if (!_Rd_) return;
cpuRegs.GPR.r[_Rd_].SD[0] = (s64)cpuRegs.sa;
}
void MTSA( void ) {
cpuRegs.sa = (s32)cpuRegs.GPR.r[_Rs_].SD[0];
}
void SYNC( void )
{
}
void PREF( void )
{
}
/*********************************************************
* Register trap *
* Format: OP rs, rt *
*********************************************************/
void TGE() {
if (cpuRegs.GPR.r[_Rs_].SD[0]>= cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGE\n" );
}
void TGEU() {
if (cpuRegs.GPR.r[_Rs_].UD[0]>= cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TGEU\n" );
}
void TLT() {
if (cpuRegs.GPR.r[_Rs_].SD[0] < cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLT\n" );
}
void TLTU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < cpuRegs.GPR.r[_Rt_].UD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TLTU\n" );
}
void TEQ() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TEQ\n" );
}
void TNE() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0]) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: TNE\n" );
}
/*********************************************************
* Trap with immediate operand *
* Format: OP rs, rt *
*********************************************************/
void TGEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] >= _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TGEIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] >= _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTI() {
if(cpuRegs.GPR.r[_Rs_].SD[0] < _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TLTIU() {
if (cpuRegs.GPR.r[_Rs_].UD[0] < _ImmU_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TEQI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] == _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
void TNEI() {
if (cpuRegs.GPR.r[_Rs_].SD[0] != _Imm_) {
cpuException(EXC_CODE_Tr, cpuRegs.branch);
}
//SysPrintf( "TrapInstruction: Immediate\n" );
}
/*********************************************************
* Sa intructions *
* Format: OP rs, rt *
*********************************************************/
void MTSAB() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3;
}
void MTSAH() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4;
}
} } } // end namespace R5900::Interpreter::OpcodeImpl

View File

@ -23,8 +23,6 @@
#include "iR5900.h"
#include "VUmicro.h"
using R5900::Cpu;
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])

View File

@ -267,7 +267,7 @@ __forceinline void SIF0Dma()
// }
// }
R5900::Cpu->Clear(sif0dma->madr, readSize*4);
Cpu->Clear(sif0dma->madr, readSize*4);
cycles += readSize * BIAS; // fixme : BIAS is factored in below
//cycles += readSize;

View File

@ -58,8 +58,6 @@ void statsClose() {
fclose(f);
}
using R5900::cpuRegs;
void statsVSync() {
static u64 accum = 0, accumvu1 = 0;
static u32 frame = 0;

View File

@ -31,7 +31,6 @@
using namespace std;
using namespace Console;
using R5900::cpuRegs;
// disable all session overrides by default...
SessionOverrideFlags g_Session = {false};
@ -228,7 +227,7 @@ void SysAllocateDynarecs()
try
{
// R5900 and R3000a must be rec-enabled together for now so if either fails they both fail.
R5900::recCpu.Allocate();
recCpu.Allocate();
psxRec.Allocate();
}
catch( Exception::BaseException& ex )
@ -240,7 +239,7 @@ void SysAllocateDynarecs()
g_Session.ForceDisableEErec = true;
R5900::recCpu.Shutdown();
recCpu.Shutdown();
psxRec.Shutdown();
}
@ -276,14 +275,14 @@ void SysAllocateDynarecs()
// If both VUrecs failed, then make sure the SuperVU is totally closed out:
if( !CHECK_VU0REC && !CHECK_VU1REC)
Dynarec::SuperVUDestroy( -1 );
SuperVUDestroy( -1 );
}
// This should be called last thing before Pcsx2 exits.
void SysShutdownMem()
{
R5900::cpuShutdown();
cpuShutdown();
vuMicroMemShutdown();
psxMemShutdown();
@ -296,10 +295,10 @@ void SysShutdownMem()
void SysShutdownDynarecs()
{
// Special SuperVU "complete" terminator.
Dynarec::SuperVUDestroy( -1 );
SuperVUDestroy( -1 );
psxRec.Shutdown();
R5900::recCpu.Shutdown();
recCpu.Shutdown();
}
// Resets all PS2 cpu execution states, which does not affect that actual PS2 state/condition.
@ -311,16 +310,16 @@ void SysResetExecutionState()
{
if( CHECK_EEREC )
{
R5900::Cpu = &R5900::recCpu;
Cpu = &recCpu;
psxCpu = &psxRec;
}
else
{
R5900::Cpu = &R5900::intCpu;
Cpu = &intCpu;
psxCpu = &psxInt;
}
R5900::Cpu->Reset();
Cpu->Reset();
psxCpu->Reset();
vuMicroCpuReset();

View File

@ -64,7 +64,7 @@ void vuMicroCpuReset()
// SuperVUreset will do nothing is none of the recs are initialized.
// But it's needed if one or the other is initialized.
Dynarec::SuperVUReset(-1);
SuperVUReset(-1);
}
void vuMicroMemAlloc()

View File

@ -21,9 +21,11 @@
#include "Common.h"
#include "ix86/ix86.h"
#include "Vif.h"
#include "VUmicro.h"
#include "Vif.h"
#include "VifDma.h"
#include <assert.h>
VIFregisters *_vifRegs;

View File

@ -31,8 +31,6 @@
#endif
using namespace std; // for min / max
using R5900::Cpu; // for detecting VU1 dummy / frameskip.
using R5900::cpuRegs;
//#define VIFUNPACKDEBUG //enable unpack debugging output

View File

@ -19,6 +19,7 @@
#include "Common.h"
#include "vtlb.h"
#include "COP0.h"
#include "x86/ix86/ix86.h"
using namespace R5900;
@ -481,9 +482,6 @@ void vtlb_Term()
}
namespace Dynarec
{
//ecx = addr
//edx = ptr
void vtlb_DynGenRead(u32 sz,int freereg)
@ -696,6 +694,4 @@ void vtlb_DynGenWrite(u32 sz,int freereg)
x86SetJ8(cont);
}
}
#endif // PCSX2_VIRTUAL_MEM

View File

@ -59,13 +59,9 @@ void __fastcall vtlb_memWrite32(u32 mem, u32 value);
void __fastcall vtlb_memWrite64(u32 mem, const u64* value);
void __fastcall vtlb_memWrite128(u32 mem, const u64* value);
namespace Dynarec {
void vtlb_DynGenWrite(u32 sz,int freereg);
void vtlb_DynGenRead(u32 sz,int freereg);
}
#endif
#endif

View File

@ -20,6 +20,7 @@
#include "Win32.h"
#include "Common.h"
#include "Counters.h"
#include "VUmicro.h"
#include "PsxCommon.h"
#include "plugins.h"
@ -165,8 +166,8 @@ BOOL CALLBACK CpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
Config.Options = newopts;
}
else if( R5900::Cpu != NULL )
R5900::UpdateVSyncRate();
else if( Cpu != NULL )
UpdateVSyncRate();
SaveConfig();

View File

@ -22,8 +22,6 @@
#include "Common.h"
#include "resource.h"
using namespace R5900;
unsigned long memory_addr;
BOOL mem_inupdate = FALSE;
HWND memoryhWnd,hWnd_memscroll,hWnd_memorydump;

View File

@ -27,13 +27,10 @@
#include "PsxMem.h"
#include "R3000A.h"
using namespace R5900;
#ifdef _MSC_VER
#pragma warning(disable:4996) //ignore the stricmp deprecated warning
#endif
extern void (*IOP_DEBUG_BSC[64])(char *buf);
void RefreshIOPDebugger(void);
extern int ISR3000A;//for disasm
HWND hWnd_debugdisasm, hWnd_debugscroll,hWnd_IOP_debugdisasm, hWnd_IOP_debugscroll;
@ -215,7 +212,7 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
opcode_addr=temp;
MakeIOPDebugOpcode();
IOP_DEBUG_BSC[(psxRegs.code) >> 26](tmp);
R3000A::IOP_DEBUG_BSC[(psxRegs.code) >> 26](tmp);
sprintf(buf, "%08X %08X: %s", temp, psxRegs.code, tmp);
fprintf(fp, "%s\n", buf);
}
@ -653,7 +650,7 @@ void RefreshDebugger(void)
sprintf(syscall_str, "%08X:\tsyscall\t%s", t, R5900::bios[bios_call]);
} else {
std::string str;
disR5900Fasm(str, *mem, t);
R5900::disR5900Fasm(str, *mem, t);
str.copy( syscall_str, 256 );
}
}
@ -675,7 +672,7 @@ void RefreshIOPDebugger(void)
{
// Make the opcode.
u32 mem = PSXMu32(t);
char *str = disR3000Fasm(mem, t);
char *str = R3000A::disR3000Fasm(mem, t);
SendMessage(hWnd_IOP_debugdisasm, LB_ADDSTRING, 0, (LPARAM)str);
}

View File

@ -28,8 +28,6 @@
#include "R3000a.h"
#include "VUmicro.h"
using namespace R5900;
HINSTANCE m_hInst;
HWND m_hWnd;
char text1[256];

View File

@ -26,8 +26,6 @@
#include "PsxCommon.h"
#include "../rdebug/deci2.h"
using namespace R5900;
u32 port=8510;
SOCKET serversocket, remote;
char message[1024]; //message to add to listbox

View File

@ -2268,6 +2268,10 @@
RelativePath="..\..\R5900.h"
>
</File>
<File
RelativePath="..\..\R5900OpcodeImpl.cpp"
>
</File>
<File
RelativePath="..\..\Vif.cpp"
>
@ -2399,6 +2403,10 @@
RelativePath="..\..\x86\iR5900LoadStore.h"
>
</File>
<File
RelativePath="..\..\x86\iR5900Misc.cpp"
>
</File>
<File
RelativePath="..\..\x86\iR5900Move.h"
>

View File

@ -741,8 +741,8 @@ LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
remoteDebugBios=DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_RDEBUGPARAMS), NULL, (DLGPROC)RemoteDebuggerParamsProc);
if (remoteDebugBios)
{
R5900::cpuReset();
R5900::cpuExecuteBios();
cpuReset();
cpuExecuteBios();
DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_RDEBUG), NULL, (DLGPROC)RemoteDebuggerProc);
//CreateMainWindow(SW_SHOWNORMAL);

View File

@ -28,8 +28,6 @@
#include "iR5900.h"
using namespace R5900;
int UseGui = 1;
int nDisableSC = 0; // screensaver
@ -234,7 +232,7 @@ void ExecuteCpu()
{
while( !g_ReturnToGui )
{
Dynarec::R5900::recExecute();
recExecute();
SysUpdate();
}
}

View File

@ -32,8 +32,8 @@
namespace Interp = R5900::Interpreter::OpcodeImpl::COP0;
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
// R5900 branch hepler!
// Recompiles code for a branch test and/or skip, complete with delay slot

View File

@ -19,13 +19,15 @@
#ifndef __iCOP0_H__
#define __iCOP0_H__
#include "COP0.h"
/*********************************************************
* COP0 opcodes *
* *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
namespace COP0
{

View File

@ -32,12 +32,6 @@
extern void _vu0WaitMicro();
// Temporary until I can get the VUs namespaced properly.
using namespace Dynarec::R5900;
namespace Dynarec
{
#define _Ft_ _Rt_
#define _Fs_ _Rd_
#define _Fd_ _Sa_
@ -49,7 +43,7 @@ namespace Dynarec
void recCop2BranchCall( void (*func)() )
{
SetFPUstate();
R5900::recBranchCall( func );
recBranchCall( func );
_freeX86regs();
}
@ -650,22 +644,25 @@ void (*recCOP2SPECIAL2t[128])(s32 info) = {
rec_C2UNK ,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,rec_C2UNK,
};
namespace R5900 { namespace OpcodeImpl {
void recCOP2()
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{
VU0.code = cpuRegs.code;
void recCOP2()
{
VU0.code = cpuRegs.code;
g_pCurInstInfo->vuregs.pipe = 0xff; // to notify eeVURecompileCode that COP2
s32 info = eeVURecompileCode(&VU0, &g_pCurInstInfo->vuregs);
info |= PROCESS_VU_COP2;
info |= PROCESS_VU_UPDATEFLAGS;
g_pCurInstInfo->vuregs.pipe = 0xff; // to notify eeVURecompileCode that COP2
s32 info = eeVURecompileCode(&VU0, &g_pCurInstInfo->vuregs);
info |= PROCESS_VU_COP2;
info |= PROCESS_VU_UPDATEFLAGS;
recCOP2t[_Rs_]( info );
recCOP2t[_Rs_]( info );
_freeX86regs();
}
} }
_freeX86regs();
}
}}}
void recCOP2_SPECIAL(s32 info )
{
@ -683,4 +680,3 @@ void recCOP2_SPECIAL2(s32 info)
recCOP2SPECIAL2t[opc](info);
}
}

View File

@ -19,19 +19,12 @@
#include "PrecompiledHeader.h"
#include "System.h"
#include "R5900.h"
#include "iR5900.h"
#include "Vif.h"
#include "VU.h"
#include "ix86/ix86.h"
#include "iCore.h"
#include "R3000A.h"
// Required because the iCore has tons of code shared between both the EE and IOP.. ugh.
using namespace R5900;
namespace Dynarec
{
u16 g_x86AllocCounter = 0;
u16 g_xmmAllocCounter = 0;
@ -1211,5 +1204,3 @@ void iDumpRegisters(u32 startpc, u32 temp)
__Log("sif: %x %x %x %x %x\n", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260));
#endif
}
}

View File

@ -25,8 +25,6 @@
// Namespace Note : iCore32 contains all of the Register Allocation logic, in addition to a handful
// of utility functions for emitting frequent code.
namespace Dynarec
{
////////////////////////////////////////////////////////////////////////////////
// Shared Register allocation flags (apply to X86, XMM, MMX, etc).
@ -426,6 +424,4 @@ extern void LogicalOpRtoR(x86MMXRegType to, x86MMXRegType from, int op);
extern void LogicalOpMtoR(x86MMXRegType to, u32 from, int op);
#endif
}
#endif

View File

@ -35,11 +35,6 @@ extern PCSX2_ALIGNED16_DECL(u32 g_maxvals[4]);
static u32 fpucw = 0x007f;
static u32 fpucws = 0;
//------------------------------------------------------------------
namespace Dynarec {
namespace R5900
{
void SaveCW(int type) {
if (iCWstate & type) return;
@ -66,9 +61,10 @@ void LoadCW() {
}
//------------------------------------------------------------------
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
namespace COP1
{
namespace COP1 {
//------------------------------------------------------------------
// Helper Macros

View File

@ -19,9 +19,8 @@
#ifndef __IFPU_H__
#define __IFPU_H__
namespace R5900 {
namespace Dynarec {
namespace R5900
{
void SaveCW();
void LoadCW();

View File

@ -34,10 +34,6 @@ extern u8 g_RealGSMem[0x2000];
#define PS2GS_BASE(mem) (g_RealGSMem+(mem&0x13ff))
#endif
namespace Dynarec {
using namespace R5900;
// __thiscall -- Calling Convention Notes.
// ** MSVC passes the pointer to the object as ECX. Other parameters are passed normally
@ -305,5 +301,3 @@ void gsConstRead128(u32 mem, int xmmreg)
GIF_LOG("GS read 128 %8.8lx (%8.8x), at %8.8lx\n", (uptr)PS2GS_BASE(mem), mem);
_eeReadConstMem128( xmmreg, (uptr)PS2GS_BASE(mem));
}
} // end namespace Dynarec

View File

@ -22,8 +22,16 @@
#include "iR5900.h"
#include "VUmicro.h"
#include "PsxMem.h"
// The full suite of hardware APIs:
#include "IPU/IPU.h"
#include "GS.h"
#include "Counters.h"
#include "Vif.h"
#include "Vifdma.h"
#include "SPR.h"
#include "Sif.h"
#ifndef PCSX2_VIRTUAL_MEM
extern u8 *psH; // hw mem
@ -34,9 +42,6 @@ extern int rdram_sdevid;
extern char sio_buffer[1024];
extern int sio_count;
using namespace Dynarec;
using namespace Dynarec::R5900;
int hwConstRead8(u32 x86reg, u32 mem, u32 sign)
{
if( mem >= 0x10000000 && mem < 0x10008000 )

View File

@ -24,10 +24,6 @@
#include "IPU.h"
namespace Dynarec
{
using namespace Dynarec::R5900;
///////////////////////////////////////////////////////////////////////
// IPU Register Reads
@ -205,4 +201,3 @@ void ipuConstWrite64(u32 mem, int mmreg)
break;
}
}
}

View File

@ -31,8 +31,8 @@
namespace Interp = R5900::Interpreter::OpcodeImpl::MMI;
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
namespace MMI
{

View File

@ -24,8 +24,8 @@
#ifndef __IMMI_H__
#define __IMMI_H__
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
// These are instructions contained the MMI "opcode space" but are not

View File

@ -21,17 +21,9 @@
#include "PsxCommon.h"
#include "iR5900.h"
// iPsxHw uses the R5900 flushcall because this module can be called from both
// the EE and the IOP -- R5900's iFlushCall is compatible with iPsxFlushcall, but
// iPsxFlushCall does not flush all the regtypes that iFlushCall does.
using ::Dynarec::R5900::iFlushCall;
extern int g_pbufi;
extern s8 g_pbuf[1024];
namespace Dynarec
{
#define CONSTREAD8_CALL(name) { \
iFlushCall(0); \
CALLFunc((uptr)name); \
@ -1185,5 +1177,3 @@ void psxHw4ConstWrite8(u32 add, int mmreg) {
return;
}
}
} // end namespace Dynarec

View File

@ -25,9 +25,6 @@
extern int g_psxWriteOk;
namespace Dynarec
{
extern u32 g_psxMaxRecMem;
static u32 writectrl;
@ -873,4 +870,3 @@ int psxRecMemConstWrite32(u32 mem, int mmreg)
}
#endif
}

View File

@ -38,16 +38,10 @@
#include "SamplProf.h"
using namespace R3000a;
extern char* disR3000Fasm(u32 code, u32 pc);
extern u32 g_psxNextBranchCycle;
extern void psxBREAK();
extern void zeroEx();
namespace Dynarec
{
u32 g_psxMaxRecMem = 0;
u32 s_psxrecblocks[] = {0};
@ -1594,9 +1588,6 @@ StartRecomp:
assert( s_pCurBlock->pFnptr != 0 );
}
}
using namespace Dynarec;
R3000Acpu psxRec = {
recAlloc,
recReset,
@ -1605,3 +1596,4 @@ R3000Acpu psxRec = {
recClear,
recShutdown
};

View File

@ -18,6 +18,7 @@
#ifndef _R3000A_SUPERREC_
#define _R3000A_SUPERREC_
#include "R3000A.h"
#include "BaseblockEx.h"
// Cycle penalties for particuarly slow instructions.
@ -29,8 +30,6 @@ static const int psxInstCycles_Peephole_Store = 0;
static const int psxInstCycles_Store = 0;
static const int psxInstCycles_Load = 0;
namespace Dynarec
{
// to be consistent with EE
#define PSX_HI XMMGPR_HI
#define PSX_LO XMMGPR_LO
@ -67,12 +66,30 @@ void psxLoadBranchState();
void psxSetBranchReg(u32 reg);
void psxSetBranchImm( u32 imm );
void psxRecompileNextInstruction(int delayslot);
void psxRecClearMem(BASEBLOCK* p);
////////////////////////////////////////////////////////////////////
// IOP Constant Propagation Defines, Vars, and API - From here down!
#define PSX_IS_CONST1(reg) ((reg)<32 && (g_psxHasConstReg&(1<<(reg))))
#define PSX_IS_CONST2(reg1, reg2) ((g_psxHasConstReg&(1<<(reg1)))&&(g_psxHasConstReg&(1<<(reg2))))
#define PSX_SET_CONST(reg) { \
if( (reg) < 32 ) { \
g_psxHasConstReg |= (1<<(reg)); \
g_psxFlushedConstReg &= ~(1<<(reg)); \
} \
}
#define PSX_DEL_CONST(reg) { \
if( (reg) < 32 ) g_psxHasConstReg &= ~(1<<(reg)); \
}
extern u32 g_psxConstRegs[32];
extern u32 g_psxHasConstReg, g_psxFlushedConstReg;
typedef void (*R3000AFNPTR)();
typedef void (*R3000AFNPTR_INFO)(int info);
void psxRecClearMem(BASEBLOCK* p);
//
// non mmx/xmm version, slower
//
@ -120,6 +137,4 @@ void psxRecompileCodeConst2(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode)
// [lo,hi] = rt op rs
void psxRecompileCodeConst3(R3000AFNPTR constcode, R3000AFNPTR_INFO constscode, R3000AFNPTR_INFO consttcode, R3000AFNPTR_INFO noconstcode, int LOHI);
} // end namespace Dynarec
#endif

View File

@ -26,16 +26,7 @@
#include "iCore.h"
#include "iR3000A.h"
extern void psxLWL();
extern void psxLWR();
extern void psxSWL();
extern void psxSWR();
extern int g_psxWriteOk;
namespace Dynarec
{
extern u32 g_psxMaxRecMem;
// R3000A instruction implementation
@ -48,6 +39,11 @@ static void rpsx##f() { \
/* branch = 2; */\
}
extern void psxLWL();
extern void psxLWR();
extern void psxSWL();
extern void psxSWR();
////
void rpsxADDIU_const()
{
@ -2033,5 +2029,3 @@ void rpsxpropCP0(EEINST* prev, EEINST* pinst)
jNO_DEFAULT
}
}
}

View File

@ -44,11 +44,6 @@
#define EE_CONST_PROP // rec2 - enables constant propagation (faster)
namespace Dynarec {
namespace R5900 {
using namespace ::R5900; // This makes sure the Dynarec inherits all R5900 globals.
#define PC_GETBLOCK(x) PC_GETBLOCK_(x, recLUT)
extern u32 pc;
@ -56,8 +51,8 @@ extern int branch;
extern uptr* recLUT;
extern u32 maxrecmem;
extern u32 pc; // recompiler pc
extern int branch; // set for branch
extern u32 pc; // recompiler pc (also used by the SuperVU! .. why? (air))
extern int branch; // set for branch (also used by the SuperVU! .. why? (air))
extern u32 target; // branch target
extern u32 s_nBlockCycles; // cycles of current block recompiling
extern u32 s_saveConstGPRreg;
@ -104,14 +99,41 @@ void LoadBranchState();
void recompileNextInstruction(int delayslot);
void SetBranchReg( u32 reg );
void SetBranchImm( u32 imm );
u32 eeScaleBlockCycles();
void iFlushCall(int flushtype);
void recBranchCall( void (*func)() );
void recCall( void (*func)(), int delreg );
extern void (*recBSC_co[64])();
// these are defined in iFPU.cpp
void LoadCW();
void SaveCW(int type);
u32* _eeGetConstReg(int reg); // gets a memory pointer to the constant reg
extern void recExecute(); // same as recCpu.Execute(), but faster (can be inline'd)
////////////////////////////////////////////////////////////////////
// Constant Propagation - From here to the end of the header!
#define GPR_IS_CONST1(reg) ((reg)<32 && (g_cpuHasConstReg&(1<<(reg))))
#define GPR_IS_CONST2(reg1, reg2) ((g_cpuHasConstReg&(1<<(reg1)))&&(g_cpuHasConstReg&(1<<(reg2))))
#define GPR_SET_CONST(reg) { \
if( (reg) < 32 ) { \
g_cpuHasConstReg |= (1<<(reg)); \
g_cpuFlushedConstReg &= ~(1<<(reg)); \
} \
}
#define GPR_DEL_CONST(reg) { \
if( (reg) < 32 ) g_cpuHasConstReg &= ~(1<<(reg)); \
}
extern void (*recBSC_co[64])();
extern PCSX2_ALIGNED16_DECL(GPR_reg64 g_cpuConstRegs[32]);
extern u32 g_cpuHasConstReg, g_cpuFlushedConstReg;
// gets a memory pointer to the constant reg
u32* _eeGetConstReg(int reg);
// finds where the GPR is stored and moves lower 32 bits to EAX
void _eeMoveGPRtoR(x86IntRegType to, int fromgpr);
@ -121,10 +143,6 @@ void _eeMoveGPRtoRm(x86IntRegType to, int fromgpr);
void _eeFlushAllUnused();
void _eeOnWriteReg(int reg, int signext);
// these are defined in iFPU.cpp
void LoadCW();
void SaveCW(int type);
// totally deletes from const, xmm, and mmx entries
// if flush is 1, also flushes to memory
// if 0, only flushes if not an xmm reg (used when overwriting lower 64bits of reg)
@ -133,12 +151,12 @@ void _deleteEEreg(int reg, int flush);
// allocates memory on the instruction size and returns the pointer
u32* recAllocStackMem(int size, int align);
extern void recExecute(); // same as recCpu.Execute(), but faster (can be inline'd)
void _vuRegsCOP22(VURegs * VU, _VURegsNum *VUregsn);
//////////////////////////////////////
// Templates for code recompilation //
//////////////////////////////////////
typedef void (*R5900FNPTR)();
typedef void (*R5900FNPTR_INFO)(int info);
@ -290,6 +308,4 @@ protected:
};
} }
#endif // __IR5900_H__

View File

@ -24,8 +24,8 @@
* Format: OP rd, rs, rt *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{
void recADD( void );

View File

@ -23,10 +23,10 @@
* Arithmetic with immediate operand *
* Format: OP rt, rs, immediate *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recADDI( void );
void recADDIU( void );
void recDADDI( void );

View File

@ -24,10 +24,10 @@
* Format: OP rd, rt, sa *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recBEQ( void );
void recBEQL( void );
void recBNE( void );

View File

@ -24,10 +24,10 @@
* Format: OP target *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recJ( void );
void recJAL( void );
void recJR( void );

View File

@ -23,10 +23,10 @@
* Format: OP rt, offset(base) *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recLB( void );
void recLBU( void );
void recLH( void );

211
pcsx2/x86/iR5900Misc.cpp Normal file
View File

@ -0,0 +1,211 @@
#include "PrecompiledHeader.h"
#include "Common.h"
#include "iR5900.h"
#include "InterTables.h"
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
////////////////////////////////////////////////////
//static void recCACHE( void ) {
// MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
// MOV32ItoM( (uptr)&cpuRegs.pc, pc );
// iFlushCall(FLUSH_EVERYTHING);
// CALLFunc( (uptr)CACHE );
// //branch = 2;
//
// CMP32ItoM((int)&cpuRegs.pc, pc);
// j8Ptr[0] = JE8(0);
// RET();
// x86SetJ8(j8Ptr[0]);
//}
void recPREF( void )
{
}
void recSYNC( void )
{
}
void recMFSA( void )
{
int mmreg;
if (!_Rd_) return;
mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE);
if( mmreg >= 0 ) {
SSE_MOVLPS_M64_to_XMM(mmreg, (uptr)&cpuRegs.sa);
}
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) {
MOVDMtoMMX(mmreg, (uptr)&cpuRegs.sa);
SetMMXstate();
}
else {
MOV32MtoR(EAX, (u32)&cpuRegs.sa);
_deleteEEreg(_Rd_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[0], EAX);
MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[1], 0);
}
}
void recMTSA( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] );
}
else {
int mmreg;
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
SSE_MOVSS_XMM_to_M32((uptr)&cpuRegs.sa, mmreg);
}
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
MOVDMMXtoM((uptr)&cpuRegs.sa, mmreg);
SetMMXstate();
}
else {
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
}
void recMTSAB( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3);
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0xF);
XOR32ItoR(EAX, _Imm_&0xf);
SHL32ItoR(EAX, 3);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
void recMTSAH( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4);
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0x7);
XOR32ItoR(EAX, _Imm_&0x7);
SHL32ItoR(EAX, 4);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
////////////////////////////////////////////////////
void recNULL( void )
{
Console::Error("EE: Unimplemented op %x", params cpuRegs.code);
}
////////////////////////////////////////////////////
void recUnknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized op %x", params cpuRegs.code);
}
void recMMI_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized MMI op %x", params cpuRegs.code);
}
void recCOP0_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized COP0 op %x", params cpuRegs.code);
}
void recCOP1_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized FPU/COP1 op %x", params cpuRegs.code);
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
void recCACHE()
{
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::CACHE );
branch = 2;
}
void recTGE( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGE );
}
void recTGEU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEU );
}
void recTLT( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLT );
}
void recTLTU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTU );
}
void recTEQ( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TEQ );
}
void recTNE( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TNE );
}
void recTGEI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEI );
}
void recTGEIU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEIU );
}
void recTLTI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTI );
}
void recTLTIU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTIU );
}
void recTEQI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TEQI );
}
void recTNEI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TNEI );
}
} }} // end Namespace R5900::Dynarec::OpcodeImpl

View File

@ -19,10 +19,10 @@
#ifndef __IR5900MOVE_H__
#define __IR5900MOVE_H__
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recLUI( void );
void recMFLO( void );
void recMFHI( void );

View File

@ -24,10 +24,10 @@
* Format: OP rs, rt *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recMULT( void );
void recMULTU( void );
void recDIV( void );

View File

@ -24,10 +24,10 @@
* Format: OP rd, rt, sa *
*********************************************************/
namespace Dynarec {
namespace R5900 {
namespace OpcodeImpl
{
namespace Dynarec {
namespace OpcodeImpl {
void recSLL( void );
void recSRL( void );
void recSRA( void );

View File

@ -24,7 +24,8 @@
#include "VUmicro.h"
#include "iVUzerorec.h"
namespace Dynarec {
namespace VU0micro
{
static void recAlloc()
{
@ -65,7 +66,7 @@ namespace Dynarec {
}
}
using namespace Dynarec;
using namespace VU0micro;
VUmicroCpu recVU0 =
{
@ -76,4 +77,3 @@ VUmicroCpu recVU0 =
, recClear
, recShutdown
};

View File

@ -31,8 +31,8 @@
extern u32 vudump;
#endif
namespace Dynarec {
namespace VU1micro
{
// commented out because I'm not sure it actually works anymore with SuperVU (air)
/*static void iVU1DumpBlock()
{
@ -125,7 +125,7 @@ namespace Dynarec {
}
using namespace Dynarec;
using namespace VU1micro;
VUmicroCpu recVU1 =
{
@ -135,4 +135,4 @@ VUmicroCpu recVU1 =
, recExecuteBlock
, recClear
, recShutdown
};
};

View File

@ -38,10 +38,8 @@
#endif
//------------------------------------------------------------------
namespace Dynarec
{
using ::Dynarec::R5900::pc;
using ::Dynarec::R5900::branch;
// fixme - VUmicro should really use its own static vars for pc and branch.
// Sharing with the EE's copies of pc and branch is not cool! (air)
//------------------------------------------------------------------
// Helper Macros
@ -1272,5 +1270,3 @@ void SetVUNanMode(int mode)
g_VuNanHandling = mode;
if ( mode ) SysPrintf("enabling vunan mode");
}
}

View File

@ -21,16 +21,12 @@
extern u32 vudump;
namespace Dynarec
{
#define VU0_MEMSIZE 0x1000
#define VU1_MEMSIZE 0x4000
void recResetVU0();
void recExecuteVU0Block();
void recClearVU0( u32 Addr, u32 Size );
void _vuRegsCOP22(VURegs * VU, _VURegsNum *VUregsn);
void recVU1Init();
void recVU1Shutdown();
@ -281,6 +277,4 @@ void recVUMI_XTOP(VURegs *vuRegs, int info);
void recVUMI_XITOP(VURegs *vuRegs, int info);
void recVUMI_XTOP( VURegs *VU , int info);
} // end namespace Dynarec
#endif /* __IVUMICRO_H__ */

View File

@ -33,9 +33,6 @@
#include "iVUzerorec.h"
//------------------------------------------------------------------
namespace Dynarec
{
//------------------------------------------------------------------
// Helper Macros
//------------------------------------------------------------------
@ -2010,5 +2007,3 @@ void VU1XGKICK_MTGSTransfer(u32 *pMem, u32 addr)
}
}
//------------------------------------------------------------------
} // end namespace Dynarec

View File

@ -33,9 +33,6 @@
#include "iVUzerorec.h"
//------------------------------------------------------------------
namespace Dynarec
{
//------------------------------------------------------------------
// Helper Macros
//------------------------------------------------------------------
@ -2598,5 +2595,3 @@ void recVUMI_CLIP(VURegs *VU, int info)
_freeX86reg(x86temp1);
_freeX86reg(x86temp2);
}
} // end namespace Dynarec

View File

@ -43,16 +43,10 @@
using namespace std;
using namespace R5900;
using namespace Dynarec::R5900;
// temporary externs
extern void iDumpVU0Registers();
extern void iDumpVU1Registers();
namespace Dynarec
{
// SuperVURec optimization options, uncomment only for debugging purposes
#define SUPERVU_CACHING // vu programs are saved and queried via memcompare (should be no reason to disable this)
#define SUPERVU_WRITEBACKS // don't flush the writebacks after every block
@ -4146,5 +4140,3 @@ void recVUunknown( VURegs* VU, s32 info )
{
SysPrintf("Unknown SVU micromode opcode called\n");
}
}

View File

@ -23,8 +23,6 @@
#include "iVUmicro.h"
namespace Dynarec
{
extern void SuperVUAlloc(int vuindex); // global VU resources aare automatically allocated if necessary.
extern void SuperVUDestroy(int vuindex); // if vuindex is -1, destroys everything
extern void SuperVUReset(int vuindex); // if vuindex is -1, resets everything
@ -49,6 +47,4 @@ u32 SuperVUGetVIAddr(int reg, int read);
// if p == 0, flush q else flush p; if wait is != 0, waits for p/q
void SuperVUFlush(int p, int wait);
}
#endif

View File

@ -37,162 +37,50 @@
#include "iFPU.h"
#include "iCOP0.h"
namespace Dynarec {
namespace R5900
// Use this to call into interpreter functions that require an immediate branchtest
// to be done afterward (anything that throws an exception or enables interrupts, etc).
void recBranchCall( void (*func)() )
{
// Use this to call into interpreter functions that require an immediate branchtest
// to be done afterward (anything that throws an exception or enables interrupts, etc).
void recBranchCall( void (*func)() )
{
// In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle.
// In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle.
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( EAX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, EAX );
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( EAX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, EAX );
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
branch = 2;
}
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
branch = 2;
}
void recCall( void (*func)(), int delreg )
{
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING);
if( delreg > 0 ) _deleteEEreg(delreg, 0);
CALLFunc( (uptr)func );
}
namespace OpcodeImpl
void recCall( void (*func)(), int delreg )
{
////////////////////////////////////////////////////
void recNULL( void )
{
Console::Error("EE: Unimplemented op %x", params cpuRegs.code);
}
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
////////////////////////////////////////////////////
void recUnknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized op %x", params cpuRegs.code);
}
iFlushCall(FLUSH_EVERYTHING);
if( delreg > 0 ) _deleteEEreg(delreg, 0);
CALLFunc( (uptr)func );
}
void recMMI_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized MMI op %x", params cpuRegs.code);
}
using namespace R5900::Dynarec::OpcodeImpl;
void recCOP0_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized COP0 op %x", params cpuRegs.code);
}
void recCOP1_Unknown()
{
// TODO : Unknown ops should throw an exception.
Console::Error("EE: Unrecognized FPU/COP1 op %x", params cpuRegs.code);
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
void recCACHE()
{
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::CACHE );
branch = 2;
}
void recTGE( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGE );
}
void recTGEU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEU );
}
void recTLT( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLT );
}
void recTLTU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTU );
}
void recTEQ( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TEQ );
}
void recTNE( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TNE );
}
void recTGEI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEI );
}
void recTGEIU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TGEIU );
}
void recTLTI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTI );
}
void recTLTIU( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TLTIU );
}
void recTEQI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TEQI );
}
void recTNEI( void )
{
recBranchCall( R5900::Interpreter::OpcodeImpl::TNEI );
}
} // End OpcodeImpl
using namespace OpcodeImpl;
#ifdef PCSX2_VIRTUAL_MEM
// coissued insts
void (*recBSC_co[64] )() = {
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, recNULL, recLDL_co, recLDR_co, recNULL, recNULL, recLQ_co, recSQ_co,
recLB_co, recLH_co, recLWL_co, recLW_co, recLBU_co, recLHU_co, recLWR_co, recLWU_co,
recSB_co, recSH_co, recSWL_co, recSW_co, recSDL_co, recSDR_co, recSWR_co, recNULL,
recNULL, recLWC1_co, recNULL, recNULL, recNULL, recNULL, recLQC2_co, recLD_co,
recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co
};
#endif
#ifdef PCSX2_VIRTUAL_MEM
// coissued insts
void (*recBSC_co[64] )() = {
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, recNULL, recLDL_co, recLDR_co, recNULL, recNULL, recLQ_co, recSQ_co,
recLB_co, recLH_co, recLWL_co, recLW_co, recLBU_co, recLHU_co, recLWR_co, recLWU_co,
recSB_co, recSH_co, recSWL_co, recSW_co, recSDL_co, recSDR_co, recSWR_co, recNULL,
recNULL, recLWC1_co, recNULL, recNULL, recNULL, recNULL, recLQC2_co, recLD_co,
recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co
};
#endif
/*
@ -1172,5 +1060,3 @@ void BSCPropagate::rprop()
break;
}
} // End namespace OpcodeImpl
} } // End namespace Dynarec::R5900

View File

@ -18,22 +18,15 @@
#include "PrecompiledHeader.h"
#include "System.h"
#include "R5900.h"
#include "iR5900.h"
#include "Vif.h"
#include "VU.h"
#include "ix86/ix86.h"
#include "iCore.h"
#include "R3000A.h"
#include "iR5900.h"
#include "iR3000A.h"
#include <vector>
using namespace std;
using namespace ::R5900;
namespace Dynarec
{
u16 x86FpuState, iCWstate;
u16 g_mmxAllocCounter = 0;
@ -282,7 +275,7 @@ int _allocX86reg(int x86reg, int type, int reg, int mode)
_deleteMMXreg(MMX_GPR+reg, 1);
_deleteGPRtoXMMreg(reg, 1);
R5900::_eeMoveGPRtoR(x86reg, reg);
_eeMoveGPRtoR(x86reg, reg);
_deleteMMXreg(MMX_GPR+reg, 0);
_deleteGPRtoXMMreg(reg, 0);
@ -822,7 +815,7 @@ __forceinline void _callPushArg(u32 arg, uptr argmem)
else if( IS_CONSTREG(arg) ) PUSH32I(argmem);
else if( IS_GPRREG(arg) ) {
SUB32ItoR(ESP, 4);
R5900::_eeMoveGPRtoRm(ESP, arg&0xff);
_eeMoveGPRtoRm(ESP, arg&0xff);
}
else if( IS_XMMREG(arg) ) {
SUB32ItoR(ESP, 4);
@ -1117,5 +1110,3 @@ void LogicalOp32ItoM(u32 to, u32 from, int op)
case 3: OR32ItoM(to, from); break;
}
}
} // end namespace Dynarec

View File

@ -43,12 +43,12 @@
#include "SamplProf.h"
using namespace R5900;
// used to disable register freezing during cpuBranchTests (registers
// are safe then since they've been completely flushed)
bool g_EEFreezeRegs = false;
namespace Dynarec { namespace R5900 {
// I can't find where the Linux recRecompile is defined. Is it used anymore?
// If so, namespacing might break it. :/ (air)
#ifdef __LINUX__
@ -68,6 +68,8 @@ u8* dyna_block_discard_recmem=0;
u32 pc; // recompiler pc
int branch; // set for branch
PCSX2_ALIGNED16(GPR_reg64 g_cpuConstRegs[32]) = {0};
u32 g_cpuHasConstReg = 0, g_cpuFlushedConstReg = 0;
u32 s_saveConstGPRreg = 0;
GPR_reg64 s_ConstGPRreg;
@ -651,7 +653,7 @@ static __forceinline bool recEventTest()
#endif
// Perform counters, ints, and IOP updates:
bool retval = ::R5900::_cpuBranchTest_Shared();
bool retval = _cpuBranchTest_Shared();
#ifdef PCSX2_DEVBUILD
assert( !g_globalXMMSaved && !g_globalMMXSaved);
@ -834,6 +836,42 @@ extern void DispatcherReg();
}
#endif
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl {
////////////////////////////////////////////////////
void recSYSCALL( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_NODESTROY);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::SYSCALL );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr + 5 ));
x86SetJ8(j8Ptr[0]);
//branch = 2;
}
////////////////////////////////////////////////////
void recBREAK( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::BREAK );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
RET();
x86SetJ8(j8Ptr[0]);
//branch = 2;
}
} } } // end namespace R5900::Dynarec::OpcodeImpl
////////////////////////////////////////////////////
void recClear( u32 Addr, u32 Size )
{
@ -1101,7 +1139,7 @@ void iFlushCall(int flushtype)
//}
static u32 eeScaleBlockCycles()
u32 eeScaleBlockCycles()
{
// Note: s_nBlockCycles is 3 bit fixed point. Divide by 8 when done!
@ -1204,135 +1242,6 @@ static void iBranchTest(u32 newpc, bool noDispatch)
RET2();
}
namespace OpcodeImpl
{
////////////////////////////////////////////////////
void recSYSCALL( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_NODESTROY);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::SYSCALL );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr + 5 ));
x86SetJ8(j8Ptr[0]);
//branch = 2;
}
////////////////////////////////////////////////////
void recBREAK( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)R5900::Interpreter::OpcodeImpl::BREAK );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
ADD32ItoM((uptr)&cpuRegs.cycle, eeScaleBlockCycles());
RET();
x86SetJ8(j8Ptr[0]);
//branch = 2;
}
////////////////////////////////////////////////////
//static void recCACHE( void ) {
// MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
// MOV32ItoM( (uptr)&cpuRegs.pc, pc );
// iFlushCall(FLUSH_EVERYTHING);
// CALLFunc( (uptr)CACHE );
// //branch = 2;
//
// CMP32ItoM((int)&cpuRegs.pc, pc);
// j8Ptr[0] = JE8(0);
// RET();
// x86SetJ8(j8Ptr[0]);
//}
void recPREF( void )
{
}
void recSYNC( void )
{
}
void recMFSA( void )
{
int mmreg;
if (!_Rd_) return;
mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rd_, MODE_WRITE);
if( mmreg >= 0 ) {
SSE_MOVLPS_M64_to_XMM(mmreg, (uptr)&cpuRegs.sa);
}
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rd_, MODE_WRITE)) >= 0 ) {
MOVDMtoMMX(mmreg, (uptr)&cpuRegs.sa);
SetMMXstate();
}
else {
MOV32MtoR(EAX, (u32)&cpuRegs.sa);
_deleteEEreg(_Rd_, 0);
MOV32RtoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[0], EAX);
MOV32ItoM((uptr)&cpuRegs.GPR.r[_Rd_].UL[1], 0);
}
}
void recMTSA( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, g_cpuConstRegs[_Rs_].UL[0] );
}
else {
int mmreg;
if( (mmreg = _checkXMMreg(XMMTYPE_GPRREG, _Rs_, MODE_READ)) >= 0 ) {
SSE_MOVSS_XMM_to_M32((uptr)&cpuRegs.sa, mmreg);
}
else if( (mmreg = _checkMMXreg(MMX_GPR+_Rs_, MODE_READ)) >= 0 ) {
MOVDMMXtoM((uptr)&cpuRegs.sa, mmreg);
SetMMXstate();
}
else {
MOV32MtoR(EAX, (uptr)&cpuRegs.GPR.r[_Rs_].UL[0]);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
}
void recMTSAB( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0xF) ^ (_Imm_ & 0xF)) << 3);
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0xF);
XOR32ItoR(EAX, _Imm_&0xf);
SHL32ItoR(EAX, 3);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
void recMTSAH( void )
{
if( GPR_IS_CONST1(_Rs_) ) {
MOV32ItoM((uptr)&cpuRegs.sa, ((g_cpuConstRegs[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4);
}
else {
_eeMoveGPRtoR(EAX, _Rs_);
AND32ItoR(EAX, 0x7);
XOR32ItoR(EAX, _Imm_&0x7);
SHL32ItoR(EAX, 4);
MOV32RtoM((uptr)&cpuRegs.sa, EAX);
}
}
} // end Namespace Dynarec::R5900::OpcodeImpl
static void checkcodefn()
{
int pctemp;
@ -2131,21 +2040,12 @@ StartRecomp:
}
}
} } // end namespace Dynarec::R5900
using namespace Dynarec;
using namespace Dynarec::R5900;
namespace R5900
{
R5900cpu recCpu = {
recAlloc,
recReset,
recStep,
recExecute,
recExecuteBlock,
recClear,
recShutdown
};
}
R5900cpu recCpu = {
recAlloc,
recReset,
recStep,
recExecute,
recExecuteBlock,
recClear,
recShutdown
};

View File

@ -24,8 +24,8 @@
#include "iR5900.h"
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

View File

@ -23,8 +23,8 @@
#include "ix86/ix86.h"
#include "iR5900.h"
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

View File

@ -27,8 +27,8 @@
namespace Interp = R5900::Interpreter::OpcodeImpl;
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

View File

@ -25,8 +25,8 @@
#include "ix86/ix86.h"
#include "iR5900.h"
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

View File

@ -23,12 +23,11 @@
#include "ix86/ix86.h"
#include "iR5900.h"
namespace Dynarec {
// Implemented at the bottom of the module:
void SetFastMemory(int bSetFast);
// Implemented at the bottom of the module:
void SetFastMemory(int bSetFast);
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{
@ -4468,9 +4467,9 @@ void recSQC2( void )
#endif
} } // end namespace R5900::OpcodeImpl
} } } // end namespace R5900::Dynarec::OpcodeImpl
using namespace R5900::OpcodeImpl;
using namespace R5900::Dynarec;
#ifdef PCSX2_VIRTUAL_MEM
@ -4499,4 +4498,3 @@ using namespace R5900::OpcodeImpl;
void SetFastMemory(int bSetFast) {}
#endif
}

View File

@ -29,8 +29,8 @@
#pragma warning(disable:4761)
#endif
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

View File

@ -25,8 +25,8 @@
namespace Interp = R5900::Interpreter::OpcodeImpl;
namespace Dynarec {
namespace R5900 {
namespace Dynarec {
namespace OpcodeImpl
{

Some files were not shown because too many files have changed in this diff Show More