Merged drk||Raziel's new VTLB codebase into Playground. It's a faster and more stable replacement for the old TLB build. It lacks the full suite of recompiler optimizations, so don't get too excited (yet). It'll get better though. :)

Important Note: VM and VTLB saves are incompatible!

Also in this revision: Part 1 of a major code cleanup to the EE recompiler.  Adding namespaces and better/safer scoping, and the Standard, Special, and MMI instructions work through a single structured opcode table now.  (other instructions will follow suite when I have the time).

Fixed some sloppiness in the R5900 disassemblers.  Those also need more work yet.

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@459 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2008-12-20 01:46:47 +00:00 committed by Gregory Hainaut
parent 77392f06a7
commit 0123e80888
75 changed files with 5455 additions and 3308 deletions

View File

@ -100,7 +100,7 @@ void TocEntryCopy(struct TocEntry* tocEntry, struct dirTocEntry* internalTocEntr
tocEntry->fileSize = internalTocEntry->fileSize; tocEntry->fileSize = internalTocEntry->fileSize;
tocEntry->fileLBA = internalTocEntry->fileLBA; tocEntry->fileLBA = internalTocEntry->fileLBA;
tocEntry->fileProperties = internalTocEntry->fileProperties; tocEntry->fileProperties = internalTocEntry->fileProperties;
memcpy(tocEntry->date, internalTocEntry->dateStamp, 7); memcpy(tocEntry->date, internalTocEntry->dateStamp, 7); //TODO: Buffer read overrun, dateStamp is 6 bytes
if (CDVolDesc.filesystemType == 2){ if (CDVolDesc.filesystemType == 2){
// This is a Joliet Filesystem, so use Unicode to ISO string copy // This is a Joliet Filesystem, so use Unicode to ISO string copy

View File

@ -24,17 +24,13 @@
//extern BOOL bExecBIOS; //extern BOOL bExecBIOS;
void COP0() {
Int_COP0PrintTable[_Rs_]();
}
void COP0_BC0() { void COP0_BC0() {
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); COP0_LOG("%s\n", disR5900Current.getString());
Int_COP0BC0PrintTable[(cpuRegs.code >> 16) & 0x03](); Int_COP0BC0PrintTable[(cpuRegs.code >> 16) & 0x03]();
} }
void COP0_Func() { void COP0_Func() {
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); COP0_LOG("%s\n", disR5900Current.getString());
Int_COP0C0PrintTable[_Funct_](); Int_COP0C0PrintTable[_Funct_]();
} }
@ -64,7 +60,7 @@ extern u32 s_iLastPERFCycle[2];
void MFC0() { void MFC0() {
if (!_Rt_) return; if (!_Rt_) return;
if (_Rd_ != 9) { COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); } if (_Rd_ != 9) { COP0_LOG("%s\n", disR5900Current.getString()); }
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MFC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) { switch (_Rd_) {
@ -104,7 +100,7 @@ void MFC0() {
} }
void MTC0() { void MTC0() {
COP0_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); COP0_LOG("%s\n", disR5900Current.getString());
//if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) SysPrintf("MTC0 _Rd_ %x = %x\n", _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) { switch (_Rd_) {
case 25: case 25:
@ -186,16 +182,26 @@ void TLBR() {
cpuRegs.CP0.n.EntryLo1 =(tlb[i].EntryLo1&~1)|((tlb[i].EntryHi>>12)&1); cpuRegs.CP0.n.EntryLo1 =(tlb[i].EntryLo1&~1)|((tlb[i].EntryHi>>12)&1);
} }
void ClearTLB(int i) { void UnmapTLB(int i)
{
//SysPrintf("Clear TLB %d: %08x-> [%08x %08x] S=%d G=%d ASID=%d Mask= %03X\n",i,tlb[i].VPN2,tlb[i].PFN0,tlb[i].PFN1,tlb[i].S,tlb[i].G,tlb[i].ASID,tlb[i].Mask);
u32 mask, addr; u32 mask, addr;
u32 saddr, eaddr; u32 saddr, eaddr;
#ifndef PCSX2_VIRTUAL_MEM
if (tlb[i].S)
{
vtlb_VMapUnmap(tlb[i].VPN2,0x4000);
return;
}
#endif
if (tlb[i].EntryLo0 & 0x2) { if (tlb[i].EntryLo0 & 0x2)
{
mask = ((~tlb[i].Mask) << 1) & 0xfffff; mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = tlb[i].VPN2 >> 12; saddr = tlb[i].VPN2 >> 12;
eaddr = saddr + tlb[i].Mask + 1; eaddr = saddr + tlb[i].Mask + 1;
// SysPrintf("Clear TLB: %08x ~ %08x\n",saddr,eaddr-1);
for (addr=saddr; addr<eaddr; addr++) { for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12); memClearPageAddr(addr << 12);
@ -208,7 +214,7 @@ void ClearTLB(int i) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff; mask = ((~tlb[i].Mask) << 1) & 0xfffff;
saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1; saddr = (tlb[i].VPN2 >> 12) + tlb[i].Mask + 1;
eaddr = saddr + tlb[i].Mask + 1; eaddr = saddr + tlb[i].Mask + 1;
// SysPrintf("Clear TLB: %08x ~ %08x\n",saddr,eaddr-1);
for (addr=saddr; addr<eaddr; addr++) { for (addr=saddr; addr<eaddr; addr++) {
if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match if ((addr & mask) == ((tlb[i].VPN2 >> 12) & mask)) { //match
memClearPageAddr(addr << 12); memClearPageAddr(addr << 12);
@ -218,25 +224,20 @@ void ClearTLB(int i) {
} }
} }
void WriteTLB(int i) { void MapTLB(int i)
{
u32 mask, addr; u32 mask, addr;
u32 saddr, eaddr; u32 saddr, eaddr;
tlb[i].PageMask = cpuRegs.CP0.n.PageMask; #ifndef PCSX2_VIRTUAL_MEM
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi; SysPrintf("MAP TLB %d: %08x-> [%08x %08x] S=%d G=%d ASID=%d Mask= %03X\n",i,tlb[i].VPN2,tlb[i].PFN0,tlb[i].PFN1,tlb[i].S,tlb[i].G,tlb[i].ASID,tlb[i].Mask);
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0; if (tlb[i].S)
tlb[i].EntryLo1 = cpuRegs.CP0.n.EntryLo1; {
SysPrintf("OMG SPRAM MAPPING %08X %08X\n",tlb[i].VPN2,tlb[i].Mask);
tlb[i].Mask = (cpuRegs.CP0.n.PageMask >> 13) & 0xfff; vtlb_VMapBuffer(tlb[i].VPN2,psS,0x4000);
tlb[i].nMask = (~tlb[i].Mask) & 0xfff; }
tlb[i].VPN2 = ((cpuRegs.CP0.n.EntryHi >> 13) & (~tlb[i].Mask)) << 13; #endif
tlb[i].ASID = cpuRegs.CP0.n.EntryHi & 0xfff; if (tlb[i].VPN2 == 0x70000000) return; //uh uhh right ...
tlb[i].G = cpuRegs.CP0.n.EntryLo0 & cpuRegs.CP0.n.EntryLo1 & 0x1;
tlb[i].PFN0 = (((cpuRegs.CP0.n.EntryLo0 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN0|= (0x80000000);
tlb[i].PFN1 = (((cpuRegs.CP0.n.EntryLo1 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN1|= (0x80000000);
if (tlb[i].VPN2 == 0x70000000) return;
if (tlb[i].EntryLo0 & 0x2) { if (tlb[i].EntryLo0 & 0x2) {
mask = ((~tlb[i].Mask) << 1) & 0xfffff; mask = ((~tlb[i].Mask) << 1) & 0xfffff;
@ -264,6 +265,25 @@ void WriteTLB(int i) {
} }
} }
} }
void WriteTLB(int i)
{
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
tlb[i].EntryLo1 = cpuRegs.CP0.n.EntryLo1;
tlb[i].Mask = (cpuRegs.CP0.n.PageMask >> 13) & 0xfff;
tlb[i].nMask = (~tlb[i].Mask) & 0xfff;
tlb[i].VPN2 = ((cpuRegs.CP0.n.EntryHi >> 13) & (~tlb[i].Mask)) << 13;
tlb[i].ASID = cpuRegs.CP0.n.EntryHi & 0xfff;
tlb[i].G = cpuRegs.CP0.n.EntryLo0 & cpuRegs.CP0.n.EntryLo1 & 0x1;
tlb[i].PFN0 = (((cpuRegs.CP0.n.EntryLo0 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
tlb[i].PFN1 = (((cpuRegs.CP0.n.EntryLo1 >> 6) & 0xFFFFF) & (~tlb[i].Mask)) << 12;
#ifndef PCSX2_VIRTUAL_MEM
tlb[i].S = cpuRegs.CP0.n.EntryLo0&0x80000000;
#endif
MapTLB(i);
}
void TLBWI() { void TLBWI() {
int j = cpuRegs.CP0.n.Index & 0x3f; int j = cpuRegs.CP0.n.Index & 0x3f;
@ -277,7 +297,7 @@ void TLBWI() {
// if( !bExecBIOS ) // if( !bExecBIOS )
// __Log("TLBWI %d\n", j); // __Log("TLBWI %d\n", j);
ClearTLB(j); UnmapTLB(j);
WriteTLB(j); WriteTLB(j);
} }
@ -293,7 +313,7 @@ void TLBWR() {
// if( !bExecBIOS ) // if( !bExecBIOS )
// __Log("TLBWR %d\n", j); // __Log("TLBWR %d\n", j);
ClearTLB(j); UnmapTLB(j);
WriteTLB(j); WriteTLB(j);
} }

View File

@ -22,6 +22,7 @@
void WriteCP0Status(u32 value); void WriteCP0Status(u32 value);
void UpdateCP0Status(); void UpdateCP0Status();
void WriteTLB(int i); void WriteTLB(int i);
void ClearTLB(int i); void UnmapTLB(int i);
void MapTLB(int i);
#endif /* __COP0_H__ */ #endif /* __COP0_H__ */

View File

@ -25,8 +25,10 @@
_cacheS pCache[64]; _cacheS pCache[64];
#ifndef PCSX2_VIRTUAL_MEM namespace EE { namespace Interpreter { namespace OpcodeImpl
/*_cacheS pCache[64];*/ {
#ifdef PCSX2_CACHE_EMU_MEM
int getFreeCache(u32 mem, int mode, int * way) { int getFreeCache(u32 mem, int mode, int * way) {
u8 * out; u8 * out;
u32 paddr; u32 paddr;
@ -386,4 +388,6 @@ void CACHE() {
void CACHE() { void CACHE() {
} }
#endif #endif
}}} // end namespace EE::Interpeter::OpcodeImpl

View File

@ -755,8 +755,7 @@ int rcntFreeze(gzFile f, int Mode) {
if( Mode == 0 ) if( Mode == 0 )
{ {
int i; #ifdef PCSX2_VIRTUAL_MEM
// Sanity check for loading older savestates: // Sanity check for loading older savestates:
if( counters[4].sCycle == 0 ) if( counters[4].sCycle == 0 )
@ -764,9 +763,10 @@ int rcntFreeze(gzFile f, int Mode) {
if( counters[5].sCycle == 0 ) if( counters[5].sCycle == 0 )
counters[5].sCycle = cpuRegs.cycle; counters[5].sCycle = cpuRegs.cycle;
#endif
// make sure the gate flags are set based on the counter modes... // make sure the gate flags are set based on the counter modes...
for( i=0; i<4; i++ ) for( int i=0; i<4; i++ )
_rcntSetGate( i ); _rcntSetGate( i );
} }

View File

@ -22,19 +22,23 @@
#include <stdio.h> #include <stdio.h>
#include <zlib.h> #include <zlib.h>
#include <string>
#include "Misc.h" #include "Misc.h"
extern FILE *emuLog; extern FILE *emuLog;
char* disR5900F(u32 code, u32 pc); void disR5900F( std::string& output, u32 code, u32 pc);
char* disR5900Fasm(u32 code, u32 pc); void disR5900Fasm( std::string& output, u32 code, u32 pc);
char* disR3000Fasm(u32 code, u32 pc); char* disR3000Fasm(u32 code, u32 pc);
void disR5900AddSym(u32 addr, char *name); void disR5900AddSym(u32 addr, const char *name);
char* disR5900GetSym(u32 addr); const char* disR5900GetSym(u32 addr);
char* disR5900GetUpperSym(u32 addr); const char* disR5900GetUpperSym(u32 addr);
void disR5900FreeSyms(); void disR5900FreeSyms();
void dFindSym( std::string& output, u32 addr );
void strAppend( std::string& output, const char *fmt, ... );
char* disVU0MicroUF(u32 code, u32 pc); char* disVU0MicroUF(u32 code, u32 pc);
char* disVU0MicroLF(u32 code, u32 pc); char* disVU0MicroLF(u32 code, u32 pc);
@ -47,6 +51,19 @@ extern const char *CP2VFnames[];
extern const char *disRNameCP2f[]; extern const char *disRNameCP2f[];
extern const char *disRNameCP2i[]; extern const char *disRNameCP2i[];
// A helper class for getting a quick and efficient string representation of the
// R5900's current instruction. This class is *not* thread safe!
class DisR5900CurrentState
{
protected:
std::string result;
public:
const char* getString();
};
extern DisR5900CurrentState disR5900Current;
//that way is slower but you now not need to compile every time ;P //that way is slower but you now not need to compile every time ;P
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD

View File

@ -19,12 +19,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
using namespace std;
#include "Debug.h" #include "Debug.h"
#include "R5900.h" #include "R5900.h"
#include "VU.h" #include "VU.h"
static char ostr[1024]; //static char ostr[1024];
// Names of registers // Names of registers
const char *disRNameGPR[] = { const char *disRNameGPR[] = {
@ -66,17 +69,19 @@ const char *disRNameCP2i[] = {
const char *CP2VFnames[] = { "x", "y", "z", "w" }; const char *CP2VFnames[] = { "x", "y", "z", "w" };
// Type definition of our functions // Type definition of our functions
#define DisFInterface (u32 code, u32 pc) #define DisFInterface (string& output, u32 code, u32 pc)
#define DisFInterfaceT (u32, u32) #define DisFInterfaceT (string&, u32, u32)
#define DisFInterfaceN (code, pc) #define DisFInterfaceN (output, code, pc)
typedef char* (*TdisR5900F)DisFInterface; typedef void (*TdisR5900F)DisFInterface;
// These macros are used to assemble the disassembler functions // These macros are used to assemble the disassembler functions
#define MakeDisF(fn, b) \ #define MakeDisF(fn, b) \
char* fn DisFInterface { \ void fn DisFInterface { \
char ostr[128]; \
sprintf (ostr, "%8.8x %8.8x:", pc, code); \ sprintf (ostr, "%8.8x %8.8x:", pc, code); \
b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \ output.append( ostr ); \
b; \
} }
#undef _Target_ #undef _Target_
@ -128,38 +133,38 @@ typedef char* (*TdisR5900F)DisFInterface;
#define _Fsf_ ((code >> 21) & 0x03) #define _Fsf_ ((code >> 21) & 0x03)
#define _Ftf_ ((code >> 23) & 0x03) #define _Ftf_ ((code >> 23) & 0x03)
#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i) #define dName(i) strAppend(output, "%-7s,", i);
#define dGPR128(i) sprintf(ostr, "%s %8.8x_%8.8x_%8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i]) #define dGPR128(i) strAppend(output, "%8.8x_%8.8x_%8.8x_%8.8x (%s),", cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dGPR64(i) sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i]) #define dGPR64(i) strAppend(output, "%8.8x_%8.8x (%s),", cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dGPR64U(i) sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], disRNameGPR[i]) #define dGPR64U(i) strAppend(output, "%8.8x_%8.8x (%s),", cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], disRNameGPR[i])
#define dGPR32(i) sprintf(ostr, "%s %8.8x (%s),", ostr, cpuRegs.GPR.r[i].UL[0], disRNameGPR[i]) #define dGPR32(i) strAppend(output, "%8.8x (%s),", cpuRegs.GPR.r[i].UL[0], disRNameGPR[i])
#define dCP032(i) sprintf(ostr, "%s %8.8x (%s),", ostr, cpuRegs.CP0.r[i], disRNameCP0[i]) #define dCP032(i) strAppend(output, "%8.8x (%s),", cpuRegs.CP0.r[i], disRNameCP0[i])
#define dCP132(i) sprintf(ostr, "%s %f (%s),", ostr, fpuRegs.fpr[i].f, disRNameCP1[i]) #define dCP132(i) strAppend(output, "%f (%s),", fpuRegs.fpr[i].f, disRNameCP1[i])
#define dCP1c32(i) sprintf(ostr, "%s %8.8x (%s),", ostr, fpuRegs.fprc[i], disRNameCP1c[i]) #define dCP1c32(i) strAppend(output, "%8.8x (%s),", fpuRegs.fprc[i], disRNameCP1c[i])
#define dCP1acc() sprintf(ostr, "%s %f (ACC),", ostr, fpuRegs.ACC.f) #define dCP1acc() strAppend(output, "%f (ACC),", fpuRegs.ACC.f)
#define dCP2128f(i) sprintf(ostr, "%s w=%f z=%f y=%f x=%f (%s),", ostr, VU0.VF[i].f.w, VU0.VF[i].f.z, VU0.VF[i].f.y, VU0.VF[i].f.x, disRNameCP2f[i]) #define dCP2128f(i) strAppend(output, "w=%f z=%f y=%f x=%f (%s),", VU0.VF[i].f.w, VU0.VF[i].f.z, VU0.VF[i].f.y, VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232x(i) sprintf(ostr, "%s x=%f (%s),", ostr, VU0.VF[i].f.x, disRNameCP2f[i]) #define dCP232x(i) strAppend(output, "x=%f (%s),", VU0.VF[i].f.x, disRNameCP2f[i])
#define dCP232y(i) sprintf(ostr, "%s y=%f (%s),", ostr, VU0.VF[i].f.y, disRNameCP2f[i]) #define dCP232y(i) strAppend(output, "y=%f (%s),", VU0.VF[i].f.y, disRNameCP2f[i])
#define dCP232z(i) sprintf(ostr, "%s z=%f (%s),", ostr, VU0.VF[i].f.z, disRNameCP2f[i]) #define dCP232z(i) strAppend(output, "z=%f (%s),", VU0.VF[i].f.z, disRNameCP2f[i])
#define dCP232w(i) sprintf(ostr, "%s w=%f (%s),", ostr, VU0.VF[i].f.w, disRNameCP2f[i]) #define dCP232w(i) strAppend(output, "w=%f (%s),", VU0.VF[i].f.w, disRNameCP2f[i])
#define dCP2ACCf() sprintf(ostr, "%s w=%f z=%f y=%f x=%f (ACC),", ostr, VU0.ACC.f.w, VU0.ACC.f.z, VU0.ACC.f.y, VU0.ACC.f.x) #define dCP2ACCf() strAppend(output, "w=%f z=%f y=%f x=%f (ACC),", VU0.ACC.f.w, VU0.ACC.f.z, VU0.ACC.f.y, VU0.ACC.f.x)
#define dCP232i(i) sprintf(ostr, "%s %8.8x (%s),", ostr, VU0.VI[i].UL, disRNameCP2i[i]) #define dCP232i(i) strAppend(output, "%8.8x (%s),", VU0.VI[i].UL, disRNameCP2i[i])
#define dCP232iF(i) sprintf(ostr, "%s %f (%s),", ostr, VU0.VI[i].F, disRNameCP2i[i]) #define dCP232iF(i) strAppend(output, "%f (%s),", VU0.VI[i].F, disRNameCP2i[i])
#define dCP232f(i, j) sprintf(ostr, "%s Q %s=%f (%s),", ostr, CP2VFnames[j], VU0.VF[i].F[j], disRNameCP2f[i]) #define dCP232f(i, j) strAppend(output, "Q %s=%f (%s),", CP2VFnames[j], VU0.VF[i].F[j], disRNameCP2f[i])
#define dHI64() sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.HI.UL[1], cpuRegs.HI.UL[0], "hi") #define dHI64() strAppend(output, "%8.8x_%8.8x (%s),", cpuRegs.HI.UL[1], cpuRegs.HI.UL[0], "hi")
#define dLO64() sprintf(ostr, "%s %8.8x_%8.8x (%s),", ostr, cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], "lo") #define dLO64() strAppend(output, "%8.8x_%8.8x (%s),", cpuRegs.LO.UL[1], cpuRegs.LO.UL[0], "lo")
#define dImm() sprintf(ostr, "%s %4.4x (%d),", ostr, _Im_, _Im_) #define dImm() strAppend(output, "%4.4x (%d),", _Im_, _Im_)
#define dTarget() sprintf(ostr, "%s %8.8x,", ostr, _Target_) #define dTarget() strAppend(output, "%8.8x,", _Target_)
#define dSa() sprintf(ostr, "%s %2.2x (%d),", ostr, _Sa_, _Sa_) #define dSa() strAppend(output, "%2.2x (%d),", _Sa_, _Sa_)
#define dSa32() sprintf(ostr, "%s %2.2x (%d),", ostr, _Sa_+32, _Sa_+32) #define dSa32() strAppend(output, "%2.2x (%d),", _Sa_+32, _Sa_+32)
#define dOfB() sprintf(ostr, "%s %4.4x (%8.8x (%s)),", ostr, _Im_, cpuRegs.GPR.r[_Rs_].UL[0], disRNameGPR[_Rs_]) #define dOfB() strAppend(output, "%4.4x (%8.8x (%s)),", _Im_, cpuRegs.GPR.r[_Rs_].UL[0], disRNameGPR[_Rs_])
#define dOffset() sprintf(ostr, "%s %8.8x,", ostr, _Branch_) #define dOffset() strAppend(output, "%8.8x,", _Branch_)
#define dCode() sprintf(ostr, "%s %8.8x,", ostr, (code >> 6) & 0xffffff) #define dCode() strAppend(output, "%8.8x,", (code >> 6) & 0xffffff)
#define dSaR() sprintf(ostr, "%s %8.8x,", ostr, cpuRegs.sa) #define dSaR() strAppend(output, "%8.8x,", cpuRegs.sa)
struct sSymbol { struct sSymbol {
u32 addr; u32 addr;
@ -167,10 +172,20 @@ struct sSymbol {
}; };
static sSymbol *dSyms = NULL; static sSymbol *dSyms = NULL;
static int nSymAlloc = 0;
static int nSyms = 0; static int nSyms = 0;
void disR5900AddSym(u32 addr, char *name) { void disR5900AddSym(u32 addr, const char *name) {
dSyms = (sSymbol*)realloc(dSyms, sizeof(sSymbol) * (nSyms+1));
assert( strlen(name) < 32 );
if( nSyms+1 >= nSymAlloc )
{
// Realloc by threshold block sizes.
nSymAlloc += 64 + (nSyms / 4);
dSyms = (sSymbol*)realloc(dSyms, sizeof(sSymbol) * (nSymAlloc));
}
if (dSyms == NULL) return; if (dSyms == NULL) return;
dSyms[nSyms].addr = addr; dSyms[nSyms].addr = addr;
strncpy(dSyms[nSyms].name, name, 32); strncpy(dSyms[nSyms].name, name, 32);
@ -179,10 +194,11 @@ void disR5900AddSym(u32 addr, char *name) {
void disR5900FreeSyms() { void disR5900FreeSyms() {
if (dSyms != NULL) { free(dSyms); dSyms = NULL; } if (dSyms != NULL) { free(dSyms); dSyms = NULL; }
nSymAlloc = 0;
nSyms = 0; nSyms = 0;
} }
char *disR5900GetSym(u32 addr) { const char *disR5900GetSym(u32 addr) {
int i; int i;
if (dSyms == NULL) return NULL; if (dSyms == NULL) return NULL;
@ -192,7 +208,7 @@ char *disR5900GetSym(u32 addr) {
return NULL; return NULL;
} }
char *disR5900GetUpperSym(u32 addr) { const char *disR5900GetUpperSym(u32 addr) {
u32 laddr; u32 laddr;
int i, j=-1; int i, j=-1;
@ -207,11 +223,15 @@ char *disR5900GetUpperSym(u32 addr) {
return dSyms[j].name; return dSyms[j].name;
} }
#define dFindSym(i) { \ void dFindSym( string& output, u32 addr )
char *str = disR5900GetSym(i); \ {
if (str != NULL) sprintf(ostr, "%s %s", ostr, str); \ const char* label = disR5900GetSym( addr );
if( label != NULL )
output.append( label );
} }
#define dAppendSym(addr) dFindSym( output, addr )
/********************************************************* /*********************************************************
* Arithmetic with immediate operand * * Arithmetic with immediate operand *
* Format: OP rt, rs, immediate * * Format: OP rt, rs, immediate *
@ -249,15 +269,15 @@ MakeDisF(disSLTU, dName("SLTU"); dGPR64(_Rd_); dGPR64(_Rs_); dGPR64(_Rt_);)
* Jump to target * * Jump to target *
* Format: OP target * * Format: OP target *
*********************************************************/ *********************************************************/
MakeDisF(disJ, dName("J"); dTarget(); dFindSym(_Target_);) MakeDisF(disJ, dName("J"); dTarget(); dAppendSym(_Target_);)
MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR32(31); dFindSym(_Target_);) MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR32(31); dAppendSym(_Target_);)
/********************************************************* /*********************************************************
* Register jump * * Register jump *
* Format: OP rs, rd * * Format: OP rs, rd *
*********************************************************/ *********************************************************/
MakeDisF(disJR, dName("JR"); dGPR32(_Rs_); dFindSym(cpuRegs.GPR.r[_Rs_].UL[0]);) MakeDisF(disJR, dName("JR"); dGPR32(_Rs_); dAppendSym(cpuRegs.GPR.r[_Rs_].UL[0]);)
MakeDisF(disJALR, dName("JALR"); dGPR32(_Rs_); dGPR32(_Rd_); dFindSym(cpuRegs.GPR.r[_Rs_].UL[0]);) MakeDisF(disJALR, dName("JALR"); dGPR32(_Rs_); dGPR32(_Rd_); dAppendSym(cpuRegs.GPR.r[_Rs_].UL[0]);)
/********************************************************* /*********************************************************
* Register mult/div & Register trap logic * * Register mult/div & Register trap logic *
@ -770,10 +790,10 @@ MakeDisF(disTEQI, dName("TEQI"); dGPR64(_Rs_); dImm();)
MakeDisF(disTNEI, dName("TNEI"); dGPR64(_Rs_); dImm();) MakeDisF(disTNEI, dName("TNEI"); dGPR64(_Rs_); dImm();)
/********************************************************* /*********************************************************
* Unknow instruction (would generate an exception) * * Unknown instruction (would generate an exception) *
* Format: ? * * Format: ? *
*********************************************************/ *********************************************************/
MakeDisF(disNULL, dName("*** Bad OP ***");) static MakeDisF(disNULL, dName("*** Bad OP ***");)
TdisR5900F disR5900_MMI0[] = { // Subset of disMMI0 TdisR5900F disR5900_MMI0[] = { // Subset of disMMI0
disPADDW, disPSUBW, disPCGTW, disPMAXW, disPADDW, disPSUBW, disPCGTW, disPMAXW,
@ -991,3 +1011,12 @@ TdisR5900F disR5900[] = {
MakeDisF(disR5900F, disR5900[code >> 26] DisFInterfaceN) MakeDisF(disR5900F, disR5900[code >> 26] DisFInterfaceN)
// returns a string representation of the cpuRegs current instruction.
// The return value of this method is *not* thread safe!
const char* DisR5900CurrentState::getString()
{
disR5900F( result, cpuRegs.code, cpuRegs.pc );
return result.c_str();
}
DisR5900CurrentState disR5900Current;

File diff suppressed because it is too large Load Diff

View File

@ -69,10 +69,11 @@ typedef char* (*TdisR5900F)DisFInterface;
/********************************************************* /*********************************************************
* Unknow instruction (would generate an exception) * * Unknown instruction (would generate an exception) *
* Format: ? * * Format: ? *
*********************************************************/ *********************************************************/
extern char* disNULL DisFInterface; //extern char* disNULL DisFInterface;
static MakeDisF(disNULL, dName("*** Bad OP ***");)
#include "DisVUmicro.h" #include "DisVUmicro.h"
#include "DisVUops.h" #include "DisVUops.h"

View File

@ -113,7 +113,8 @@ typedef char* (*TdisR5900F)DisFInterface;
* Unknown instruction (would generate an exception) * * Unknown instruction (would generate an exception) *
* Format: ? * * Format: ? *
*********************************************************/ *********************************************************/
extern char* disNULL DisFInterface; //extern char* disNULL DisFInterface;
static MakeDisF(disNULL, dName("*** Bad OP ***");)
#include "DisVUmicro.h" #include "DisVUmicro.h"
#include "DisVUops.h" #include "DisVUops.h"

View File

@ -144,30 +144,6 @@
intDoBranch( _BranchTarget_ ); \ intDoBranch( _BranchTarget_ ); \
} else cpuRegs.pc += 4; } else cpuRegs.pc += 4;
//****************************************************************
// Used to manage FPU Opcodes
//****************************************************************
void COP1() {
FPU_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
Int_COP1PrintTable[_Rs_]();
}
void COP1_BC1() {
Int_COP1BC1PrintTable[_Rt_]();
}
void COP1_S() {
Int_COP1SPrintTable[_Funct_]();
}
void COP1_W() {
Int_COP1WPrintTable[_Funct_]();
}
void COP1_Unknown() {
FPU_LOG("Unknown FPU opcode called\n");
}
//**************************************************************** //****************************************************************
// FPU Opcodes // FPU Opcodes
@ -267,13 +243,6 @@ void DIV_S() {
checkUnderflow( _FdValUl_, 0, 1 ); checkUnderflow( _FdValUl_, 0, 1 );
} }
void LWC1() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff);
if (addr & 0x00000003) { SysPrintf( "FPU (LWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memRead32(addr, &fpuRegs.fpr[_Rt_].UL);
}
/* The Instruction Set manual has an overly complicated way of /* The Instruction Set manual has an overly complicated way of
determining the flags that are set. Hopefully this shorter determining the flags that are set. Hopefully this shorter
method provides a similar outcome and is faster. (cottonvibes) method provides a similar outcome and is faster. (cottonvibes)
@ -386,9 +355,19 @@ void SUBA_S() {
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 ); checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 );
} }
void SWC1() { namespace EE { namespace Interpreter{ namespace OpcodeImpl
u32 addr; {
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff); void LWC1() {
if (addr & 0x00000003) { SysPrintf( "FPU (SWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception? u32 addr;
memWrite32(addr, fpuRegs.fpr[_Rt_].UL); addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff);
} if (addr & 0x00000003) { SysPrintf( "FPU (LWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memRead32(addr, &fpuRegs.fpr[_Rt_].UL);
}
void SWC1() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff);
if (addr & 0x00000003) { SysPrintf( "FPU (SWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memWrite32(addr, fpuRegs.fpr[_Rt_].UL);
}
}}}

View File

@ -90,7 +90,7 @@ extern HANDLE g_hGsEvent;
extern pthread_cond_t g_condGsEvent; extern pthread_cond_t g_condGsEvent;
#endif #endif
void WriteFIFO(u32 mem, u64 *value) { void WriteFIFO(u32 mem, const u64 *value) {
int ret; int ret;
if ((mem >= 0x10004000) && (mem < 0x10005000)) { if ((mem >= 0x10004000) && (mem < 0x10005000)) {

View File

@ -287,7 +287,8 @@ u32 CSRw;
extern uptr pDsp; extern uptr pDsp;
typedef u8* PU8; typedef u8* PU8;
PCSX2_ALIGNED16(u8 g_MTGSMem[0x2000]); // mtgs has to have its own memory PCSX2_ALIGNED( 4096, u8 GS_RINGBUFF_STOREAGE[GS_RINGBUFFERSIZE] );
PCSX2_ALIGNED16( u8 g_MTGSMem[0x2000] ); // mtgs has to have its own memory
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
#define gif ((DMACh*)&PS2MEM_HW[0xA000]) #define gif ((DMACh*)&PS2MEM_HW[0xA000])
@ -412,7 +413,7 @@ void gsInit()
if( CHECK_MULTIGS ) { if( CHECK_MULTIGS ) {
#ifdef _WIN32 #ifdef _WIN32
g_pGSRingPos = (u8*)VirtualAlloc(GS_RINGBUFFERBASE, GS_RINGBUFFERSIZE, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); g_pGSRingPos = GS_RINGBUFFERBASE;//(u8*)VirtualAlloc(GS_RINGBUFFERBASE, GS_RINGBUFFERSIZE, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
#else #else
// setup linux vm // setup linux vm
g_pGSRingPos = (u8*)SysMmap((uptr)GS_RINGBUFFERBASE, GS_RINGBUFFERSIZE); g_pGSRingPos = (u8*)SysMmap((uptr)GS_RINGBUFFERBASE, GS_RINGBUFFERSIZE);
@ -602,8 +603,63 @@ void gsShutdown()
GSclose(); GSclose();
} }
#ifdef PCSX2_GSRING_TX_STATS
u32 ringtx_s=0;
u32 ringtx_s_ulg=0;
u32 ringtx_s_min=0xFFFFFFFF;
u32 ringtx_s_max=0;
u32 ringtx_c=0;
u32 ringtx_inf[32][32];
u32 ringtx_inf_s[32];
#include <intrin.h>
#endif
u32 GSRingBufCopySz;
u8* GSRingBufCopy( u32 size, u32 type ) u8* GSRingBufCopy( u32 size, u32 type )
{ {
#ifdef PCSX2_GSRING_TX_STATS
ringtx_s+=size;
ringtx_s_ulg+=size&0x7F;
ringtx_s_min=min(ringtx_s_min,size);
ringtx_s_max=max(ringtx_s_max,size);
ringtx_c++;
unsigned long tx_sz;
if (_BitScanReverse(&tx_sz,size))
{
unsigned long tx_algn;
_BitScanForward(&tx_algn,size);
ringtx_inf[tx_sz][tx_algn]++;
ringtx_inf_s[tx_sz]+=size;
}
if (ringtx_s>=128*1024*1024)
{
SysPrintf("GSRingBufCopy:128MB in %d tx -> b/tx: AVG = %.2f , max = %d, min = %d\n",ringtx_c,ringtx_s/(float)ringtx_c,ringtx_s_max,ringtx_s_min);
for (int i=0;i<32;i++)
{
u32 total_bucket=0;
u32 bucket_subitems=0;
for (int j=0;j<32;j++)
{
if (ringtx_inf[i][j])
{
total_bucket+=ringtx_inf[i][j];
bucket_subitems++;
SysPrintf("GSRingBufCopy :tx [%d,%d] algn %d : count= %d [%.2f%%]\n",1<<i,(1<<(i+1))-16,1<<j,ringtx_inf[i][j],ringtx_inf[i][j]/(float)ringtx_c*100);
ringtx_inf[i][j]=0;
}
}
if (total_bucket)
SysPrintf("GSRingBufCopy :tx [%d,%d] total : count= %d [%.2f%%] [%.2f%%]\n",1<<i,(1<<(i+1))-16,total_bucket,total_bucket/(float)ringtx_c*100,ringtx_inf_s[i]/(float)ringtx_s*100);
ringtx_inf_s[i]=0;
}
SysPrintf("GSRingBufCopy :tx ulg count =%d [%.2f%%]\n",ringtx_s_ulg,ringtx_s_ulg/(float)ringtx_s*100);
ringtx_s_ulg=0;
ringtx_c=0;
ringtx_s=0;
ringtx_s_min=0xFFFFFFFF;
ringtx_s_max=0;
}
#endif
// Note on volatiles: g_pGSWritePos is not modified by the GS thread, // Note on volatiles: g_pGSWritePos is not modified by the GS thread,
// so there's no need to use volatile reads here. We still have to use // so there's no need to use volatile reads here. We still have to use
// interlocked exchanges when we modify it, however, since the GS thread // interlocked exchanges when we modify it, however, since the GS thread
@ -711,6 +767,18 @@ u8* GSRingBufCopy( u32 size, u32 type )
#endif #endif
*(u32*)writepos = type | (((size-16)>>4)<<16); *(u32*)writepos = type | (((size-16)>>4)<<16);
#ifdef PCSX2_GSRING_SAMPLING_STATS
if (GSRingBufCopySz)
return writepos+16;
__asm
{
mov GSRingBufCopySz,offset __GSRingBufCopyEnd;
sub GSRingBufCopySz,offset GSRingBufCopy;
__GSRingBufCopyEnd:
}
ProfilerRegisterSource("pcsx2:GSRingBufCopy",&GSRingBufCopy,GSRingBufCopySz);
#endif
return writepos+16; return writepos+16;
} }
@ -1285,9 +1353,9 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
{ {
pendmem = (pendmem&~0xfff)-16; pendmem = (pendmem&~0xfff)-16;
} }
memcpy_fast(pgsmem, pMem, pendmem-(u32)gif->madr+16); memcpy_raz_(pgsmem, pMem, pendmem-(u32)gif->madr+16);
} }
else memcpy_fast(pgsmem, pMem, sizetoread); else memcpy_raz_(pgsmem, pMem, sizetoread);
GSgifTransferDummy(2, pMem, qwc); GSgifTransferDummy(2, pMem, qwc);
GSRINGBUF_DONECOPY(pgsmem, sizetoread); GSRINGBUF_DONECOPY(pgsmem, sizetoread);

View File

@ -45,10 +45,11 @@ extern u8 g_RealGSMem[0x2000];
#define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080)) #define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080))
#endif #endif
#define GS_RINGBUFFERBASE (u8*)(0x10200000) #define GS_RINGBUFFERBASE GS_RINGBUFF_STOREAGE
#define GS_RINGBUFFERSIZE 0x00300000 // 3Mb #define GS_RINGBUFFERSIZE 0x00300000 // 3Mb
#define GS_RINGBUFFEREND (u8*)(GS_RINGBUFFERBASE+GS_RINGBUFFERSIZE) #define GS_RINGBUFFEREND (u8*)(GS_RINGBUFFERBASE+GS_RINGBUFFERSIZE)
__declspec(align(4096)) extern u8 GS_RINGBUFF_STOREAGE[GS_RINGBUFFERSIZE];
enum GS_RINGTYPE enum GS_RINGTYPE
{ {
GS_RINGTYPE_RESTART = 0 GS_RINGTYPE_RESTART = 0

View File

@ -1118,7 +1118,7 @@ void hwWrite64(u32 mem, u64 value) {
} }
} }
void hwWrite128(u32 mem, u64 *value) { void hwWrite128(u32 mem, const u64 *value) {
if (mem >= 0x10004000 && mem < 0x10008000) { if (mem >= 0x10004000 && mem < 0x10008000) {
WriteFIFO(mem, value); return; WriteFIFO(mem, value); return;
} }

View File

@ -55,7 +55,7 @@ extern void CPU_INT( u32 n, s32 ecycle );
void ReadFIFO(u32 mem, u64 *out); void ReadFIFO(u32 mem, u64 *out);
void ConstReadFIFO(u32 mem); void ConstReadFIFO(u32 mem);
void WriteFIFO(u32 mem, u64 *value); void WriteFIFO(u32 mem, const u64 *value);
void ConstWriteFIFO(u32 mem); void ConstWriteFIFO(u32 mem);
@ -354,12 +354,12 @@ static __forceinline void *dmaGetAddr(u32 addr) {
return (void*)&psS[addr & 0x3ff0]; return (void*)&psS[addr & 0x3ff0];
} }
ptr = (u8*)memLUTR[addr >> 12]; ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0);
if (ptr == NULL) { if (ptr == NULL) {
SysPrintf("*PCSX2*: DMA error: %8.8x\n", addr); SysPrintf("*PCSX2*: DMA error: %8.8x\n", addr);
return NULL; return NULL;
} }
return (void*)(ptr + (addr & 0xff0)); return ptr;
} }
#endif #endif
@ -397,7 +397,7 @@ void hwConstWrite32(u32 mem, int mmreg);
void hwWrite64(u32 mem, u64 value); void hwWrite64(u32 mem, u64 value);
void hwConstWrite64(u32 mem, int mmreg); void hwConstWrite64(u32 mem, int mmreg);
void hwWrite128(u32 mem, u64 *value); void hwWrite128(u32 mem, const u64 *value);
void hwConstWrite128(u32 mem, int xmmreg); void hwConstWrite128(u32 mem, int xmmreg);
void hwIntcIrq(int n); void hwIntcIrq(int n);
@ -409,6 +409,10 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size);
int hwDmacSrcChainWithStack(DMACh *dma, int id); int hwDmacSrcChainWithStack(DMACh *dma, int id);
int hwDmacSrcChain(DMACh *dma, int id); int hwDmacSrcChain(DMACh *dma, int id);
#ifdef PCSX2_VIRTUAL_MEM
void iMemRead32Check();
#endif
extern void intcInterrupt(); extern void intcInterrupt();
extern void dmacInterrupt(); extern void dmacInterrupt();

View File

@ -20,98 +20,416 @@
#include "InterTables.h" #include "InterTables.h"
void (*Int_OpcodePrintTable[64])() = namespace EE
{ {
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ, namespace Opcodes
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI, {
COP0, COP1, COP2, UnknownOpcode, BEQL, BNEL, BLEZL, BGTZL, // We're working on new hopefully better cycle ratios, but they're still a WIP.
DADDI, DADDIU, LDL, LDR, MMI, UnknownOpcode, LQ, SQ, // And yes this whole thing is an ugly hack. I'll clean it up once we have
LB, LH, LWL, LW, LBU, LHU, LWR, LWU, // a better idea how exactly the cycle ratios will work best.
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
UnknownOpcode, LWC1, UnknownOpcode, PREF, UnknownOpcode,UnknownOpcode, LQC2, LD, //#define EXPERIMENTAL_CYCLE_TIMINGS
UnknownOpcode, SWC1, UnknownOpcode, UnknownOpcode, UnknownOpcode,UnknownOpcode, SQC2, SD
}; #ifdef EXPERIMENTAL_CYCLE_TIMINGS
// Number of cycles for basic instructions (add/sub, etc).
// On the EE these normally run in less than 1 cycle thanks to
// the superscalar nature of the CPU.
static const int Cycles_Default = 7; // 0.75 cycles for base instructions.
static const int Cycles_Branch = Cycles_Default;
// Cycle penalties for particuarly slow instructions.
static const int Cycles_Mult = 3*8;
static const int Cycles_Div = 14*8;
static const int Cycles_FPU_Sqrt = 5*8;
static const int Cycles_MMI_Mult = 4*8;
static const int Cycles_MMI_Div = 24*8;
static const int Cycles_Store = 28;
static const int Cycles_Load = 12;
#else
static const int Cycles_Default = 9;
static const int Cycles_Branch = Cycles_Default;
static const int Cycles_Mult = 2*8;
static const int Cycles_Div = 14*8;
static const int Cycles_FPU_Sqrt = 4*8;
static const int Cycles_MMI_Mult = 3*8;
static const int Cycles_MMI_Div = 23*8;
static const int Cycles_Store = 19; // 21 for snes emu
static const int Cycles_Load = 11; // 13 for snes emu
#endif
MakeOpcode( Unknown, Default );
MakeOpcode( MMI_Unknown, Default );
// Class Subset Opcodes
// (not really opcodes, but rather entire subsets of other opcode classes)
MakeOpcodeClass( SPECIAL );
MakeOpcodeClass( REGIMM );
//MakeOpcodeClass( COP0 );
//MakeOpcodeClass( COP1 );
//MakeOpcodeClass( COP2 );
MakeOpcodeClass( MMI );
MakeOpcodeClass( MMI0 );
MakeOpcodeClass( MMI2 );
MakeOpcodeClass( MMI1 );
MakeOpcodeClass( MMI3 );
// Misc Junk
MakeOpcode( COP0, Default );
MakeOpcode( COP1, Default );
MakeOpcode( COP2, Default );
MakeOpcode( CACHE, Default );
MakeOpcode( PREF, Default );
MakeOpcode( SYSCALL, Default );
MakeOpcode( BREAK, Default );
MakeOpcode( SYNC, Default );
// Branch/Jump Opcodes
MakeOpcode( J , Default );
MakeOpcode( JAL, Default );
MakeOpcode( JR, Default );
MakeOpcode( JALR, Default );
MakeOpcode( BEQ, Branch );
MakeOpcode( BNE, Branch );
MakeOpcode( BLEZ, Branch );
MakeOpcode( BGTZ, Branch );
MakeOpcode( BEQL, Branch );
MakeOpcode( BNEL, Branch );
MakeOpcode( BLEZL, Branch );
MakeOpcode( BGTZL, Branch );
MakeOpcode( BLTZ, Branch );
MakeOpcode( BGEZ, Branch );
MakeOpcode( BLTZL, Branch );
MakeOpcode( BGEZL, Branch );
MakeOpcode( BLTZAL, Branch );
MakeOpcode( BGEZAL, Branch );
MakeOpcode( BLTZALL, Branch );
MakeOpcode( BGEZALL, Branch );
MakeOpcode( TGEI, Branch );
MakeOpcode( TGEIU, Branch );
MakeOpcode( TLTI, Branch );
MakeOpcode( TLTIU, Branch );
MakeOpcode( TEQI, Branch );
MakeOpcode( TNEI, Branch );
MakeOpcode( TGE, Branch );
MakeOpcode( TGEU, Branch );
MakeOpcode( TLT, Branch );
MakeOpcode( TLTU, Branch );
MakeOpcode( TEQ, Branch );
MakeOpcode( TNE, Branch );
// Arithmetic
MakeOpcode( MULT, Mult );
MakeOpcode( MULTU, Mult );
MakeOpcode( MULT1, Mult );
MakeOpcode( MULTU1, Mult );
MakeOpcode( MADD, Mult );
MakeOpcode( MADDU, Mult );
MakeOpcode( MADD1, Mult );
MakeOpcode( MADDU1, Mult );
MakeOpcode( DIV, Div );
MakeOpcode( DIVU, Div );
MakeOpcode( DIV1, Div );
MakeOpcode( DIVU1, Div );
MakeOpcode( ADDI, Default );
MakeOpcode( ADDIU, Default );
MakeOpcode( DADDI, Default );
MakeOpcode( DADDIU, Default );
MakeOpcode( DADD, Default );
MakeOpcode( DADDU, Default );
MakeOpcode( DSUB, Default );
MakeOpcode( DSUBU, Default );
MakeOpcode( ADD, Default );
MakeOpcode( ADDU, Default );
MakeOpcode( SUB, Default );
MakeOpcode( SUBU, Default );
MakeOpcode( ANDI, Default );
MakeOpcode( ORI, Default );
MakeOpcode( XORI, Default );
MakeOpcode( AND, Default );
MakeOpcode( OR, Default );
MakeOpcode( XOR, Default );
MakeOpcode( NOR, Default );
MakeOpcode( SLTI, Default );
MakeOpcode( SLTIU, Default );
MakeOpcode( SLT, Default );
MakeOpcode( SLTU, Default );
MakeOpcode( LUI, Default );
MakeOpcode( SLL, Default );
MakeOpcode( SRL, Default );
MakeOpcode( SRA, Default );
MakeOpcode( SLLV, Default );
MakeOpcode( SRLV, Default );
MakeOpcode( SRAV, Default );
MakeOpcode( MOVZ, Default );
MakeOpcode( MOVN, Default );
MakeOpcode( DSLLV, Default );
MakeOpcode( DSRLV, Default );
MakeOpcode( DSRAV, Default );
MakeOpcode( DSLL, Default );
MakeOpcode( DSRL, Default );
MakeOpcode( DSRA, Default );
MakeOpcode( DSLL32, Default );
MakeOpcode( DSRL32, Default );
MakeOpcode( DSRA32, Default );
MakeOpcode( MFHI, Default );
MakeOpcode( MTHI, Default );
MakeOpcode( MFLO, Default );
MakeOpcode( MTLO, Default );
MakeOpcode( MFSA, Default );
MakeOpcode( MTSA, Default );
MakeOpcode( MTSAB, Default );
MakeOpcode( MTSAH, Default );
MakeOpcode( MFHI1, Default );
MakeOpcode( MTHI1, Default );
MakeOpcode( MFLO1, Default );
MakeOpcode( MTLO1, Default );
// Loads!
MakeOpcode( LDL, Load );
MakeOpcode( LDR, Load );
MakeOpcode( LQ, Load );
MakeOpcode( LB, Load );
MakeOpcode( LH, Load );
MakeOpcode( LWL, Load );
MakeOpcode( LW, Load );
MakeOpcode( LBU, Load );
MakeOpcode( LHU, Load );
MakeOpcode( LWR, Load );
MakeOpcode( LWU, Load );
MakeOpcode( LWC1, Load );
MakeOpcode( LQC2, Load );
MakeOpcode( LD, Load );
// Stores!
MakeOpcode( SQ, Store );
MakeOpcode( SB, Store );
MakeOpcode( SH, Store );
MakeOpcode( SWL, Store );
MakeOpcode( SW, Store );
MakeOpcode( SDL, Store );
MakeOpcode( SDR, Store );
MakeOpcode( SWR, Store );
MakeOpcode( SWC1, Store );
MakeOpcode( SQC2, Store );
MakeOpcode( SD, Store );
void (*Int_SpecialPrintTable[64])() = // Multimedia Instructions!
{
SLL, UnknownOpcode, SRL, SRA, SLLV, UnknownOpcode, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, UnknownOpcode, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, UnknownOpcode, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, UnknownOpcode,UnknownOpcode,UnknownOpcode,UnknownOpcode,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA , MTSA , SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, UnknownOpcode, TNE, UnknownOpcode,
DSLL, UnknownOpcode, DSRL, DSRA, DSLL32, UnknownOpcode, DSRL32, DSRA32
};
void (*Int_REGIMMPrintTable[32])() = { MakeOpcode( PLZCW, Default );
BLTZ, BGEZ, BLTZL, BGEZL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, MakeOpcode( PMFHL, Default );
TGEI, TGEIU, TLTI, TLTIU, TEQI, UnknownOpcode, TNEI, UnknownOpcode, MakeOpcode( PMTHL, Default );
BLTZAL, BGEZAL, BLTZALL, BGEZALL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, MakeOpcode( PSLLH, Default );
MTSAB, MTSAH , UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, MakeOpcode( PSRLH, Default );
}; MakeOpcode( PSRAH, Default );
MakeOpcode( PSLLW, Default );
MakeOpcode( PSRLW, Default );
MakeOpcode( PSRAW, Default );
void (*Int_MMIPrintTable[64])() = MakeOpcode( PADDW, Default );
{ MakeOpcode( PADDH, Default );
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDB, Default );
MMI0, MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDSW, Default );
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDSH, Default );
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDSB, Default );
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDUW, Default );
MMI1 , MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADDUH, Default );
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH, MakeOpcode( PADDUB, Default );
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW, MakeOpcode( PSUBW, Default );
}; MakeOpcode( PSUBH, Default );
MakeOpcode( PSUBB, Default );
MakeOpcode( PSUBSW, Default );
MakeOpcode( PSUBSH, Default );
MakeOpcode( PSUBSB, Default );
MakeOpcode( PSUBUW, Default );
MakeOpcode( PSUBUH, Default );
MakeOpcode( PSUBUB, Default );
void (*Int_MMI0PrintTable[32])() = MakeOpcode( PCGTW, Default );
{ MakeOpcode( PMAXW, Default );
PADDW, PSUBW, PCGTW, PMAXW, MakeOpcode( PMAXH, Default );
PADDH, PSUBH, PCGTH, PMAXH, MakeOpcode( PCGTH, Default );
PADDB, PSUBB, PCGTB, MMI_Unknown, MakeOpcode( PCGTB, Default );
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PEXTLW, Default );
PADDSW, PSUBSW, PEXTLW, PPACW, MakeOpcode( PEXTLH, Default );
PADDSH, PSUBSH, PEXTLH, PPACH, MakeOpcode( PEXTLB, Default );
PADDSB, PSUBSB, PEXTLB, PPACB, MakeOpcode( PEXT5, Default );
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5, MakeOpcode( PPACW, Default );
}; MakeOpcode( PPACH, Default );
MakeOpcode( PPACB, Default );
MakeOpcode( PPAC5, Default );
void (*Int_MMI1PrintTable[32])() = MakeOpcode( PABSW, Default );
{ MakeOpcode( PABSH, Default );
MMI_Unknown, PABSW, PCEQW, PMINW, MakeOpcode( PCEQW, Default );
PADSBH, PABSH, PCEQH, PMINH, MakeOpcode( PMINW, Default );
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown, MakeOpcode( PMINH, Default );
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PADSBH, Default );
PADDUW, PSUBUW, PEXTUW, MMI_Unknown, MakeOpcode( PCEQH, Default );
PADDUH, PSUBUH, PEXTUH, MMI_Unknown, MakeOpcode( PCEQB, Default );
PADDUB, PSUBUB, PEXTUB, QFSRV, MakeOpcode( PEXTUW, Default );
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MakeOpcode( PEXTUH, Default );
}; MakeOpcode( PEXTUB, Default );
MakeOpcode( PSLLVW, Default );
MakeOpcode( PSRLVW, Default );
MakeOpcode( QFSRV, Default );
MakeOpcode( PMADDH, MMI_Mult );
MakeOpcode( PHMADH, MMI_Mult );
MakeOpcode( PMSUBH, MMI_Mult );
MakeOpcode( PHMSBH, MMI_Mult );
MakeOpcode( PMULTH, MMI_Mult );
MakeOpcode( PMADDW, MMI_Mult );
MakeOpcode( PMSUBW, MMI_Mult );
MakeOpcode( PMFHI, MMI_Mult );
MakeOpcode( PMFLO, MMI_Mult );
MakeOpcode( PMULTW, MMI_Mult );
MakeOpcode( PMADDUW, MMI_Mult );
MakeOpcode( PMULTUW, MMI_Mult );
MakeOpcode( PDIVUW, MMI_Div );
MakeOpcode( PDIVW, MMI_Div );
MakeOpcode( PDIVBW, MMI_Div );
MakeOpcode( PINTH, Default );
MakeOpcode( PCPYLD, Default );
MakeOpcode( PAND, Default );
MakeOpcode( PXOR, Default );
MakeOpcode( PEXEH, Default );
MakeOpcode( PREVH, Default );
MakeOpcode( PEXEW, Default );
MakeOpcode( PROT3W, Default );
MakeOpcode( PSRAVW, Default );
MakeOpcode( PMTHI, Default );
MakeOpcode( PMTLO, Default );
MakeOpcode( PINTEH, Default );
MakeOpcode( PCPYUD, Default );
MakeOpcode( POR, Default );
MakeOpcode( PNOR, Default );
MakeOpcode( PEXCH, Default );
MakeOpcode( PCPYH, Default );
MakeOpcode( PEXCW, Default );
}
namespace OpcodeTables
{
using namespace Opcodes;
const OPCODE Standard[64] =
{
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, Unknown, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, Opcodes::MMI, Unknown, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
Unknown, LWC1, Unknown, PREF, Unknown, Unknown, LQC2, LD,
Unknown, SWC1, Unknown, Unknown, Unknown, Unknown, SQC2, SD
};
const OPCODE Special[64] =
{
SLL, Unknown, SRL, SRA, SLLV, Unknown, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, Unknown, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, Unknown, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, Unknown, Unknown, Unknown, Unknown,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA, MTSA, SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, Unknown, TNE, Unknown,
DSLL, Unknown, DSRL, DSRA, DSLL32, Unknown, DSRL32, DSRA32
};
const OPCODE RegImm[32] = {
BLTZ, BGEZ, BLTZL, BGEZL, Unknown, Unknown, Unknown, Unknown,
TGEI, TGEIU, TLTI, TLTIU, TEQI, Unknown, TNEI, Unknown,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, Unknown, Unknown, Unknown, Unknown,
MTSAB, MTSAH , Unknown, Unknown, Unknown, Unknown, Unknown, Unknown,
};
const OPCODE MMI[64] =
{
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
Opcodes::MMI0, Opcodes::MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
Opcodes::MMI1, Opcodes::MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
};
const OPCODE MMI0[32] =
{
PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDSW, PSUBSW, PEXTLW, PPACW,
PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
};
const OPCODE MMI1[32] =
{
MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDUW, PSUBUW, PEXTUW, MMI_Unknown,
PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
};
void (*Int_MMI2PrintTable[32])() = const OPCODE MMI2[32] =
{ {
PMADDW, MMI_Unknown, PSLLVW, PSRLVW, PMADDW, MMI_Unknown, PSLLVW, PSRLVW,
PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown, PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHI, PMFLO, PINTH, MMI_Unknown, PMFHI, PMFLO, PINTH, MMI_Unknown,
PMULTW, PDIVW, PCPYLD, MMI_Unknown, PMULTW, PDIVW, PCPYLD, MMI_Unknown,
PMADDH, PHMADH, PAND, PXOR, PMADDH, PHMADH, PAND, PXOR,
PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown, PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXEH, PREVH, MMI_Unknown, MMI_Unknown, PEXEH, PREVH,
PMULTH, PDIVBW, PEXEW, PROT3W, PMULTH, PDIVBW, PEXEW, PROT3W,
}; };
void (*Int_MMI3PrintTable[32])() = const OPCODE MMI3[32] =
{ {
PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW, PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMTHI, PMTLO, PINTEH, MMI_Unknown, PMTHI, PMTLO, PINTEH, MMI_Unknown,
PMULTUW, PDIVUW, PCPYUD, MMI_Unknown, PMULTUW, PDIVUW, PCPYUD, MMI_Unknown,
MMI_Unknown, MMI_Unknown, POR, PNOR, MMI_Unknown, MMI_Unknown, POR, PNOR,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXCH, PCPYH, MMI_Unknown, MMI_Unknown, PEXCH, PCPYH,
MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown, MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown,
}; };
} // end namespace EE::OpcodeTables
} // end namespace EE
void (*Int_COP0PrintTable[32])() = void (*Int_COP0PrintTable[32])() =
{ {

View File

@ -18,14 +18,62 @@
#ifndef INTERTABLES_H #ifndef INTERTABLES_H
#define INTERTABLES_H #define INTERTABLES_H
extern void (*Int_OpcodePrintTable[64])(); #include <string>
extern void (*Int_SpecialPrintTable[64])();
extern void (*Int_REGIMMPrintTable[32])(); #include "PS2ETypes.h"
extern void (*Int_MMIPrintTable[64])();
extern void (*Int_MMI0PrintTable[32])(); #include "iR5900AritImm.h"
extern void (*Int_MMI1PrintTable[32])(); #include "iR5900Arit.h"
extern void (*Int_MMI2PrintTable[32])(); #include "iR5900MultDiv.h"
extern void (*Int_MMI3PrintTable[32])(); #include "iR5900Shift.h"
#include "iR5900Branch.h"
#include "iR5900Jump.h"
#include "iR5900LoadStore.h"
#include "iR5900Move.h"
#include "iMMI.h"
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
void recUnknown();
void recMMI_Unknown();
void recREGIMM() ;
void recSPECIAL();
void recCOP0();
void recCOP1();
void recCOP2();
void recMMI();
void recMMI0();
void recMMI1();
void recMMI2();
void recMMI3();
void recCACHE();
void recPREF();
void recSYSCALL();
void recBREAK();
void recSYNC();
void recMFSA();
void recMTSA();
void recMTSAB();
void recMTSAH();
void recTGE();
void recTGEU();
void recTLT();
void recTLTU();
void recTEQ();
void recTNE();
void recTGEI();
void recTGEIU();
void recTLTI();
void recTLTIU();
void recTEQI();
void recTNEI();
} } }
// TODO : Move these into the EE::OpcodesTable namespace
extern void (*Int_COP0PrintTable[32])(); extern void (*Int_COP0PrintTable[32])();
extern void (*Int_COP0BC0PrintTable[32])(); extern void (*Int_COP0BC0PrintTable[32])();
extern void (*Int_COP0C0PrintTable[64])(); extern void (*Int_COP0C0PrintTable[64])();
@ -38,18 +86,6 @@ extern void (*Int_COP2BC2PrintTable[32])();
extern void (*Int_COP2SPECIAL1PrintTable[64])(); extern void (*Int_COP2SPECIAL1PrintTable[64])();
extern void (*Int_COP2SPECIAL2PrintTable[128])(); extern void (*Int_COP2SPECIAL2PrintTable[128])();
void SPECIAL();
void REGIMM();
void UnknownOpcode();
void COP0();
void COP1();
void COP2();
void MMI_Unknown();
void MMI();
void MMI0();
void MMI1();
void MMI2();
void MMI3();
void COP0_Unknown(); void COP0_Unknown();
void COP0_BC0(); void COP0_BC0();
void COP0_Func(); void COP0_Func();
@ -62,240 +98,602 @@ void COP2_SPECIAL();
void COP2_Unknown(); void COP2_Unknown();
void COP2_SPECIAL2(); void COP2_SPECIAL2();
namespace EE
{
// Encapsulates information about every opcode on the Emotion Engine and
// it's many co-processors.
struct OPCODE
{
// Textual name of the instruction.
const char Name[12];
// Number of cycles this instruction normally uses.
u8 cycles;
const OPCODE& (*getsubclass)();
// Process the instruction using the interpreter.
// The action is performed immediately on the EE's cpu state.
void (*interpret)();
#ifndef PCSX2_NORECBUILD
// Generate recompiled code for this instruction, injected into
// the current EErec block state.
void (*recompile)();
#endif
// Generates a string representation of the instruction and it's parameters,
// and pastes it into the given output parameter.
void (*decode)( std::string& output );
};
// Returns the current real instruction, as per the current cpuRegs settings.
const OPCODE& GetCurrentInstruction();
// Generates an entry for the given opcode name.
// Assumes the default function naming schemes for interpreter and recompiler functions.
#ifdef PCSX2_NORECBUILD
# define MakeOpcode( name, cycles ) \
static const OPCODE name = { \
#name, \
cycles, \
NULL, \
EE::Interpreter::OpcodeImpl::name, \
EE::Debug::OpcodePrint::name \
}
# define MakeOpcodeClass( name ) \
static const OPCODE name = { \
#name, \
0, \
EE::Opcodes::Class_##name, \
NULL, \
NULL \
}
#else
# define MakeOpcode( name, cycles ) \
static const OPCODE name = { \
#name, \
Cycles_##cycles, \
NULL, \
EE::Interpreter::OpcodeImpl::name, \
EE::Dynarec::OpcodeImpl::rec##name, \
EE::Debug::OpcodePrint::name \
}
# define MakeOpcodeClass( name ) \
static const OPCODE name = { \
#name, \
0, \
EE::Opcodes::Class_##name, \
NULL, \
NULL, \
NULL \
}
#endif
namespace OpcodeTables
{
extern const OPCODE Standard[64];
extern const OPCODE Special[64];
extern const OPCODE RegImm[32];
extern const OPCODE MMI[64];
extern const OPCODE MMI0[32];
extern const OPCODE MMI1[32];
extern const OPCODE MMI2[32];
extern const OPCODE MMI3[32];
}
namespace Opcodes
{
const OPCODE& Class_SPECIAL();
const OPCODE& Class_REGIMM();
const OPCODE& Class_MMI();
const OPCODE& Class_MMI0();
const OPCODE& Class_MMI1();
const OPCODE& Class_MMI2();
const OPCODE& Class_MMI3();
}
namespace Debug
{
namespace OpcodePrint
{
//****************************************************************
void Unknown( std::string& output );
void COP0( std::string& output );
void COP1( std::string& output );
void COP2( std::string& output );
void MMI_Unknown( std::string& output );
// **********************Standard Opcodes************************** // **********************Standard Opcodes**************************
void J(); void J( std::string& output );
void JAL(); void JAL( std::string& output );
void BEQ(); void BEQ( std::string& output );
void BNE(); void BNE( std::string& output );
void BLEZ(); void BLEZ( std::string& output );
void BGTZ(); void BGTZ( std::string& output );
void ADDI(); void ADDI( std::string& output );
void ADDIU(); void ADDIU( std::string& output );
void SLTI(); void SLTI( std::string& output );
void SLTIU(); void SLTIU( std::string& output );
void ANDI(); void ANDI( std::string& output );
void ORI(); void ORI( std::string& output );
void XORI(); void XORI( std::string& output );
void LUI(); void LUI( std::string& output );
void BEQL(); void BEQL( std::string& output );
void BNEL(); void BNEL( std::string& output );
void BLEZL(); void BLEZL( std::string& output );
void BGTZL(); void BGTZL( std::string& output );
void DADDI(); void DADDI( std::string& output );
void DADDIU(); void DADDIU( std::string& output );
void LDL(); void LDL( std::string& output );
void LDR(); void LDR( std::string& output );
void LB(); void LB( std::string& output );
void LH(); void LH( std::string& output );
void LWL(); void LWL( std::string& output );
void LW(); void LW( std::string& output );
void LBU(); void LBU( std::string& output );
void LHU(); void LHU( std::string& output );
void LWR(); void LWR( std::string& output );
void LWU(); void LWU( std::string& output );
void SB(); void SB( std::string& output );
void SH(); void SH( std::string& output );
void SWL(); void SWL( std::string& output );
void SW(); void SW( std::string& output );
void SDL(); void SDL( std::string& output );
void SDR(); void SDR( std::string& output );
void SWR(); void SWR( std::string& output );
void CACHE(); void CACHE( std::string& output );
void LWC1(); void LWC1( std::string& output );
void PREF(); void PREF( std::string& output );
void LQC2(); void LQC2( std::string& output );
void LD(); void LD( std::string& output );
void SQC2(); void SQC2( std::string& output );
void SD(); void SD( std::string& output );
void LQ(); void LQ( std::string& output );
void SQ(); void SQ( std::string& output );
void SWC1(); void SWC1( std::string& output );
//***************end of standard opcodes*************************
//***************SPECIAL OPCODES**********************************
void SLL( std::string& output );
void SRL( std::string& output );
void SRA( std::string& output );
void SLLV( std::string& output );
void SRLV( std::string& output );
void SRAV( std::string& output );
void JR( std::string& output );
void JALR( std::string& output );
void SYSCALL( std::string& output );
void BREAK( std::string& output );
void SYNC( std::string& output );
void MFHI( std::string& output );
void MTHI( std::string& output );
void MFLO( std::string& output );
void MTLO( std::string& output );
void DSLLV( std::string& output );
void DSRLV( std::string& output );
void DSRAV( std::string& output );
void MULT( std::string& output );
void MULTU( std::string& output );
void DIV( std::string& output );
void DIVU( std::string& output );
void ADD( std::string& output );
void ADDU( std::string& output );
void SUB( std::string& output );
void SUBU( std::string& output );
void AND( std::string& output );
void OR( std::string& output );
void XOR( std::string& output );
void NOR( std::string& output );
void SLT( std::string& output );
void SLTU( std::string& output );
void DADD( std::string& output );
void DADDU( std::string& output );
void DSUB( std::string& output );
void DSUBU( std::string& output );
void TGE( std::string& output );
void TGEU( std::string& output );
void TLT( std::string& output );
void TLTU( std::string& output );
void TEQ( std::string& output );
void TNE( std::string& output );
void DSLL( std::string& output );
void DSRL( std::string& output );
void DSRA( std::string& output );
void DSLL32( std::string& output );
void DSRL32( std::string& output );
void DSRA32( std::string& output );
void MOVZ( std::string& output );
void MOVN( std::string& output );
void MFSA( std::string& output );
void MTSA( std::string& output );
//******************END OF SPECIAL OPCODES**************************
//******************REGIMM OPCODES**********************************
void BLTZ( std::string& output );
void BGEZ( std::string& output );
void BLTZL( std::string& output );
void BGEZL( std::string& output );
void TGEI( std::string& output );
void TGEIU( std::string& output );
void TLTI( std::string& output );
void TLTIU( std::string& output );
void TEQI( std::string& output );
void TNEI( std::string& output );
void BLTZAL( std::string& output );
void BGEZAL( std::string& output );
void BLTZALL( std::string& output );
void BGEZALL( std::string& output );
void MTSAB( std::string& output );
void MTSAH( std::string& output );
//*****************END OF REGIMM OPCODES*****************************
//*****************MMI OPCODES*********************************
void MADD( std::string& output );
void MADDU( std::string& output );
void PLZCW( std::string& output );
void MADD1( std::string& output );
void MADDU1( std::string& output );
void MFHI1( std::string& output );
void MTHI1( std::string& output );
void MFLO1( std::string& output );
void MTLO1( std::string& output );
void MULT1( std::string& output );
void MULTU1( std::string& output );
void DIV1( std::string& output );
void DIVU1( std::string& output );
void PMFHL( std::string& output );
void PMTHL( std::string& output );
void PSLLH( std::string& output );
void PSRLH( std::string& output );
void PSRAH( std::string& output );
void PSLLW( std::string& output );
void PSRLW( std::string& output );
void PSRAW( std::string& output );
//*****************END OF MMI OPCODES**************************
//*************************MMI0 OPCODES************************
void PADDW( std::string& output );
void PSUBW( std::string& output );
void PCGTW( std::string& output );
void PMAXW( std::string& output );
void PADDH( std::string& output );
void PSUBH( std::string& output );
void PCGTH( std::string& output );
void PMAXH( std::string& output );
void PADDB( std::string& output );
void PSUBB( std::string& output );
void PCGTB( std::string& output );
void PADDSW( std::string& output );
void PSUBSW( std::string& output );
void PEXTLW( std::string& output );
void PPACW( std::string& output );
void PADDSH( std::string& output );
void PSUBSH( std::string& output );
void PEXTLH( std::string& output );
void PPACH( std::string& output );
void PADDSB( std::string& output );
void PSUBSB( std::string& output );
void PEXTLB( std::string& output );
void PPACB( std::string& output );
void PEXT5( std::string& output );
void PPAC5( std::string& output );
//***END OF MMI0 OPCODES******************************************
//**********MMI1 OPCODES**************************************
void PABSW( std::string& output );
void PCEQW( std::string& output );
void PMINW( std::string& output );
void PADSBH( std::string& output );
void PABSH( std::string& output );
void PCEQH( std::string& output );
void PMINH( std::string& output );
void PCEQB( std::string& output );
void PADDUW( std::string& output );
void PSUBUW( std::string& output );
void PEXTUW( std::string& output );
void PADDUH( std::string& output );
void PSUBUH( std::string& output );
void PEXTUH( std::string& output );
void PADDUB( std::string& output );
void PSUBUB( std::string& output );
void PEXTUB( std::string& output );
void QFSRV( std::string& output );
//********END OF MMI1 OPCODES***********************************
//*********MMI2 OPCODES***************************************
void PMADDW( std::string& output );
void PSLLVW( std::string& output );
void PSRLVW( std::string& output );
void PMSUBW( std::string& output );
void PMFHI( std::string& output );
void PMFLO( std::string& output );
void PINTH( std::string& output );
void PMULTW( std::string& output );
void PDIVW( std::string& output );
void PCPYLD( std::string& output );
void PMADDH( std::string& output );
void PHMADH( std::string& output );
void PAND( std::string& output );
void PXOR( std::string& output );
void PMSUBH( std::string& output );
void PHMSBH( std::string& output );
void PEXEH( std::string& output );
void PREVH( std::string& output );
void PMULTH( std::string& output );
void PDIVBW( std::string& output );
void PEXEW( std::string& output );
void PROT3W( std::string& output );
//*****END OF MMI2 OPCODES***********************************
//*************************MMI3 OPCODES************************
void PMADDUW( std::string& output );
void PSRAVW( std::string& output );
void PMTHI( std::string& output );
void PMTLO( std::string& output );
void PINTEH( std::string& output );
void PMULTUW( std::string& output );
void PDIVUW( std::string& output );
void PCPYUD( std::string& output );
void POR( std::string& output );
void PNOR( std::string& output );
void PEXCH( std::string& output );
void PCPYH( std::string& output );
void PEXCW( std::string& output );
//**********************END OF MMI3 OPCODES********************
}
}
namespace Interpreter
{
namespace OpcodeImpl
{
void COP0();
void COP1();
void COP2();
void Unknown();
void MMI_Unknown();
// **********************Standard Opcodes**************************
void J();
void JAL();
void BEQ();
void BNE();
void BLEZ();
void BGTZ();
void ADDI();
void ADDIU();
void SLTI();
void SLTIU();
void ANDI();
void ORI();
void XORI();
void LUI();
void BEQL();
void BNEL();
void BLEZL();
void BGTZL();
void DADDI();
void DADDIU();
void LDL();
void LDR();
void LB();
void LH();
void LWL();
void LW();
void LBU();
void LHU();
void LWR();
void LWU();
void SB();
void SH();
void SWL();
void SW();
void SDL();
void SDR();
void SWR();
void CACHE();
void LWC1();
void PREF();
void LQC2();
void LD();
void SQC2();
void SD();
void LQ();
void SQ();
void SWC1();
//***************end of standard opcodes************************* //***************end of standard opcodes*************************
//***************SPECIAL OPCODES********************************** //***************SPECIAL OPCODES**********************************
void SLL(); void SLL();
void SRL(); void SRL();
void SRA(); void SRA();
void SLLV(); void SLLV();
void SRLV(); void SRLV();
void SRAV(); void SRAV();
void JR(); void JR();
void JALR(); void JALR();
void SYSCALL(); void SYSCALL();
void BREAK(); void BREAK();
void SYNC(); void SYNC();
void MFHI(); void MFHI();
void MTHI(); void MTHI();
void MFLO(); void MFLO();
void MTLO(); void MTLO();
void DSLLV(); void DSLLV();
void DSRLV(); void DSRLV();
void DSRAV(); void DSRAV();
void MULT(); void MULT();
void MULTU(); void MULTU();
void DIV(); void DIV();
void DIVU(); void DIVU();
void ADD(); void ADD();
void ADDU(); void ADDU();
void SUB(); void SUB();
void SUBU(); void SUBU();
void AND(); void AND();
void OR(); void OR();
void XOR(); void XOR();
void NOR(); void NOR();
void SLT(); void SLT();
void SLTU(); void SLTU();
void DADD(); void DADD();
void DADDU(); void DADDU();
void DSUB(); void DSUB();
void DSUBU(); void DSUBU();
void TGE(); void TGE();
void TGEU(); void TGEU();
void TLT(); void TLT();
void TLTU(); void TLTU();
void TEQ(); void TEQ();
void TNE(); void TNE();
void DSLL(); void DSLL();
void DSRL(); void DSRL();
void DSRA(); void DSRA();
void DSLL32(); void DSLL32();
void DSRL32(); void DSRL32();
void DSRA32(); void DSRA32();
void MOVZ(); void MOVZ();
void MOVN(); void MOVN();
void MFSA(); void MFSA();
void MTSA(); void MTSA();
//******************END OF SPECIAL OPCODES************************** //******************END OF SPECIAL OPCODES**************************
//******************REGIMM OPCODES********************************** //******************REGIMM OPCODES**********************************
void BLTZ(); void BLTZ();
void BGEZ(); void BGEZ();
void BLTZL(); void BLTZL();
void BGEZL(); void BGEZL();
void TGEI(); void TGEI();
void TGEIU(); void TGEIU();
void TLTI(); void TLTI();
void TLTIU(); void TLTIU();
void TEQI(); void TEQI();
void TNEI(); void TNEI();
void BLTZAL(); void BLTZAL();
void BGEZAL(); void BGEZAL();
void BLTZALL(); void BLTZALL();
void BGEZALL(); void BGEZALL();
void MTSAB(); void MTSAB();
void MTSAH(); void MTSAH();
//*****************END OF REGIMM OPCODES***************************** //*****************END OF REGIMM OPCODES*****************************
//*****************MMI OPCODES*********************************
void MADD();
void MADDU();
void PLZCW();
void MADD1();
void MADDU1();
void MFHI1();
void MTHI1();
void MFLO1();
void MTLO1();
void MULT1();
void MULTU1();
void DIV1();
void DIVU1();
void PMFHL();
void PMTHL();
void PSLLH();
void PSRLH();
void PSRAH();
void PSLLW();
void PSRLW();
void PSRAW();
//*****************END OF MMI OPCODES**************************
//*************************MMI0 OPCODES************************
void PADDW(); //*****************MMI OPCODES*********************************
void PSUBW(); void MADD();
void PCGTW(); void MADDU();
void PMAXW(); void PLZCW();
void PADDH(); void MADD1();
void PSUBH(); void MADDU1();
void PCGTH(); void MFHI1();
void PMAXH(); void MTHI1();
void PADDB(); void MFLO1();
void PSUBB(); void MTLO1();
void PCGTB(); void MULT1();
void PADDSW(); void MULTU1();
void PSUBSW(); void DIV1();
void PEXTLW(); void DIVU1();
void PPACW(); void PMFHL();
void PADDSH(); void PMTHL();
void PSUBSH(); void PSLLH();
void PEXTLH(); void PSRLH();
void PPACH(); void PSRAH();
void PADDSB(); void PSLLW();
void PSUBSB(); void PSRLW();
void PEXTLB(); void PSRAW();
void PPACB(); //*****************END OF MMI OPCODES**************************
void PEXT5();
void PPAC5(); //*************************MMI0 OPCODES************************
void PADDW();
void PSUBW();
void PCGTW();
void PMAXW();
void PADDH();
void PSUBH();
void PCGTH();
void PMAXH();
void PADDB();
void PSUBB();
void PCGTB();
void PADDSW();
void PSUBSW();
void PEXTLW();
void PPACW();
void PADDSH();
void PSUBSH();
void PEXTLH();
void PPACH();
void PADDSB();
void PSUBSB();
void PEXTLB();
void PPACB();
void PEXT5();
void PPAC5();
//***END OF MMI0 OPCODES****************************************** //***END OF MMI0 OPCODES******************************************
//**********MMI1 OPCODES************************************** //**********MMI1 OPCODES**************************************
void PABSW(); void PABSW();
void PCEQW(); void PCEQW();
void PMINW(); void PMINW();
void PADSBH(); void PADSBH();
void PABSH(); void PABSH();
void PCEQH(); void PCEQH();
void PMINH(); void PMINH();
void PCEQB(); void PCEQB();
void PADDUW(); void PADDUW();
void PSUBUW(); void PSUBUW();
void PEXTUW(); void PEXTUW();
void PADDUH(); void PADDUH();
void PSUBUH(); void PSUBUH();
void PEXTUH(); void PEXTUH();
void PADDUB(); void PADDUB();
void PSUBUB(); void PSUBUB();
void PEXTUB(); void PEXTUB();
void QFSRV(); void QFSRV();
//********END OF MMI1 OPCODES*********************************** //********END OF MMI1 OPCODES***********************************
//*********MMI2 OPCODES*************************************** //*********MMI2 OPCODES***************************************
void PMADDW(); void PMADDW();
void PSLLVW(); void PSLLVW();
void PSRLVW(); void PSRLVW();
void PMSUBW(); void PMSUBW();
void PMFHI(); void PMFHI();
void PMFLO(); void PMFLO();
void PINTH(); void PINTH();
void PMULTW(); void PMULTW();
void PDIVW(); void PDIVW();
void PCPYLD(); void PCPYLD();
void PMADDH(); void PMADDH();
void PHMADH(); void PHMADH();
void PAND(); void PAND();
void PXOR(); void PXOR();
void PMSUBH(); void PMSUBH();
void PHMSBH(); void PHMSBH();
void PEXEH(); void PEXEH();
void PREVH(); void PREVH();
void PMULTH(); void PMULTH();
void PDIVBW(); void PDIVBW();
void PEXEW(); void PEXEW();
void PROT3W(); void PROT3W();
//*****END OF MMI2 OPCODES*********************************** //*****END OF MMI2 OPCODES***********************************
//*************************MMI3 OPCODES************************ //*************************MMI3 OPCODES************************
void PMADDUW(); void PMADDUW();
void PSRAVW(); void PSRAVW();
void PMTHI(); void PMTHI();
void PMTLO(); void PMTLO();
void PINTEH(); void PINTEH();
void PMULTUW(); void PMULTUW();
void PDIVUW(); void PDIVUW();
void PCPYUD(); void PCPYUD();
void POR(); void POR();
void PNOR(); void PNOR();
void PEXCH(); void PEXCH();
void PCPYH(); void PCPYH();
void PEXCW(); void PEXCW();
//**********************END OF MMI3 OPCODES******************** //**********************END OF MMI3 OPCODES********************
}
} // end namespace Interpreter
} // End namespace EE
//**************************************************************************** //****************************************************************************
//** COP0 ** //** COP0 **
//**************************************************************************** //****************************************************************************

View File

@ -25,8 +25,6 @@
#include <float.h> #include <float.h>
extern u32 maxrecmem;
const char *bios[256]={ const char *bios[256]={
//0x00 //0x00
"RFU000_FullReset", "ResetEE", "SetGsCrt", "RFU003", "RFU000_FullReset", "ResetEE", "SetGsCrt", "RFU003",
@ -76,25 +74,40 @@ const char *bios[256]={
"Deci2Call", "PSMode", "MachineType", "GetMemorySize", "Deci2Call", "PSMode", "MachineType", "GetMemorySize",
}; };
extern void (*LT_OpcodePrintTable[64])();
int branch2 = 0; int branch2 = 0;
static u32 branchPC; static u32 branchPC;
// These macros are used to assemble the repassembler functions // These macros are used to assemble the repassembler functions
#ifdef CPU_LOG #ifdef PCSX2_DEVBUILD
#define debugI() \ static void debugI()
if (Log) { CPU_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); } \ {
//if (Log) { CPU_LOG("%s\n", disR5900Current.getString()); }
if (cpuRegs.GPR.n.r0.UD[0] || cpuRegs.GPR.n.r0.UD[1]) SysPrintf("R0 is not zero!!!!\n"); if (cpuRegs.GPR.n.r0.UD[0] || cpuRegs.GPR.n.r0.UD[1]) SysPrintf("R0 is not zero!!!!\n");
}
#else #else
#define debugI() static void debugI() {}
#endif #endif
static __forceinline void execI() { static u32 cpuBlockCycles = 0; // 3 bit fixed point version of cycle count
cpuRegs.cycle++; namespace EE
//cpuRegs.CP0.n.Count++; /*count every cycles.*/ {
const OPCODE& GetCurrentInstruction()
{
const EE::OPCODE* opcode = &EE::OpcodeTables::Standard[_Opcode_];
while( opcode->getsubclass != NULL )
opcode = &opcode->getsubclass();
return *opcode;
}
}
static std::string disOut;
static __forceinline void execI()
{
#ifdef _DEBUG #ifdef _DEBUG
if (memRead32(cpuRegs.pc, &cpuRegs.code) == -1) return; if (memRead32(cpuRegs.pc, &cpuRegs.code) == -1) return;
debugI(); debugI();
@ -102,8 +115,17 @@ static __forceinline void execI() {
cpuRegs.code = *(u32 *)PSM(cpuRegs.pc); cpuRegs.code = *(u32 *)PSM(cpuRegs.pc);
#endif #endif
cpuRegs.pc+= 4; const EE::OPCODE& opcode = EE::GetCurrentInstruction();
Int_OpcodePrintTable[cpuRegs.code >> 26]();
/*disOut.assign( "\n" );
opcode.decode( disOut );
SysPrintf( disOut.c_str() );*/
cpuBlockCycles += opcode.cycles;
//cpuRegs.cycle++;
cpuRegs.pc += 4;
opcode.interpret();
} }
static void doBranch(u32 tar) { static void doBranch(u32 tar) {
@ -113,6 +135,8 @@ static void doBranch(u32 tar) {
cpuRegs.branch = 0; cpuRegs.branch = 0;
cpuRegs.pc = branchPC; cpuRegs.pc = branchPC;
cpuRegs.cycle += cpuBlockCycles >> 3;
cpuBlockCycles &= (1<<3)-1;
IntcpuBranchTest(); IntcpuBranchTest();
} }
@ -125,11 +149,68 @@ void intSetBranch() {
branch2 = 1; branch2 = 1;
} }
void SPECIAL() {Int_SpecialPrintTable[_Funct_]();} //****************************************************************
void REGIMM() {Int_REGIMMPrintTable[_Rt_](); } // Used to manage FPU Opcodes
//****************************************************************
void COP1_BC1() {
Int_COP1BC1PrintTable[_Rt_]();
}
void COP1_S() {
Int_COP1SPrintTable[_Funct_]();
}
void COP1_W() {
Int_COP1WPrintTable[_Funct_]();
}
void COP1_Unknown() {
FPU_LOG("Unknown FPU opcode called\n");
}
void UnknownOpcode() { namespace EE { namespace Opcodes
{
const OPCODE& Class_SPECIAL() { return EE::OpcodeTables::Special[_Funct_]; }
const OPCODE& Class_REGIMM() { return EE::OpcodeTables::RegImm[_Rt_]; }
const OPCODE& Class_MMI() { return EE::OpcodeTables::MMI[_Funct_]; }
const OPCODE& Class_MMI0() { return EE::OpcodeTables::MMI0[_Sa_]; }
const OPCODE& Class_MMI1() { return EE::OpcodeTables::MMI1[_Sa_]; }
const OPCODE& Class_MMI2() { return EE::OpcodeTables::MMI2[_Sa_]; }
const OPCODE& Class_MMI3() { return EE::OpcodeTables::MMI3[_Sa_]; }
//const OPCODE& Class_COP0() { return EE::OpcodeTables::COP1[_Rs_]; }
//const OPCODE& Class_COP1() { return EE::OpcodeTables::COP1[_Rs_]; }
//const OPCODE& Class_COP2() { return EE::OpcodeTables::COP2[_Rs_]; }
} }
namespace EE { namespace Interpreter { namespace OpcodeImpl
{
void COP0()
{
Int_COP0PrintTable[_Rs_]();
}
void COP1()
{
FPU_LOG("%s\n", disR5900Current.getString() );
Int_COP1PrintTable[_Rs_]();
}
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); CPU_LOG("%8.8lx: Unknown opcode called\n", cpuRegs.pc);
} }
@ -385,11 +466,11 @@ void LB() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) { u8 temp;
memRead8RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); const u32 rt=_Rt_;
} else { if ((0==memRead8(addr, &temp)) && (rt!=0))
u64 dummy; {
memRead8RS(addr, &dummy); cpuRegs.GPR.r[rt].UD[0]=(s8)temp;
} }
} }
@ -397,11 +478,11 @@ void LBU() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) { u8 temp;
memRead8RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); const u32 rt=_Rt_;
} else { if ((0==memRead8(addr, &temp)) && (rt!=0))
u64 dummy; {
memRead8RU(addr, &dummy); cpuRegs.GPR.r[rt].UD[0]=temp;
} }
} }
@ -409,11 +490,11 @@ void LH() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) { u16 temp;
memRead16RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); const u32 rt=_Rt_;
} else { if ((0==memRead16(addr, &temp)) && (rt!=0))
u64 dummy; {
memRead16RS(addr, &dummy); cpuRegs.GPR.r[rt].UD[0]=(s16)temp;
} }
} }
@ -421,35 +502,38 @@ void LHU() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) { u16 temp;
memRead16RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); const u32 rt=_Rt_;
} else { if ((0==memRead16(addr, &temp)) && (rt!=0))
u64 dummy; {
memRead16RU(addr, &dummy); cpuRegs.GPR.r[rt].UD[0]=temp;
} }
} }
void LW() { void LW() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead32RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); u32 temp;
} else { const u32 rt=_Rt_;
u64 dummy; if ((0==memRead32(addr, &temp)) && (rt!=0))
memRead32RS(addr, &dummy); {
cpuRegs.GPR.r[rt].UD[0]=(s32)temp;
} }
} }
void LWU() { void LWU() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead32RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]); u32 temp;
} else { const u32 rt=_Rt_;
u64 dummy; if ((0==memRead32(addr, &temp)) && (rt!=0))
memRead32RU(addr, &dummy); {
cpuRegs.GPR.r[rt].UD[0]=temp;
} }
} }
@ -625,7 +709,7 @@ void SD() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
memWrite64(addr,cpuRegs.GPR.r[_Rt_].UD[0]); memWrite64(addr,&cpuRegs.GPR.r[_Rt_].UD[0]);
} }
u64 SDL_MASK[8] = { 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL, u64 SDL_MASK[8] = { 0xffffffffffffff00LL, 0xffffffffffff0000LL, 0xffffffffff000000LL, 0xffffffff00000000LL,
@ -638,9 +722,9 @@ void SDL() {
u64 mem; u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return; if (memRead64(addr & ~7, &mem) == -1) return;
mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
memWrite64(addr & ~7, (cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) | ( mem & SDL_MASK[shift]);
( mem & SDL_MASK[shift]) ); memWrite64(addr & ~7, &mem);
} }
u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL, u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
@ -653,9 +737,9 @@ void SDR() {
u64 mem; u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return; if (memRead64(addr & ~7, &mem) == -1) return;
mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
memWrite64(addr & ~7, (cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) | ( mem & SDR_MASK[shift]);
( mem & SDR_MASK[shift]) ); memWrite64(addr & ~7, &mem );
} }
void SQ() { void SQ() {
@ -929,7 +1013,7 @@ void MTSAH() {
cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4; cpuRegs.sa = ((cpuRegs.GPR.r[_Rs_].UL[0] & 0x7) ^ (_Imm_ & 0x7)) << 4;
} }
} } } // end EE::Interpreter::OpcodeImpl namespace
/////////////////////////////////////////// ///////////////////////////////////////////

View File

@ -17,36 +17,16 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "Common.h" #include "Common.h"
#include "DebugTools/Debug.h" #include "DebugTools/Debug.h"
#include "R5900.h" #include "R5900.h"
#include "InterTables.h" #include "InterTables.h"
namespace EE { namespace Interpreter{ namespace OpcodeImpl
{
void MMI() { void MMI_Unknown() { SysPrintf ("Unknown MMI opcode called\n"); }
MMI_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc));
Int_MMIPrintTable[_Funct_]();
}
void MMI0() {
Int_MMI0PrintTable[_Sa_]();
}
void MMI1() {
Int_MMI1PrintTable[_Sa_]();
}
void MMI2() {
Int_MMI2PrintTable[_Sa_]();
}
void MMI3() {
Int_MMI3PrintTable[_Sa_]();
}
void MMI_Unknown() {
SysPrintf ("Unknown MMI opcode called\n");
}
//*****************MMI OPCODES********************************* //*****************MMI OPCODES*********************************
@ -1564,3 +1544,4 @@ void PEXCW() {
// obs: // obs:
// QFSRV not verified // QFSRV not verified
}}} // end namespace EE::Interpreter::OpcodeImpl

File diff suppressed because it is too large Load Diff

View File

@ -66,6 +66,23 @@ struct PSMEMORYMAP
#define PSM(mem) (PS2MEM_BASE + TRANSFORM_ADDR(mem)) #define PSM(mem) (PS2MEM_BASE + TRANSFORM_ADDR(mem))
int memRead8(u32 mem, u8 *out);
int memRead8RS(u32 mem, u64 *out);
int memRead8RU(u32 mem, u64 *out);
int memRead16(u32 mem, u16 *out);
int memRead16RS(u32 mem, u64 *out);
int memRead16RU(u32 mem, u64 *out);
int memRead32(u32 mem, u32 *out);
int memRead32RS(u32 mem, u64 *out);
int memRead32RU(u32 mem, u64 *out);
int memRead64(u32 mem, u64 *out);
int memRead128(u32 mem, u64 *out);
void memWrite8 (u32 mem, u8 value);
void memWrite16(u32 mem, u16 value);
void memWrite32(u32 mem, u32 value);
void memWrite64(u32 mem, const u64 *value);
void memWrite128(u32 mem, const u64 *value);
#else #else
extern u8 *psM; //32mb Main Ram extern u8 *psM; //32mb Main Ram
@ -87,16 +104,9 @@ extern u8 g_RealGSMem[0x2000];
#define PS2MEM_GS g_RealGSMem #define PS2MEM_GS g_RealGSMem
//#define _PSM(mem) (memLUTR[(mem) >> 12] == 0 ? NULL : (void*)(memLUTR[(mem) >> 12] + ((mem) & 0xfff))) //#define _PSM(mem) (memLUTR[(mem) >> 12] == 0 ? NULL : (void*)(memLUTR[(mem) >> 12] + ((mem) & 0xfff)))
#define PSM(mem) ((void*)(memLUTR[(mem) >> 12] + ((mem) & 0xfff))) #define PSM(mem) (vtlb_GetPhyPtr(mem&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D
#define FREE(ptr) _aligned_free(ptr) #define FREE(ptr) _aligned_free(ptr)
extern uptr *memLUTR;
extern uptr *memLUTW;
extern uptr *memLUTRK;
extern uptr *memLUTWK;
extern uptr *memLUTRU;
extern uptr *memLUTWU;
#endif #endif
#define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
@ -171,23 +181,6 @@ void memSetPageAddr(u32 vaddr, u32 paddr);
void memClearPageAddr(u32 vaddr); void memClearPageAddr(u32 vaddr);
void memShutdown(); void memShutdown();
int memRead8(u32 mem, u8 *out);
int memRead8RS(u32 mem, u64 *out);
int memRead8RU(u32 mem, u64 *out);
int memRead16(u32 mem, u16 *out);
int memRead16RS(u32 mem, u64 *out);
int memRead16RU(u32 mem, u64 *out);
int memRead32(u32 mem, u32 *out);
int memRead32RS(u32 mem, u64 *out);
int memRead32RU(u32 mem, u64 *out);
int memRead64(u32 mem, u64 *out);
int memRead128(u32 mem, u64 *out);
void memWrite8 (u32 mem, u8 value);
void memWrite16(u32 mem, u16 value);
void memWrite32(u32 mem, u32 value);
void memWrite64(u32 mem, u64 value);
void memWrite128(u32 mem, u64 *value);
// recMemConstRead8, recMemConstRead16, recMemConstRead32 return 1 if a call was made, 0 otherwise // recMemConstRead8, recMemConstRead16, recMemConstRead32 return 1 if a call was made, 0 otherwise
u8 recMemRead8(); u8 recMemRead8();
u16 recMemRead16(); u16 recMemRead16();
@ -202,39 +195,37 @@ void recMemWrite32();
void recMemWrite64(); void recMemWrite64();
void recMemWrite128(); void recMemWrite128();
// VM only functions int SysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps);
#ifdef PCSX2_VIRTUAL_MEM
void _eeReadConstMem8(int mmreg, u32 mem, int sign); #ifndef PCSX2_VIRTUAL_MEM
void _eeReadConstMem16(int mmreg, u32 mem, int sign); #include "vtlb.h"
void _eeReadConstMem32(int mmreg, u32 mem);
void _eeReadConstMem128(int mmreg, u32 mem);
void _eeWriteConstMem8(u32 mem, int mmreg);
void _eeWriteConstMem16(u32 mem, int mmreg);
void _eeWriteConstMem32(u32 mem, int mmreg);
void _eeWriteConstMem64(u32 mem, int mmreg);
void _eeWriteConstMem128(u32 mem, int mmreg);
void _eeMoveMMREGtoR(int to, int mmreg);
// extra ops int mmap_GetRamPageInfo(void* ptr);
void _eeWriteConstMem16OP(u32 mem, int mmreg, int op); void mmap_MarkCountedRamPage(void* ptr,u32 vaddr);
void _eeWriteConstMem32OP(u32 mem, int mmreg, int op); void mmap_ResetBlockTracking();
int recMemConstRead8(u32 x86reg, u32 mem, u32 sign); int __fastcall _memRead8(u32 mem, u8 *out);
int recMemConstRead16(u32 x86reg, u32 mem, u32 sign); int __fastcall _memRead16(u32 mem, u16 *out);
int recMemConstRead32(u32 x86reg, u32 mem); int __fastcall _memRead32(u32 mem, u32 *out);
void recMemConstRead64(u32 mem, int mmreg); int __fastcall _memRead64(u32 mem, u64 *out);
void recMemConstRead128(u32 mem, int xmmreg); int __fastcall _memRead128(u32 mem, u64 *out);
void __fastcall _memWrite8 (u32 mem, u8 value);
void __fastcall _memWrite16(u32 mem, u16 value);
void __fastcall _memWrite32(u32 mem, u32 value);
void __fastcall _memWrite64(u32 mem, u64 value);
void __fastcall _memWrite128(u32 mem, u64 *value);
int recMemConstWrite8(u32 mem, int mmreg); #define memRead8 vtlb_memRead8
int recMemConstWrite16(u32 mem, int mmreg); #define memRead16 vtlb_memRead16
int recMemConstWrite32(u32 mem, int mmreg); #define memRead32 vtlb_memRead32
int recMemConstWrite64(u32 mem, int mmreg); #define memRead64 vtlb_memRead64
int recMemConstWrite128(u32 mem, int xmmreg); #define memRead128 vtlb_memRead128
extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps); #define memWrite8 vtlb_memWrite8
#define memWrite16 vtlb_memWrite16
#else #define memWrite32 vtlb_memWrite32
#define memWrite64 vtlb_memWrite64
#define memWrite128 vtlb_memWrite128
#define _eeReadConstMem8 0&& #define _eeReadConstMem8 0&&
#define _eeReadConstMem16 0&& #define _eeReadConstMem16 0&&
@ -263,6 +254,38 @@ extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps);
#define recMemConstWrite64 0&& #define recMemConstWrite64 0&&
#define recMemConstWrite128 0&& #define recMemConstWrite128 0&&
#else // PCSX2_VIRTUAL_MEM
// VM only functions
void _eeReadConstMem8(int mmreg, u32 mem, int sign);
void _eeReadConstMem16(int mmreg, u32 mem, int sign);
void _eeReadConstMem32(int mmreg, u32 mem);
void _eeReadConstMem128(int mmreg, u32 mem);
void _eeWriteConstMem8(u32 mem, int mmreg);
void _eeWriteConstMem16(u32 mem, int mmreg);
void _eeWriteConstMem32(u32 mem, int mmreg);
void _eeWriteConstMem64(u32 mem, int mmreg);
void _eeWriteConstMem128(u32 mem, int mmreg);
void _eeMoveMMREGtoR(int to, int mmreg);
// extra ops
void _eeWriteConstMem16OP(u32 mem, int mmreg, int op);
void _eeWriteConstMem32OP(u32 mem, int mmreg, int op);
int recMemConstRead8(u32 x86reg, u32 mem, u32 sign);
int recMemConstRead16(u32 x86reg, u32 mem, u32 sign);
int recMemConstRead32(u32 x86reg, u32 mem);
void recMemConstRead64(u32 mem, int mmreg);
void recMemConstRead128(u32 mem, int xmmreg);
int recMemConstWrite8(u32 mem, int mmreg);
int recMemConstWrite16(u32 mem, int mmreg);
int recMemConstWrite32(u32 mem, int mmreg);
int recMemConstWrite64(u32 mem, int mmreg);
int recMemConstWrite128(u32 mem, int xmmreg);
#endif #endif
#endif #endif

View File

@ -39,12 +39,11 @@
#include "iVUzerorec.h" #include "iVUzerorec.h"
#include "GS.h" #include "GS.h"
#include "COP0.h"
#include "Cache.h" #include "Cache.h"
#include "Paths.h" #include "Paths.h"
u32 dwSaveVersion = 0x7a300010;
u32 dwCurSaveStateVer = 0; u32 dwCurSaveStateVer = 0;
extern u32 s_iLastCOP0Cycle; extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2]; extern u32 s_iLastPERFCycle[2];
@ -397,7 +396,7 @@ int connected=0;
void __Log(const char *fmt, ...) { void __Log(const char *fmt, ...) {
#ifdef EMU_LOG #ifdef EMU_LOG
va_list list; va_list list;
static char tmp[2024]; //hm, should be enough char tmp[2024]; //hm, should be enough
va_start(list, fmt); va_start(list, fmt);
#ifdef _WIN32 #ifdef _WIN32
@ -475,7 +474,7 @@ int SaveState(const char *file) {
f = gzopen(file, "wb"); f = gzopen(file, "wb");
if (f == NULL) return -1; if (f == NULL) return -1;
gzwrite(f, &dwSaveVersion, 4); gzwrite(f, &g_SaveVersion, 4);
gzwrite(f, PS2MEM_BASE, 0x02000000); // 32 MB main memory gzwrite(f, PS2MEM_BASE, 0x02000000); // 32 MB main memory
gzwrite(f, PS2MEM_ROM, 0x00400000); // 4 mb rom memory gzwrite(f, PS2MEM_ROM, 0x00400000); // 4 mb rom memory
@ -488,19 +487,17 @@ int SaveState(const char *file) {
gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); // iop regs] gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); // iop regs]
gzwrite(f, (void*)&fpuRegs, sizeof(fpuRegs)); // fpu regs gzwrite(f, (void*)&fpuRegs, sizeof(fpuRegs)); // fpu regs
gzwrite(f, (void*)&tlb, sizeof(tlb)); // tlbs gzwrite(f, (void*)&tlb, sizeof(tlb)); // tlbs
gzwrite(f, &EEsCycle, sizeof(EEsCycle)); gzwrite(f, &EEsCycle, sizeof(EEsCycle));
gzwrite(f, &EEoCycle, sizeof(EEoCycle)); gzwrite(f, &EEoCycle, sizeof(EEoCycle));
gzwrite(f, &psxRegs.cycle, sizeof(u32)); // used to be IOPoCycle. This retains compatibility. gzwrite(f, &psxRegs.cycle, sizeof(u32)); // used to be IOPoCycle. This retains compatibility.
gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle)); gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
gzwrite(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle)); gzwrite(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
// [TODO] These following two lines to be addedlater in a new savestate version.
//gzwrite(f, &psxNextsCounter, sizeof(psxNextsCounter));
//gzwrite(f, &psxNextsCounter, sizeof(psxNextsCounter));
gzwrite(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle)); gzwrite(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
gzwrite(f, s_iLastPERFCycle, sizeof(u32)*2); gzwrite(f, s_iLastPERFCycle, sizeof(u32)*2);
gzwrite(f, &g_psxWriteOk, sizeof(g_psxWriteOk)); gzwrite(f, &g_psxWriteOk, sizeof(g_psxWriteOk));
//gzwrite(f, (void*)&ipuRegs, sizeof(IPUregisters)); // ipu regs
//hope didn't forgot any cpu.... //hope didn't forgot any cpu....
rcntFreeze(f, 1); rcntFreeze(f, 1);
@ -571,20 +568,28 @@ int LoadState(const char *file) {
gzread(f, &dwCurSaveStateVer, 4); gzread(f, &dwCurSaveStateVer, 4);
if( dwCurSaveStateVer != dwSaveVersion ) { if( dwCurSaveStateVer != g_SaveVersion ) {
// pcsx2 supports opening these formats #ifdef PCSX2_VIRTUAL_MEM
// pcsx2 vm supports opening these formats
if( dwCurSaveStateVer != 0x7a30000d && dwCurSaveStateVer != 0x7a30000e && dwCurSaveStateVer != 0x7a30000f) { if( dwCurSaveStateVer != 0x7a30000d && dwCurSaveStateVer != 0x7a30000e && dwCurSaveStateVer != 0x7a30000f) {
gzclose(f); gzclose(f);
SysPrintf("State to load is a different version from current.\n"); SysPrintf("Unsupported savestate version: %x.\n", dwCurSaveStateVer );
return 0; return 0;
} }
#else
gzclose(f);
SysPrintf(
"Savestate load aborted:\n"
" vTlb edition cannot safely load savestates created by the VM edition.\n" );
return 0;
#endif
} }
// stop and reset the system first // stop and reset the system first
gsWaitGS(); gsWaitGS();
for (i=0; i<48; i++) ClearTLB(i); for (i=0; i<48; i++) UnmapTLB(i);
Cpu->Reset(); Cpu->Reset();
#ifndef PCSX2_NORECBUILD #ifndef PCSX2_NORECBUILD
@ -627,9 +632,7 @@ int LoadState(const char *file) {
gzread(f, &dud, sizeof(u32)); // was IOPoCycle gzread(f, &dud, sizeof(u32)); // was IOPoCycle
gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle)); gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
gzread(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle)); gzread(f, &g_psxNextBranchCycle, sizeof(g_psxNextBranchCycle));
// [TODO] these following 2 lines to be added later in a new savestate version
//gzread(f, &psxNextsCounter, sizeof(psxNextsCounter));
//gzread(f, &psxNextCounter, sizeof(psxNextsCounter));
gzread(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle)); gzread(f, &s_iLastCOP0Cycle, sizeof(s_iLastCOP0Cycle));
if( dwCurSaveStateVer >= 0x7a30000e ) { if( dwCurSaveStateVer >= 0x7a30000e ) {
gzread(f, s_iLastPERFCycle, sizeof(u32)*2); gzread(f, s_iLastPERFCycle, sizeof(u32)*2);
@ -684,7 +687,7 @@ int LoadState(const char *file) {
//dumplog |= 4; //dumplog |= 4;
WriteCP0Status(cpuRegs.CP0.n.Status.val); WriteCP0Status(cpuRegs.CP0.n.Status.val);
for (i=0; i<48; i++) WriteTLB(i); for (i=0; i<48; i++) MapTLB(i);
return 0; return 0;
} }

View File

@ -137,18 +137,24 @@ extern PcsxConfig Config;
extern u32 BiosVersion; extern u32 BiosVersion;
extern char CdromId[12]; extern char CdromId[12];
#define gzfreeze(ptr, size) \
if (Mode == 1) gzwrite(f, ptr, size); \
else if (Mode == 0) gzread(f, ptr, size);
#define gzfreezel(ptr) gzfreeze(ptr, sizeof(ptr))
int LoadCdrom(); int LoadCdrom();
int CheckCdrom(); int CheckCdrom();
int GetPS2ElfName(char*); int GetPS2ElfName(char*);
extern const char *LabelAuthors; extern const char *LabelAuthors;
extern const char *LabelGreets; extern const char *LabelGreets;
// --->> Savestate stuff [PathUtil.c]
// Savestate Versioning!
// If you make changes to the savestate version, please increment the value below.
#ifdef PCSX2_VIRTUAL_MEM
static const u32 g_SaveVersion = 0x7a300010;
#else
static const u32 g_SaveVersion = 0x8b400000;
#endif
int SaveState(const char *file); int SaveState(const char *file);
int LoadState(const char *file); int LoadState(const char *file);
int CheckState(const char *file); int CheckState(const char *file);
@ -156,6 +162,14 @@ int CheckState(const char *file);
int SaveGSState(const char *file); int SaveGSState(const char *file);
int LoadGSState(const char *file); int LoadGSState(const char *file);
#define gzfreeze(ptr, size) \
if (Mode == 1) gzwrite(f, ptr, size); \
else if (Mode == 0) gzread(f, ptr, size);
#define gzfreezel(ptr) gzfreeze(ptr, sizeof(ptr))
// <<--- End Savestate Stuff
char *ParseLang(char *id); char *ParseLang(char *id);
void ProcessFKeys(int fkey, int shift); // processes fkey related commands value 1-12 void ProcessFKeys(int fkey, int shift); // processes fkey related commands value 1-12
@ -249,6 +263,8 @@ void FreezeMMXRegs_(int save);
#if defined(_WIN32) && !defined(__x86_64__) #if defined(_WIN32) && !defined(__x86_64__)
// faster memcpy // faster memcpy
void __fastcall memcpy_raz_u(void *dest, const void *src, size_t bytes);
void __fastcall memcpy_raz_(void *dest, const void *src, size_t qwc);
void * memcpy_amd_(void *dest, const void *src, size_t n); void * memcpy_amd_(void *dest, const void *src, size_t n);
#define memcpy_fast memcpy_amd_ #define memcpy_fast memcpy_amd_
//#define memcpy_fast memcpy //Dont use normal memcpy, it has sse in 2k5! //#define memcpy_fast memcpy //Dont use normal memcpy, it has sse in 2k5!
@ -295,9 +311,6 @@ static __forceinline void pcsx2_aligned_free(void* pmem)
#define _aligned_malloc pcsx2_aligned_malloc #define _aligned_malloc pcsx2_aligned_malloc
#define _aligned_free pcsx2_aligned_free #define _aligned_free pcsx2_aligned_free
// This might work, too; I'll have to test the two, and see if it makes a difference.
//#define _aligned_malloc(size,align) memalign(align, size)
//#define _aligned_free free
#endif #endif
// cross-platform atomic operations // cross-platform atomic operations

View File

@ -44,6 +44,7 @@ typedef unsigned __int16 u16;
typedef unsigned __int32 u32; typedef unsigned __int32 u32;
typedef unsigned __int64 u64; typedef unsigned __int64 u64;
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x #define PCSX2_ALIGNED16(x) __declspec(align(16)) x
#define PCSX2_ALIGNED16_DECL(x) __declspec(align(16)) x #define PCSX2_ALIGNED16_DECL(x) __declspec(align(16)) x

View File

@ -128,7 +128,7 @@ void _applypatch(int place, IniPatch *p) {
if (p->enabled == 0) return; if (p->enabled == 0) return;
switch (p->cpu) { switch (p->cpu) {
case EE: case CPU_EE:
switch (p->type) { switch (p->type) {
case BYTE_T: case BYTE_T:
memWrite8(p->addr, (u8)p->data); memWrite8(p->addr, (u8)p->data);
@ -140,7 +140,7 @@ void _applypatch(int place, IniPatch *p) {
memWrite32(p->addr, (u32)p->data); memWrite32(p->addr, (u32)p->data);
break; break;
case DOUBLE_T: case DOUBLE_T:
memWrite64(p->addr, p->data); memWrite64(p->addr, &p->data);
break; break;
case EXTENDED_T: case EXTENDED_T:
if (SkipCount > 0){ if (SkipCount > 0){
@ -327,7 +327,7 @@ void _applypatch(int place, IniPatch *p) {
} }
} }
break; break;
case IOP: { case CPU_IOP: {
switch (p->type) { switch (p->type) {
case BYTE_T: case BYTE_T:
psxMemWrite8(p->addr, (u8)p->data); psxMemWrite8(p->addr, (u8)p->data);
@ -579,7 +579,7 @@ void patchFunc_fastmemory( char * cmd, char * param )
{ {
#ifndef PCSX2_NORECBUILD #ifndef PCSX2_NORECBUILD
// only valid for recompilers // only valid for recompilers
SetFastMemory(1); EE::Dynarec::SetFastMemory(1);
#endif #endif
} }

View File

@ -43,9 +43,10 @@
enum patch_cpu_type { enum patch_cpu_type {
NO_CPU, NO_CPU,
EE, CPU_EE,
IOP CPU_IOP
}; };
enum patch_data_type { enum patch_data_type {
NO_TYPE, NO_TYPE,
BYTE_T, BYTE_T,
@ -128,7 +129,10 @@ void resetpatch( void );
int AddPatch(int Mode, int Place, int Address, int Size, u64 data); int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
void SetFastMemory(int); // iR5900LoadStore.c namespace EE { namespace Dynarec {
void SetFastMemory(int); // iR5900LoadStore.c
} }
void SetVUNanMemory(int); // iVUmicro.c void SetVUNanMemory(int); // iVUmicro.c
extern void SetVUNanMode(int mode); extern void SetVUNanMode(int mode);

View File

@ -710,7 +710,8 @@ u64 psxRcntCycles(int index)
extern u32 dwCurSaveStateVer; extern u32 dwCurSaveStateVer;
int psxRcntFreeze(gzFile f, int Mode) int psxRcntFreeze(gzFile f, int Mode)
{ {
if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) ) #ifdef PCSX2_VIRTUAL_MEM
if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) )
{ {
// --- Reading Mode, Old Version --- // --- Reading Mode, Old Version ---
// struct used to be 32bit count and target // struct used to be 32bit count and target
@ -751,6 +752,12 @@ int psxRcntFreeze(gzFile f, int Mode)
psxNextCounter = 0; psxNextCounter = 0;
psxNextsCounter = psxRegs.cycle; psxNextsCounter = psxRegs.cycle;
} }
#else
gzfreezel(psxCounters);
gzfreeze(&psxNextCounter, sizeof(psxNextCounter));
gzfreeze(&psxNextsCounter, sizeof(psxNextsCounter));
#endif
return 0; return 0;
} }

View File

@ -883,7 +883,7 @@ void psxHwWrite32(u32 add, u32 value) {
case 0x1f801078: case 0x1f801078:
PSXHW_LOG("ICTRL 32bit write %lx\n", value); PSXHW_LOG("ICTRL 32bit write %lx\n", value);
psxHu32(0x1078) = value; psxHu32(0x1078) = value;//1; //According to pSXAuthor this allways becomes 1 on write, but MHPB won't boot if value is not writen ;p
return; return;
//SSBus registers //SSBus registers

View File

@ -43,13 +43,11 @@ s32 EEsCycle; // used to sync the IOP to the EE
u32 EEoCycle; u32 EEoCycle;
u32 bExecBIOS = 0; // set if the BIOS has already been executed u32 bExecBIOS = 0; // set if the BIOS has already been executed
extern u32 dwSaveVersion;
int cpuInit() int cpuInit()
{ {
int ret; int ret;
SysPrintf("PCSX2 " PCSX2_VERSION " save ver: %x\n", dwSaveVersion); SysPrintf("PCSX2 " PCSX2_VERSION " save ver: %x\n", g_SaveVersion);
SysPrintf("EE pc offset: 0x%x, PSX pc offset: 0x%x\n", (u32)&cpuRegs.pc - (u32)&cpuRegs, (u32)&psxRegs.pc - (u32)&psxRegs); SysPrintf("EE pc offset: 0x%x, PSX pc offset: 0x%x\n", (u32)&cpuRegs.pc - (u32)&cpuRegs, (u32)&psxRegs.pc - (u32)&psxRegs);
cpuRegs.constzero = 0; cpuRegs.constzero = 0;
@ -220,7 +218,7 @@ void cpuException(u32 code, u32 bd) {
} }
void cpuTlbMiss(u32 addr, u32 bd, u32 excode) { void cpuTlbMiss(u32 addr, u32 bd, u32 excode) {
SysPrintf("cpuTlbMiss %x, %x, addr: %x, status=%x, code=%x\n", cpuRegs.pc, cpuRegs.cycle, addr, cpuRegs.CP0.n.Status.val, excode); SysPrintf("cpuTlbMiss pc:%x, cycl:%x, addr: %x, status=%x, code=%x\n", cpuRegs.pc, cpuRegs.cycle, addr, cpuRegs.CP0.n.Status.val, excode);
if (bd) { if (bd) {
SysPrintf("branch delay!!\n"); SysPrintf("branch delay!!\n");
} }

View File

@ -170,8 +170,8 @@ struct fpuRegisters {
extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs); extern PCSX2_ALIGNED16_DECL(fpuRegisters fpuRegs);
struct tlbs
struct tlbs { {
u32 PageMask,EntryHi; u32 PageMask,EntryHi;
u32 EntryLo0,EntryLo1; u32 EntryLo0,EntryLo1;
u32 Mask, nMask; u32 Mask, nMask;
@ -180,6 +180,9 @@ struct tlbs {
u32 VPN2; u32 VPN2;
u32 PFN0; u32 PFN0;
u32 PFN1; u32 PFN1;
#ifndef PCSX2_VIRTUAL_MEM
u32 S;
#endif
}; };
extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]); extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]);
@ -198,7 +201,7 @@ extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]);
#define _i8(x) (s8)x #define _i8(x) (s8)x
#define _u8(x) (u8)x #define _u8(x) (u8)x
/**** R3000A Instruction Macros ****/ /**** R5900 Instruction Macros ****/
#define _PC_ cpuRegs.pc // The next PC to be executed #define _PC_ cpuRegs.pc // The next PC to be executed
#define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register #define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register
@ -213,9 +216,7 @@ extern PCSX2_ALIGNED16_DECL(tlbs tlb[48]);
#define _ImmU_ (cpuRegs.code&0xffff) // zero-extended immediate #define _ImmU_ (cpuRegs.code&0xffff) // zero-extended immediate
#define _ImmSB_ (cpuRegs.code&0x8000) // gets the sign-bit of the immediate value #define _ImmSB_ (cpuRegs.code&0x8000) // gets the sign-bit of the immediate value
#define _Opcode_ (cpuRegs.code >> 26 )
//#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
//#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction
#define _JumpTarget_ ((_Target_ << 2) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction #define _JumpTarget_ ((_Target_ << 2) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction
#define _BranchTarget_ (((s32)(s16)_Im_ * 4) + _PC_) // Calculates the target during a branch instruction #define _BranchTarget_ (((s32)(s16)_Im_ * 4) + _PC_) // Calculates the target during a branch instruction

31
pcsx2/SamplProf.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef _SAMPLPROF_H_
#define _SAMPLPROF_H_
#include "common.h"
// The profiler does not have a Linux version yet.
// So for now we turn it into duds for non-Win32 platforms.
#if !defined( _DEBUG ) || !defined( WIN32 )
void ProfilerInit();
void ProfilerTerm();
void ProfilerSetEnabled(bool Enabled);
void ProfilerRegisterSource(const char* Name,void* buff,u32 sz);
void ProfilerRegisterSource(const char* Name,void* function);
#else
// Disables the profiler in Debug builds.
// Profiling info in debug builds isn't much use anyway and the console
// popups are annoying when you're trying to trace debug logs and stuff.
#define ProfilerInit()
#define ProfilerTerm()
#define ProfilerSetEnabled 0&&
#define ProfilerRegisterSource 0&&
#define ProfilerRegisterSource 0&&
#endif
#endif

View File

@ -45,7 +45,7 @@ void statsClose() {
f = fopen(LOGS_DIR "/stats.txt", "w"); f = fopen(LOGS_DIR "/stats.txt", "w");
#endif #endif
if (!f) { SysPrintf("Can't open stats.txt\n"); return; } if (!f) { SysPrintf("Can't open stats.txt\n"); return; }
fprintf(f, "-- PCSX2 %s statics--\n\n", PCSX2_VERSION); fprintf(f, "-- PCSX2 v%s statics--\n\n", PCSX2_VERSION);
fprintf(f, "Ran for %d seconds\n", t); fprintf(f, "Ran for %d seconds\n", t);
fprintf(f, "Total VSyncs: %d (%s)\n", stats.vsyncCount, Config.PsxType ? "PAL" : "NTSC"); fprintf(f, "Total VSyncs: %d (%s)\n", stats.vsyncCount, Config.PsxType ? "PAL" : "NTSC");
#ifndef __x86_64__ #ifndef __x86_64__

View File

@ -27,6 +27,8 @@
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
#include "Common.h" #include "Common.h"
#include "DebugTools/Debug.h" #include "DebugTools/Debug.h"
#include "R5900.h" #include "R5900.h"
@ -50,11 +52,6 @@
PCSX2_ALIGNED16(VURegs VU0); PCSX2_ALIGNED16(VURegs VU0);
void COP2() {
VU0_LOG("%s\n", disR5900Fasm(cpuRegs.code, cpuRegs.pc));
Int_COP2PrintTable[_Rs_]();
}
void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();} void COP2_BC2() { Int_COP2BC2PrintTable[_Rt_]();}
void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();} void COP2_SPECIAL() { Int_COP2SPECIAL1PrintTable[_Funct_]();}
@ -67,23 +64,28 @@ void COP2_Unknown()
CPU_LOG("Unknown COP2 opcode called\n"); CPU_LOG("Unknown COP2 opcode called\n");
} }
void LQC2() { namespace EE{ namespace Interpreter{ namespace OpcodeImpl
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code; {
if (_Ft_) { void LQC2() {
memRead128(addr, &VU0.VF[_Ft_].UD[0]); u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
} else { if (_Ft_) {
u64 val[2]; memRead128(addr, &VU0.VF[_Ft_].UD[0]);
memRead128(addr, val); } else {
u64 val[2];
memRead128(addr, val);
}
} }
}
// Asadr.Changed
void SQC2() {
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
memWrite64(addr, VU0.VF[_Ft_].UD[0]);
memWrite64(addr+8,VU0.VF[_Ft_].UD[1]);
}
// Asadr.Changed
//TODO: check this
// HUH why ? doesn;t make any sense ...
void SQC2() {
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
//memWrite64(addr, VU0.VF[_Ft_].UD[0]);
//memWrite64(addr+8,VU0.VF[_Ft_].UD[1]);
memWrite128(addr, &VU0.VF[_Ft_].UD[0]);
}
}}}
//**************************************************************************** //****************************************************************************
void _vu0WaitMicro() { void _vu0WaitMicro() {

View File

@ -1672,11 +1672,10 @@ static int Vif1TransDirectHL(u32 *data){
u8* gsmem = GSRingBufCopy(ret<<2, GS_RINGTYPE_P2); u8* gsmem = GSRingBufCopy(ret<<2, GS_RINGTYPE_P2);
if( gsmem != NULL ) { if( gsmem != NULL ) {
FreezeMMXRegs(1); //unaligned copy.VIF handling is -very- messy, so i'l use this code til i fix it :)
memcpy_fast(gsmem, data, ret<<2); memcpy_raz_u(gsmem,data,ret<<2);
FreezeMMXRegs(0);
GSgifTransferDummy(1, data, ret>>2);
GSRINGBUF_DONECOPY(gsmem, ret<<2); GSRINGBUF_DONECOPY(gsmem, ret<<2);
GSgifTransferDummy(1, data, ret>>2);
} }
} }
else { else {

725
pcsx2/vtlb.cpp Normal file
View File

@ -0,0 +1,725 @@
/*
EE physical map :
[0000 0000,1000 0000) -> Ram (mirrored ?)
[1000 0000,1400 0000) -> Registers
[1400 0000,1fc0 0000) -> Reserved (ingored writes, 'random' reads)
[1fc0 0000,2000 0000) -> Boot ROM
[2000 0000,4000 0000) -> Unmapped (BUS ERROR)
[4000 0000,8000 0000) -> "Extended memory", probably unmapped (BUS ERROR) on retail ps2's :)
[8000 0000,FFFF FFFF] -> Unmapped (BUS ERROR)
vtlb/phy only supports the [0000 0000,2000 0000) region, with 4k pages.
vtlb/vmap supports mapping to either of these locations, or some other (externaly) specified address.
*/
#ifndef PCSX2_VIRTUAL_MEM
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/stat.h>
#include "Common.h"
#include "vtlb.h"
#include <..\..\x86\ix86\ix86.h>
#define verify(x) {if (!(x)) { (*(u8*)0)=3; }}
const u32 VTLB_PAGE_BITS =12;
const u32 VTLB_PAGE_MASK=(4095);
const u32 VTLB_PAGE_SIZE=(4096);
const u32 VTLB_PMAP_ITEMS=(0x20000000/VTLB_PAGE_SIZE);
const u32 VTLB_PMAP_SZ=0x20000000;
const u32 VTLB_VMAP_ITEMS=(0x100000000/VTLB_PAGE_SIZE);
s32 pmap[VTLB_PMAP_ITEMS]; //512KB
s32 vmap[VTLB_VMAP_ITEMS]; //4MB
//5 -> one for each size
//2 -> read/write
//
void* RWFT[5][2][128];
vtlbHandler vtlbHandlerCount=0;
vtlbHandler DefaultPhyHandler;
vtlbHandler UnmappedVirtHandler0;
vtlbHandler UnmappedVirtHandler1;
vtlbHandler UnmappedPhyHandler0;
vtlbHandler UnmappedPhyHandler1;
template<int typ,bool Write>
struct TemplateHelper
{
};
template<>
struct TemplateHelper<8,false>
{
static const int sidx=0;
typedef vltbMemR8FP HandlerType;
};
template<>
struct TemplateHelper<8,true>
{
static const int sidx=0;
typedef vltbMemW8FP HandlerType;
};
template<>
struct TemplateHelper<16,false>
{
static const int sidx=1;
typedef vltbMemR16FP HandlerType;
};
template<>
struct TemplateHelper<16,true>
{
static const int sidx=1;
typedef vltbMemW16FP HandlerType;
};
template<>
struct TemplateHelper<32,false>
{
static const int sidx=2;
typedef vltbMemR32FP HandlerType;
};
template<>
struct TemplateHelper<32,true>
{
static const int sidx=2;
typedef vltbMemW32FP HandlerType;
};
template<>
struct TemplateHelper<64,false>
{
static const int sidx=3;
typedef vltbMemR64FP HandlerType;
};
template<>
struct TemplateHelper<64,true>
{
static const int sidx=3;
typedef vltbMemW64FP HandlerType;
};
template<>
struct TemplateHelper<128,false>
{
static const int sidx=4;
typedef vltbMemR128FP HandlerType;
};
template<>
struct TemplateHelper<128,true>
{
static const int sidx=4;
typedef vltbMemW128FP HandlerType;
};
/*
__asm
{
mov eax,ecx;
shr ecx,12;
mov ecx,[ecx*4+vmap]; //translate
add ecx,eax; //transform
js callfunction; //if <0 its invalid ptr :)
mov eax,[ecx];
mov [edx],eax;
xor eax,eax;
ret;
callfunction:
xchg eax,ecx;
shr eax,12; //get the 'ppn'
//ecx = original addr
//eax = function entry + 0x800000
//edx = data ptr
jmp [readfunctions8-0x800000+eax];
}*/
template<int DataSize,typename DataType>
__forceinline int __fastcall MemOp_r(u32 addr,DataType* data)
{
u32 vmv=vmap[addr>>VTLB_PAGE_BITS];
s32 ppf=addr+vmv;
if (!(ppf<0))
{
data[0]=*reinterpret_cast<DataType*>(ppf);
if (DataSize==128)
data[1]=*reinterpret_cast<DataType*>(ppf+8);
return 0;
}
else
{
//has to: translate, find function, call function
u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr);
return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data);
}
}
template<int DataSize,typename DataType>
__forceinline void __fastcall MemOp_w0(u32 addr,DataType data)
{
u32 vmv=vmap[addr>>VTLB_PAGE_BITS];
s32 ppf=addr+vmv;
if (!(ppf<0))
{
*reinterpret_cast<DataType*>(ppf)=data;
}
else
{
//has to: translate, find function, call function
u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr);
reinterpret_cast<TemplateHelper<DataSize,true>::HandlerType*>(RWFT[TemplateHelper<DataSize,true>::sidx][1][hand])(paddr,data);
}
}
template<int DataSize,typename DataType>
__forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data)
{
verify(DataSize==128 || DataSize==64);
u32 vmv=vmap[addr>>VTLB_PAGE_BITS];
s32 ppf=addr+vmv;
if (!(ppf<0))
{
*reinterpret_cast<DataType*>(ppf)=*data;
if (DataSize==128)
*reinterpret_cast<DataType*>(ppf+8)=data[1];
}
else
{
//has to: translate, find function, call function
u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr);
reinterpret_cast<TemplateHelper<DataSize,true>::HandlerType*>(RWFT[TemplateHelper<DataSize,true>::sidx][1][hand])(paddr,data);
}
}
int __fastcall vtlb_memRead8(u32 mem, u8 *out)
{
return MemOp_r<8,u8>(mem,out);
}
int __fastcall vtlb_memRead16(u32 mem, u16 *out)
{
return MemOp_r<16,u16>(mem,out);
}
int __fastcall vtlb_memRead32(u32 mem, u32 *out)
{
return MemOp_r<32,u32>(mem,out);
}
int __fastcall vtlb_memRead64(u32 mem, u64 *out)
{
return MemOp_r<64,u64>(mem,out);
}
int __fastcall vtlb_memRead128(u32 mem, u64 *out)
{
return MemOp_r<128,u64>(mem,out);
}
void __fastcall vtlb_memWrite8 (u32 mem, u8 value)
{
MemOp_w0<8,u8>(mem,value);
}
void __fastcall vtlb_memWrite16(u32 mem, u16 value)
{
MemOp_w0<16,u16>(mem,value);
}
void __fastcall vtlb_memWrite32(u32 mem, u32 value)
{
MemOp_w0<32,u32>(mem,value);
}
void __fastcall vtlb_memWrite64(u32 mem, const u64* value)
{
MemOp_w1<64,u64>(mem,value);
}
void __fastcall vtlb_memWrite128(u32 mem, const u64 *value)
{
MemOp_w1<128,u64>(mem,value);
}
int vtlb_Miss(u32 addr,u32 mode)
{
SysPrintf("vtlb miss : addr 0x%X, mode %d\n",addr,mode);
verify(false);
if (mode==0)
cpuTlbMissR(addr, cpuRegs.branch);
else
cpuTlbMissW(addr, cpuRegs.branch);
return -1;
}
int vtlb_BusError(u32 addr,u32 mode)
{
SysPrintf("vtlb bus error : addr 0x%X, mode %d\n",addr,mode);
verify(false);
return -1;
}
/////
template<u32 saddr>
int __fastcall vtlbUnmappedVRead8(u32 addr,mem8_t* data) { return vtlb_Miss(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedVRead16(u32 addr,mem16_t* data) { return vtlb_Miss(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedVRead32(u32 addr,mem32_t* data) { return vtlb_Miss(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedVRead64(u32 addr,mem64_t* data) { return vtlb_Miss(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedVRead128(u32 addr,mem128_t* data) { return vtlb_Miss(addr|saddr,0); }
template<u32 saddr>
void __fastcall vtlbUnmappedVWrite8(u32 addr,mem8_t data) { vtlb_Miss(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedVWrite16(u32 addr,mem16_t data) { vtlb_Miss(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedVWrite32(u32 addr,mem32_t data) { vtlb_Miss(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedVWrite64(u32 addr,const mem64_t* data) { vtlb_Miss(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedVWrite128(u32 addr,const mem128_t* data) { vtlb_Miss(addr|saddr,1); }
/////
template<u32 saddr>
int __fastcall vtlbUnmappedPRead8(u32 addr,mem8_t* data) { return vtlb_BusError(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedPRead16(u32 addr,mem16_t* data) { return vtlb_BusError(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedPRead32(u32 addr,mem32_t* data) { return vtlb_BusError(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedPRead64(u32 addr,mem64_t* data) { return vtlb_BusError(addr|saddr,0); }
template<u32 saddr>
int __fastcall vtlbUnmappedPRead128(u32 addr,mem128_t* data) { return vtlb_BusError(addr|saddr,0); }
template<u32 saddr>
void __fastcall vtlbUnmappedPWrite8(u32 addr,mem8_t data) { vtlb_BusError(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedPWrite16(u32 addr,mem16_t data) { vtlb_BusError(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedPWrite32(u32 addr,mem32_t data) { vtlb_BusError(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedPWrite64(u32 addr,const mem64_t* data) { vtlb_BusError(addr|saddr,1); }
template<u32 saddr>
void __fastcall vtlbUnmappedPWrite128(u32 addr,const mem128_t* data) { vtlb_BusError(addr|saddr,1); }
/////
int __fastcall vtlbDefaultPhyRead8(u32 addr,mem8_t* data) { SysPrintf("vtlbDefaultPhyRead8: 0x%X\n",addr); verify(false); return -1; }
int __fastcall vtlbDefaultPhyRead16(u32 addr,mem16_t* data) { SysPrintf("vtlbDefaultPhyRead16: 0x%X\n",addr); verify(false); return -1; }
int __fastcall vtlbDefaultPhyRead32(u32 addr,mem32_t* data) { SysPrintf("vtlbDefaultPhyRead32: 0x%X\n",addr); verify(false); return -1; }
int __fastcall vtlbDefaultPhyRead64(u32 addr,mem64_t* data) { SysPrintf("vtlbDefaultPhyRead64: 0x%X\n",addr); verify(false); return -1; }
int __fastcall vtlbDefaultPhyRead128(u32 addr,mem128_t* data) { SysPrintf("vtlbDefaultPhyRead128: 0x%X\n",addr); verify(false); return -1; }
void __fastcall vtlbDefaultPhyWrite8(u32 addr,mem8_t data) { SysPrintf("vtlbDefaultPhyWrite8: 0x%X\n",addr); verify(false); }
void __fastcall vtlbDefaultPhyWrite16(u32 addr,mem16_t data) { SysPrintf("vtlbDefaultPhyWrite16: 0x%X\n",addr); verify(false); }
void __fastcall vtlbDefaultPhyWrite32(u32 addr,mem32_t data) { SysPrintf("vtlbDefaultPhyWrite32: 0x%X\n",addr); verify(false); }
void __fastcall vtlbDefaultPhyWrite64(u32 addr,const mem64_t* data) { SysPrintf("vtlbDefaultPhyWrite64: 0x%X\n",addr); verify(false); }
void __fastcall vtlbDefaultPhyWrite128(u32 addr,const mem128_t* data) { SysPrintf("vtlbDefaultPhyWrite128: 0x%X\n",addr); verify(false); }
/////
vtlbHandler vtlb_RegisterHandler( vltbMemR8FP* r8,vltbMemR16FP* r16,vltbMemR32FP* r32,vltbMemR64FP* r64,vltbMemR128FP* r128,
vltbMemW8FP* w8,vltbMemW16FP* w16,vltbMemW32FP* w32,vltbMemW64FP* w64,vltbMemW128FP* w128)
{
//write the code :p
vtlbHandler rv=vtlbHandlerCount++;
RWFT[0][0][rv]=r8!=0?r8:vtlbDefaultPhyRead8;
RWFT[1][0][rv]=r16!=0?r16:vtlbDefaultPhyRead16;
RWFT[2][0][rv]=r32!=0?r32:vtlbDefaultPhyRead32;
RWFT[3][0][rv]=r64!=0?r64:vtlbDefaultPhyRead64;
RWFT[4][0][rv]=r128!=0?r128:vtlbDefaultPhyRead128;
RWFT[0][1][rv]=w8!=0?w8:vtlbDefaultPhyWrite8;
RWFT[1][1][rv]=w16!=0?w16:vtlbDefaultPhyWrite16;
RWFT[2][1][rv]=w32!=0?w32:vtlbDefaultPhyWrite32;
RWFT[3][1][rv]=w64!=0?w64:vtlbDefaultPhyWrite64;
RWFT[4][1][rv]=w128!=0?w128:vtlbDefaultPhyWrite128;
return rv;
}
void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size)
{
verify(0==(start&VTLB_PAGE_MASK));
verify(0==(size&VTLB_PAGE_MASK) && size>0);
s32 value=handler|0x80000000;
while(size)
{
pmap[start>>VTLB_PAGE_BITS]=value;
start+=VTLB_PAGE_SIZE;
size-=VTLB_PAGE_SIZE;
}
}
void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize)
{
s32 baseint=(s32)base;
verify(0==(start&VTLB_PAGE_MASK));
verify(0==(size&VTLB_PAGE_MASK) && size>0);
if (blocksize==0)
blocksize=size;
verify(0==(blocksize&VTLB_PAGE_MASK) && blocksize>0);
verify(0==(size%blocksize));
while(size)
{
u32 blocksz=blocksize;
s32 ptr=baseint;
while(blocksz>0)
{
pmap[start>>VTLB_PAGE_BITS]=ptr;
start+=VTLB_PAGE_SIZE;
ptr+=VTLB_PAGE_SIZE;
blocksz-=VTLB_PAGE_SIZE;
size-=VTLB_PAGE_SIZE;
}
}
}
void vtlb_Mirror(u32 new_region,u32 start,u32 size)
{
verify(0==(new_region&VTLB_PAGE_MASK));
verify(0==(start&VTLB_PAGE_MASK));
verify(0==(size&VTLB_PAGE_MASK) && size>0);
while(size)
{
pmap[start>>VTLB_PAGE_BITS]=pmap[new_region>>VTLB_PAGE_BITS];
start+=VTLB_PAGE_SIZE;
new_region+=VTLB_PAGE_SIZE;
size-=VTLB_PAGE_SIZE;
}
}
void* vtlb_GetPhyPtr(u32 paddr)
{
if (paddr>=VTLB_PMAP_SZ || pmap[paddr>>VTLB_PAGE_BITS]<0)
return 0;
else
return reinterpret_cast<void*>(pmap[paddr>>VTLB_PAGE_BITS]+(paddr&VTLB_PAGE_MASK));
}
//virtual mappings
//TODO: Add invalid paddr checks
void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz)
{
verify(0==(vaddr&VTLB_PAGE_MASK));
verify(0==(paddr&VTLB_PAGE_MASK));
verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
while(sz>0)
{
s32 pme;
if (paddr>=VTLB_PMAP_SZ)
{
pme=UnmappedPhyHandler0;
if (paddr&0x80000000)
pme=UnmappedPhyHandler1;
pme|=0x80000000;
pme|=paddr;// top bit is set anyway ...
}
else
{
pme=pmap[paddr>>VTLB_PAGE_BITS];
if (pme<0)
pme|=paddr;// top bit is set anyway ...
}
vmap[vaddr>>VTLB_PAGE_BITS]=pme-vaddr;
vaddr+=VTLB_PAGE_SIZE;
paddr+=VTLB_PAGE_SIZE;
sz-=VTLB_PAGE_SIZE;
}
}
void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 sz)
{
verify(0==(vaddr&VTLB_PAGE_MASK));
verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
u32 bu8=(u32)buffer;
while(sz>0)
{
vmap[vaddr>>VTLB_PAGE_BITS]=bu8-vaddr;
vaddr+=VTLB_PAGE_SIZE;
bu8+=VTLB_PAGE_SIZE;
sz-=VTLB_PAGE_SIZE;
}
}
void vtlb_VMapUnmap(u32 vaddr,u32 sz)
{
verify(0==(vaddr&VTLB_PAGE_MASK));
verify(0==(sz&VTLB_PAGE_MASK) && sz>0);
while(sz>0)
{
u32 handl=UnmappedVirtHandler0;
if (vaddr&0x80000000)
{
handl=UnmappedVirtHandler1;
}
handl|=vaddr; // top bit is set anyway ...
handl|=0x80000000;
vmap[vaddr>>VTLB_PAGE_BITS]=handl-vaddr;
vaddr+=VTLB_PAGE_SIZE;
sz-=VTLB_PAGE_SIZE;
}
}
bool vtlb_Init()
{
//Reset all vars to default values
vtlbHandlerCount=0;
memset(RWFT,0,sizeof(RWFT));
//Register default handlers
//Unmapped Virt handlers _MUST_ be registed frist.
//On address translation the top bit cannot be preserved.This is not normaly a problem since
//the physical address space can be 'compressed' to just 29 bits.However, to properly handle exceptions
//there must be a way to get the full address back.Thats why i use these 2 functions and encode the hi bit directly into em :)
UnmappedVirtHandler0=vtlb_RegisterHandler(vtlbUnmappedVRead8<0>,vtlbUnmappedVRead16<0>,vtlbUnmappedVRead32<0>,vtlbUnmappedVRead64<0>,vtlbUnmappedVRead128<0>,
vtlbUnmappedVWrite8<0>,vtlbUnmappedVWrite16<0>,vtlbUnmappedVWrite32<0>,vtlbUnmappedVWrite64<0>,vtlbUnmappedVWrite128<0>);
UnmappedVirtHandler1=vtlb_RegisterHandler(vtlbUnmappedVRead8<0x80000000>,vtlbUnmappedVRead16<0x80000000>,vtlbUnmappedVRead32<0x80000000>,
vtlbUnmappedVRead64<0x80000000>,vtlbUnmappedVRead128<0x80000000>,
vtlbUnmappedVWrite8<0x80000000>,vtlbUnmappedVWrite16<0x80000000>,vtlbUnmappedVWrite32<0x80000000>,
vtlbUnmappedVWrite64<0x80000000>,vtlbUnmappedVWrite128<0x80000000>);
UnmappedPhyHandler0=vtlb_RegisterHandler(vtlbUnmappedPRead8<0>,vtlbUnmappedPRead16<0>,vtlbUnmappedPRead32<0>,vtlbUnmappedPRead64<0>,vtlbUnmappedPRead128<0>,
vtlbUnmappedPWrite8<0>,vtlbUnmappedPWrite16<0>,vtlbUnmappedPWrite32<0>,vtlbUnmappedPWrite64<0>,vtlbUnmappedPWrite128<0>);
UnmappedPhyHandler1=vtlb_RegisterHandler(vtlbUnmappedPRead8<0x80000000>,vtlbUnmappedPRead16<0x80000000>,vtlbUnmappedPRead32<0x80000000>,
vtlbUnmappedPRead64<0x80000000>,vtlbUnmappedPRead128<0x80000000>,
vtlbUnmappedPWrite8<0x80000000>,vtlbUnmappedPWrite16<0x80000000>,vtlbUnmappedPWrite32<0x80000000>,
vtlbUnmappedPWrite64<0x80000000>,vtlbUnmappedPWrite128<0x80000000>);
DefaultPhyHandler=vtlb_RegisterHandler(0,0,0,0,0,0,0,0,0,0);
//Setup the initial mappings
vtlb_MapHandler(DefaultPhyHandler,0,VTLB_PMAP_SZ);
//Set the V space as unmapped
vtlb_VMapUnmap(0,(VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE);
//yeah i know, its stupid .. but this code has to be here for now ;p
vtlb_VMapUnmap((VTLB_VMAP_ITEMS-1)*VTLB_PAGE_SIZE,VTLB_PAGE_SIZE);
//done !
return true;
}
void vtlb_Term()
{
//nothing to do for now
}
namespace EE { namespace Dynarec
{
//ecx = addr
//edx = ptr
void vtlb_DynGenRead(u32 sz,int freereg)
{
freereg=-1;
/*
u32 vmv=vmap[addr>>VTLB_PAGE_BITS];
s32 ppf=addr+vmv;
if (!(ppf<0))
{
data[0]=*reinterpret_cast<DataType*>(ppf);
if (DataSize==128)
data[1]=*reinterpret_cast<DataType*>(ppf+8);
return 0;
}
else
{
//has to: translate, find function, call function
u32 hand=(u8)vmv;
u32 paddr=ppf-hand+0x80000000;
//SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr);
return reinterpret_cast<TemplateHelper<DataSize,false>::HandlerType*>(RWFT[TemplateHelper<DataSize,false>::sidx][0][hand])(paddr,data);
}
mov eax,ecx;
shr eax,VTLB_PAGE_BITS;
mov eax,[eax*4+vmap];
add ecx,eax;
js _fullread;
//these are wrong order, just an example ...
mov [eax],ecx;
mov ecx,[edx];
mov [eax+4],ecx;
mov ecx,[edx+4];
mov [eax+4+4],ecx;
mov ecx,[edx+4+4];
mov [eax+4+4+4+4],ecx;
mov ecx,[edx+4+4+4+4];
///....
jmp cont;
_fullread:
movzx eax,al;
sub ecx,eax;
sub ecx,0x80000000;
call [eax+stuff];
cont:
........
*/
MOV32RtoR(EAX,ECX);
SHR32ItoR(EAX,VTLB_PAGE_BITS);
MOV32RmSOffsettoR(EAX,EAX,(int)vmap,2);
ADD32RtoR(ECX,EAX);
u8* _fullread=JS8(0);
switch(sz)
{
case 8:
MOVZX32Rm8toR(EAX,ECX);
MOV8RtoRm(EDX,EAX);
break;
case 16:
MOVZX32Rm16toR(EAX,ECX);
MOV16RtoRm(EDX,EAX);
break;
case 32:
MOV32RmtoR(EAX,ECX);
MOV32RtoRm(EDX,EAX);
break;
case 64:
if (freereg>0)
{
MOVQRmtoROffset(freereg,ECX,0);
MOVQRtoRmOffset(EDX,freereg,0);
}
else
{
MOV32RmtoR(EAX,ECX);
MOV32RtoRm(EDX,EAX);
MOV32RmtoROffset(EAX,ECX,4);
MOV32RtoRmOffset(EDX,EAX,4);
}
break;
case 128:
if (freereg>0)
{
SSE_MOVAPSRmtoROffset(freereg,ECX,0);
SSE_MOVAPSRtoRmOffset(EDX,freereg,0);
}
else
{
MOV32RmtoR(EAX,ECX);
MOV32RtoRm(EDX,EAX);
MOV32RmtoROffset(EAX,ECX,4);
MOV32RtoRmOffset(EDX,EAX,4);
MOV32RmtoROffset(EAX,ECX,8);
MOV32RtoRmOffset(EDX,EAX,8);
MOV32RmtoROffset(EAX,ECX,12);
MOV32RtoRmOffset(EDX,EAX,12);
}
break;
}
u8* cont=JMP8(0);
x86SetJ8(_fullread);
int szidx=0;
switch(sz)
{
case 8: szidx=0; break;
case 16: szidx=1; break;
case 32: szidx=2; break;
case 64: szidx=3; break;
case 128: szidx=4; break;
}
MOVZX32R8toR(EAX,EAX);
SUB32RtoR(ECX,EAX);
//eax=[funct+eax]
MOV32RmSOffsettoR(EAX,EAX,(int)&RWFT[szidx][0][0],2);
SUB32ItoR(ECX,0x80000000);
CALL32R(EAX);
x86SetJ8(cont);
}
void vtlb_DynGenWrite(u32 sz,int freereg)
{
MOV32RtoR(EAX,ECX);
SHR32ItoR(EAX,VTLB_PAGE_BITS);
MOV32RmSOffsettoR(EAX,EAX,(int)vmap,2);
ADD32RtoR(ECX,EAX);
u8* _full=JS8(0);
switch(sz)
{
//8 , 16, 32 : data on EDX
case 8:
MOV8RtoRm(ECX,EDX);
break;
case 16:
MOV16RtoRm(ECX,EDX);
break;
case 32:
MOV32RtoRm(ECX,EDX);
break;
/*
case 64:
//write8(0xCC);
POP32R(EAX);
MOV32RtoRm(ECX,EAX);
POP32R(EAX);
MOV32RtoRmOffset(ECX,EAX,4);
break;*/
case 64:
case 128:
if (freereg>0)
{
if (sz==64)
{
MOVQRmtoROffset(freereg,EDX,0);
MOVQRtoRmOffset(ECX,freereg,0);
}
else
{
SSE_MOVAPSRmtoROffset(freereg,EDX,0);
SSE_MOVAPSRtoRmOffset(ECX,freereg,0);
}
}
else
{
MOV32RmtoR(EAX,EDX);
MOV32RtoRm(ECX,EAX);
MOV32RmtoROffset(EAX,EDX,4);
MOV32RtoRmOffset(ECX,EAX,4);
if (sz==128)
{
MOV32RmtoROffset(EAX,EDX,8);
MOV32RtoRmOffset(ECX,EAX,8);
MOV32RmtoROffset(EAX,EDX,12);
MOV32RtoRmOffset(ECX,EAX,12);
}
}
break;
}
u8* cont=JMP8(0);
x86SetJ8(_full);
int szidx=0;
switch(sz)
{
case 8: szidx=0; break;
case 16: szidx=1; break;
case 32: szidx=2; break;
case 64: szidx=3; break;
case 128: szidx=4; break;
}
MOVZX32R8toR(EAX,EAX);
SUB32RtoR(ECX,EAX);
//eax=[funct+eax]
MOV32RmSOffsettoR(EAX,EAX,(int)&RWFT[szidx][1][0],2);
SUB32ItoR(ECX,0x80000000);
CALL32R(EAX);
x86SetJ8(cont);
}
} }
#endif // PCSX2_VIRTUAL_MEM

67
pcsx2/vtlb.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef _VTLB_H_
#define _VTLB_H_
#include <xmmintrin.h>
#ifndef PCSX2_VIRTUAL_MEM
#define mem8_t u8
#define mem16_t u16
#define mem32_t u32
#define mem64_t u64
#define mem128_t u64
typedef int __fastcall vltbMemR8FP(u32 addr,mem8_t* data);
typedef int __fastcall vltbMemR16FP(u32 addr,mem16_t* data);
typedef int __fastcall vltbMemR32FP(u32 addr,mem32_t* data);
typedef int __fastcall vltbMemR64FP(u32 addr,mem64_t* data);
typedef int __fastcall vltbMemR128FP(u32 addr,mem128_t* data);
typedef void __fastcall vltbMemW8FP(u32 addr,mem8_t data);
typedef void __fastcall vltbMemW16FP(u32 addr,mem16_t data);
typedef void __fastcall vltbMemW32FP(u32 addr,mem32_t data);
typedef void __fastcall vltbMemW64FP(u32 addr,const mem64_t* data);
typedef void __fastcall vltbMemW128FP(u32 addr,const mem128_t* data);
typedef u32 vtlbHandler;
bool vtlb_Init();
void vtlb_Term();
//physical stuff
vtlbHandler vtlb_RegisterHandler( vltbMemR8FP* r8,vltbMemR16FP* r16,vltbMemR32FP* r32,vltbMemR64FP* r64,vltbMemR128FP* r128,
vltbMemW8FP* w8,vltbMemW16FP* w16,vltbMemW32FP* w32,vltbMemW64FP* w64,vltbMemW128FP* w128);
void vtlb_MapHandler(vtlbHandler handler,u32 start,u32 size);
void vtlb_MapBlock(void* base,u32 start,u32 size,u32 blocksize=0);
void* vtlb_GetPhyPtr(u32 paddr);
//void vtlb_Mirror(u32 new_region,u32 start,u32 size); // -> not working yet :(
//virtual mappings
void vtlb_VMap(u32 vaddr,u32 paddr,u32 sz);
void vtlb_VMapBuffer(u32 vaddr,void* buffer,u32 sz);
void vtlb_VMapUnmap(u32 vaddr,u32 sz);
//Memory functions
int __fastcall vtlb_memRead8(u32 mem, u8 *out);
int __fastcall vtlb_memRead16(u32 mem, u16 *out);
int __fastcall vtlb_memRead32(u32 mem, u32 *out);
int __fastcall vtlb_memRead64(u32 mem, u64 *out);
int __fastcall vtlb_memRead128(u32 mem, u64 *out);
void __fastcall vtlb_memWrite8 (u32 mem, u8 value);
void __fastcall vtlb_memWrite16(u32 mem, u16 value);
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 EE { namespace Dynarec {
void vtlb_DynGenWrite(u32 sz,int freereg);
void vtlb_DynGenRead(u32 sz,int freereg);
} }
#endif
#endif

View File

@ -20,13 +20,20 @@
#include <commctrl.h> #include <commctrl.h>
#include <windowsx.h> #include <windowsx.h>
#include <stdio.h> #include <stdio.h>
#include <string>
#include "resource.h" #include "resource.h"
#include "InterTables.h"
#include "Debugger.h" #include "Debugger.h"
#include "Common.h" #include "Common.h"
#include "win32.h" #include "win32.h"
#include "PsxMem.h" #include "PsxMem.h"
#include "R3000A.h" #include "R3000A.h"
#ifdef _MSC_VER
#pragma warning(disable:4996) //ignore the stricmp deprecated warning
#endif
extern void (*IOP_DEBUG_BSC[64])(char *buf); extern void (*IOP_DEBUG_BSC[64])(char *buf);
extern void UpdateR5900op(); extern void UpdateR5900op();
void RefreshIOPDebugger(void); void RefreshIOPDebugger(void);
@ -155,24 +162,22 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
} }
else else
{ {
std::string output;
fprintf(fp,"----------------------------------\n"); fprintf(fp,"----------------------------------\n");
fprintf(fp,"EE DISASM TEXT DOCUMENT BY PCSX2 \n"); fprintf(fp,"EE DISASM TEXT DOCUMENT BY PCSX2 \n");
fprintf(fp,"----------------------------------\n"); fprintf(fp,"----------------------------------\n");
for (temp = start_pc; temp <= end_pc; temp += 4) for (temp = start_pc; temp <= end_pc; temp += 4)
{ {
opcode_addr=temp; opcode_addr=temp;
MakeDebugOpcode(); MakeDebugOpcode();
OpcodePrintTable[(cpuRegs.code) >> 26](tmp);
if (HasBreakpoint()) output.assign( HasBreakpoint() ? "*" : "" );
{ sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
sprintf(buf, "*%08X %08X: %s", temp, cpuRegs.code, tmp); output.append( buf );
}
else EE::OpcodeTables::Standard[_Opcode_].decode( output );
{
sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
}
fprintf(fp, "%s\n", buf); fprintf(fp, "%s\n", buf);
} }
@ -636,25 +641,24 @@ void RefreshDebugger(void)
for (t = DebuggerPC, cnt = 0; t < (DebuggerPC + 0x00000074); t += 0x00000004, cnt++) for (t = DebuggerPC, cnt = 0; t < (DebuggerPC + 0x00000074); t += 0x00000004, cnt++)
{ {
char syscall_str[128]; char syscall_str[256];
// Make the opcode. // Make the opcode.
u32 *mem = (u32*)PSM(t); u32 *mem = (u32*)PSM(t);
char *str;
if (mem == NULL) { if (mem == NULL) {
char nullAddr[256]; sprintf(syscall_str, "%8.8lx 00000000: NULL MEMORY", t);
sprintf(nullAddr, "%8.8lx 00000000: NULL MEMORY", t); str = nullAddr;
} else { } else {
/* special procesing for syscall. This should probably be moved into the disR5900Fasm() call in the future. */ /* special procesing for syscall. This should probably be moved into the disR5900Fasm() call in the future. */
if (0x0c == *mem && 0x24030000 == (*(mem-1) & 0xFFFFFF00)){ if (0x0c == *mem && 0x24030000 == (*(mem-1) & 0xFFFFFF00)){
/* it's a syscall preceeded by a li v1,$data instruction. */ /* it's a syscall preceeded by a li v1,$data instruction. */
u8 bios_call = *(mem-1) & 0xFF; u8 bios_call = *(mem-1) & 0xFF;
sprintf(syscall_str, "%08X:\tsyscall\t%s", t, bios[bios_call]); sprintf(syscall_str, "%08X:\tsyscall\t%s", t, bios[bios_call]);
str = syscall_str;
} else { } else {
str = disR5900Fasm(*mem, t); std::string str;
disR5900Fasm(str, *mem, t);
str.copy( syscall_str, 256 );
} }
} }
SendMessage(hWnd_debugdisasm, LB_ADDSTRING, 0, (LPARAM)str); SendMessage(hWnd_debugdisasm, LB_ADDSTRING, 0, (LPARAM)syscall_str );
} }
} }

View File

@ -22,11 +22,7 @@
#define NUM_BREAKPOINTS 8 #define NUM_BREAKPOINTS 8
extern void (*OpcodePrintTable[64])(char *buf);
extern BOOL APIENTRY DebuggerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern BOOL APIENTRY DebuggerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
extern BOOL APIENTRY MemoryProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern BOOL APIENTRY MemoryProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
extern void RefreshDebugger(void); extern void RefreshDebugger(void);

249
pcsx2/windows/SamplProf.cpp Normal file
View File

@ -0,0 +1,249 @@
#ifndef _DEBUG
#include "SamplProf.h"
#include <vector>
#include <string>
#include <map>
#include <sstream>
#include <algorithm>
using namespace std;
template <typename T>
std::string to_string(const T& value)
{
ostringstream oss;
oss << value;
return oss.str();
}
DWORD GetModuleFromPtr(IN void* ptr,OUT LPSTR lpFilename,IN DWORD nSize)
{
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(ptr,&mbi,sizeof(mbi));
return GetModuleFileName((HMODULE)mbi.AllocationBase,lpFilename,nSize);
}
struct Module
{
uptr base;
uptr end;
uptr len;
string name;
u32 ticks;
Module(const char* name,void* ptr)
{
if (name!=0)
this->name=name;
FromAddress(ptr,name==0);
ticks=0;
}
Module(const char* name,void* b,u32 s)
{
this->name=name;
FromValues(b,s);
ticks=0;
}
bool operator<(const Module &other) const
{
return ticks>other.ticks;
}
string ToString(u32 total_ticks)
{
return name + ": " + to_string(ticks*100/(float)total_ticks) + " ";
}
bool Inside(uptr val) { return val>=base && val<=end; }
void FromAddress(void* ptr,bool getname)
{
char filename[512];
char filename2[512];
static void* ptr_old=0;
if (ptr_old==ptr)
return;
ptr_old=ptr;
MEMORY_BASIC_INFORMATION mbi;
VirtualQuery(ptr,&mbi,sizeof(mbi));
base=(u32)mbi.AllocationBase;
GetModuleFileName((HMODULE)mbi.AllocationBase,filename,512);
len=(u8*)mbi.BaseAddress-(u8*)mbi.AllocationBase+mbi.RegionSize;
if (getname)
{
name=filename;
size_t last=name.find_last_of('\\');
last=last==name.npos?0:last+1;
name=name.substr(last);
}
for(;;)
{
VirtualQuery(((u8*)base)+len,&mbi,sizeof(mbi));
if (!(mbi.Type&MEM_IMAGE))
break;
if (!GetModuleFileName((HMODULE)mbi.AllocationBase,filename2,512))
break;
if (strcmp(filename,filename2)!=0)
break;
len+=mbi.RegionSize;
}
end=base+len-1;
}
void FromValues(void* b,u32 s)
{
base= (uptr)b;
len=s;
end=base+len-1;
}
};
vector<Module> ProfModules;
typedef map<string,Module> MapType;
MapType ProfUnknownHash;
HANDLE hEmuThread;
HANDLE hProfThread;
void ProfilerRegisterSource(const char* Name,void* buff,u32 sz)
{
ProfilerTerm();
Module tmp(Name,buff,sz);
ProfModules.push_back(tmp);
ProfilerInit();
}
void ProfilerRegisterSource(const char* Name,void* function)
{
ProfilerTerm();
Module tmp(Name,function);
ProfModules.push_back(tmp);
ProfilerInit();
}
volatile bool ProfRunning=false;
int __stdcall ProfilerThread(void* nada)
{
ProfUnknownHash.clear();
u32 tick_count=0;
while(ProfRunning)
{
_loopstart:
Sleep(10);
if (tick_count>300)
{
string rv="|";
u32 subtotal=0;
for (size_t i=0;i<ProfModules.size();i++)
{
rv+=ProfModules[i].ToString(tick_count);
subtotal+=ProfModules[i].ticks;
ProfModules[i].ticks=0;
}
rv+=" Total " + to_string(subtotal*100/(float)tick_count) + "\n|";
vector<MapType::mapped_type> lst;
for (MapType::iterator i=ProfUnknownHash.begin();i!=ProfUnknownHash.end();i++)
{
lst.push_back(i->second);
}
sort(lst.begin(),lst.end());
for (size_t i=0;i<lst.size();i++)
{
rv+=lst[i].ToString(tick_count);
}
SysPrintf("+Sampling Profiler Results-\n%s\n+>\n",rv.c_str());
tick_count=0;
ProfUnknownHash.clear();
}
tick_count++;
CONTEXT ctx;
ctx.ContextFlags= CONTEXT_FULL;
GetThreadContext(hEmuThread,&ctx);
for (size_t i=0;i<ProfModules.size();i++)
{
if (ProfModules[i].Inside(ctx.Eip))
{
ProfModules[i].ticks++;
goto _loopstart; //and thats why structured programming sucks
}
}
char modulename[512];
DWORD sz=GetModuleFromPtr((void*)ctx.Eip,modulename,512);
string modulenam;
if (sz==0)
modulenam="[Unknown]";
else
modulenam=modulename;
map<string,Module>::iterator iter=ProfUnknownHash.find(modulenam);
if (iter!=ProfUnknownHash.end())
{
iter->second.ticks++;
goto _loopstart;
}
Module tmp(sz==0?modulenam.c_str():0,(void*)ctx.Eip);
tmp.ticks++;
ProfUnknownHash.insert(MapType::value_type(modulenam, tmp));
}
return -1;
}
void ProfilerInit()
{
if (ProfRunning)
return;
ProfRunning=true;
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
&(HANDLE)hEmuThread,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
hProfThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ProfilerThread,0,0,0);
SetThreadPriority(hProfThread,THREAD_PRIORITY_HIGHEST);
}
void ProfilerTerm()
{
if (!ProfRunning)
return;
ProfRunning=false;
ResumeThread(hProfThread);
WaitForSingleObject(hProfThread,INFINITE);
CloseHandle(hProfThread);
CloseHandle(hEmuThread);
}
void ProfilerSetEnabled(bool Enabled)
{
if (!ProfRunning)
return;
if (Enabled)
ResumeThread(hProfThread);
else
SuspendThread(hProfThread);
}
#endif

View File

@ -19,7 +19,7 @@
</ToolFiles> </ToolFiles>
<Configurations> <Configurations>
<Configuration <Configuration
Name="Release|Win32" Name="Release VM|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0" UseOfMFC="0"
@ -65,7 +65,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2.exe" OutputFile="$(SolutionDir)\bin\pcsx2-vm.exe"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
@ -91,7 +91,7 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Debug|Win32" Name="Debug vm|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0" UseOfMFC="0"
@ -137,7 +137,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
OutputFile="$(SolutionDir)\bin\pcsx2d.exe" OutputFile="$(SolutionDir)\bin\pcsx2d-vm.exe"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
@ -163,7 +163,7 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0" UseOfMFC="0"
@ -209,7 +209,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
OutputFile="$(SolutionDir)\bin\pcsx2td.exe" OutputFile="$(SolutionDir)\bin\pcsx2d-vtlb.exe"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
@ -235,7 +235,7 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\devbuild.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0" UseOfMFC="0"
@ -302,7 +302,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2t.exe" OutputFile="$(SolutionDir)\bin\pcsx2-vtlb.exe"
/> />
<Tool <Tool
Name="VCALinkTool" Name="VCALinkTool"
@ -328,7 +328,7 @@
/> />
</Configuration> </Configuration>
<Configuration <Configuration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
ConfigurationType="1" ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops" InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops"
UseOfMFC="0" UseOfMFC="0"
@ -377,7 +377,85 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2r.exe" OutputFile="$(SolutionDir)\bin\pcsx2r-vm.exe"
ProgramDatabaseFile="&quot;$(TargetDir)$(TargetName).pdb&quot;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
<Configuration
Name="Release vtlb (to Public)|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="MASM"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/pcsx2.tlb"
/>
<Tool
Name="VCCLCompilerTool"
EnableFiberSafeOptimizations="true"
PreprocessorDefinitions="NDEBUG"
EnableEnhancedInstructionSet="0"
CompileAs="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2r-vtlb.exe"
ProgramDatabaseFile="&quot;$(TargetDir)$(TargetName).pdb&quot;" ProgramDatabaseFile="&quot;$(TargetDir)$(TargetName).pdb&quot;"
/> />
<Tool <Tool
@ -550,6 +628,14 @@
RelativePath="..\..\PathUtils.c" RelativePath="..\..\PathUtils.c"
> >
</File> </File>
<File
RelativePath="..\SamplProf.cpp"
>
</File>
<File
RelativePath="..\SamplProf.h"
>
</File>
<File <File
RelativePath="..\..\System.h" RelativePath="..\..\System.h"
> >
@ -682,7 +768,7 @@
RelativePath="..\..\zlib\adler32.c" RelativePath="..\..\zlib\adler32.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -690,7 +776,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -698,7 +784,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -706,7 +792,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -714,7 +800,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -726,7 +820,7 @@
RelativePath="..\..\zlib\compress.c" RelativePath="..\..\zlib\compress.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -734,7 +828,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -742,7 +836,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -750,7 +844,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -758,7 +852,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -770,7 +872,7 @@
RelativePath="..\..\zlib\crc32.c" RelativePath="..\..\zlib\crc32.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -778,7 +880,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -786,7 +888,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -794,7 +896,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -802,7 +904,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -818,7 +928,7 @@
RelativePath="..\..\zlib\deflate.c" RelativePath="..\..\zlib\deflate.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -826,7 +936,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -834,7 +944,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -842,7 +952,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -850,7 +960,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -866,7 +984,7 @@
RelativePath="..\..\zlib\gzio.c" RelativePath="..\..\zlib\gzio.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -874,7 +992,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -882,7 +1000,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -890,7 +1008,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -898,7 +1016,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -910,7 +1036,7 @@
RelativePath="..\..\zlib\infback.c" RelativePath="..\..\zlib\infback.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -918,7 +1044,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -926,7 +1052,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -934,7 +1060,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -942,7 +1068,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -954,7 +1088,7 @@
RelativePath="..\..\zlib\inffast.c" RelativePath="..\..\zlib\inffast.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -962,7 +1096,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -970,7 +1104,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -978,7 +1112,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -986,7 +1120,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1006,7 +1148,7 @@
RelativePath="..\..\zlib\inflate.c" RelativePath="..\..\zlib\inflate.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1014,7 +1156,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1022,7 +1164,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1030,7 +1172,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1038,7 +1180,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1054,7 +1204,7 @@
RelativePath="..\..\zlib\inftrees.c" RelativePath="..\..\zlib\inftrees.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1062,7 +1212,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1070,7 +1220,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1078,7 +1228,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1086,7 +1236,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1102,7 +1260,7 @@
RelativePath="..\..\zlib\trees.c" RelativePath="..\..\zlib\trees.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1110,7 +1268,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1118,7 +1276,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1126,7 +1284,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1134,7 +1292,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1150,7 +1316,7 @@
RelativePath="..\..\zlib\uncompr.c" RelativePath="..\..\zlib\uncompr.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1158,7 +1324,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1166,7 +1332,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1174,7 +1340,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1182,7 +1348,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1202,7 +1376,7 @@
RelativePath="..\..\zlib\zutil.c" RelativePath="..\..\zlib\zutil.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1210,7 +1384,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1218,7 +1392,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1226,7 +1400,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1234,7 +1408,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1250,6 +1432,14 @@
<Filter <Filter
Name="Ps2" Name="Ps2"
> >
<File
RelativePath="..\..\vtlb.cpp"
>
</File>
<File
RelativePath="..\..\vtlb.h"
>
</File>
<Filter <Filter
Name="EE" Name="EE"
> >
@ -1269,7 +1459,7 @@
RelativePath="..\..\Counters.c" RelativePath="..\..\Counters.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1277,7 +1467,16 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
RuntimeLibrary="0"
AssemblerOutput="4"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1369,7 +1568,7 @@
RelativePath="..\..\x86\iFPU.c" RelativePath="..\..\x86\iFPU.c"
> >
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release VM|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1377,7 +1576,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug vm|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1385,7 +1584,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Debug TLB|Win32" Name="Debug vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1393,7 +1592,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release TLB|Win32" Name="Release vtlb|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1401,7 +1600,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1461,7 +1668,15 @@
RelativePath="..\..\x86\ir5900tables.c" RelativePath="..\..\x86\ir5900tables.c"
> >
<FileConfiguration <FileConfiguration
Name="Release (to Public)|Win32" Name="Release VM (to Public)|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
<FileConfiguration
Name="Release vtlb (to Public)|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"

View File

@ -52,6 +52,7 @@
#include "cheats/cheats.h" #include "cheats/cheats.h"
#include "Paths.h" #include "Paths.h"
#include "SamplProf.h"
#define COMPILEDATE __DATE__ #define COMPILEDATE __DATE__
@ -542,12 +543,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
MessageBox(NULL, str, "SysError", MB_OK); MessageBox(NULL, str, "SysError", MB_OK);
return -1; return -1;
} }
#endif
__try __try
{ {
#endif
gApp.hInstance = hInstance; gApp.hInstance = hInstance;
gApp.hMenu = NULL; gApp.hMenu = NULL;
gApp.hWnd = NULL; gApp.hWnd = NULL;
@ -654,6 +654,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
InitCPUTicks(); InitCPUTicks();
if (SysInit() == -1) return 1; if (SysInit() == -1) return 1;
ProfilerInit();
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if( g_TestRun.enabled || g_TestRun.ptitle != NULL ) { if( g_TestRun.enabled || g_TestRun.ptitle != NULL ) {
// run without ui // run without ui
@ -697,16 +699,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
RunGui(); RunGui();
#ifdef PCSX2_VIRTUAL_MEM
} }
__except(SysPageFaultExceptionFilter(GetExceptionInformation())) __except(SysPageFaultExceptionFilter(GetExceptionInformation()))
{ {
} }
#ifdef PCSX2_VIRTUAL_MEM
VirtualFree(PS2MEM_BASE, 0, MEM_RELEASE); VirtualFree(PS2MEM_BASE, 0, MEM_RELEASE);
#endif #endif
ProfilerTerm();
return 0; return 0;
} }
@ -1598,7 +1600,7 @@ void CreateMainWindow(int nCmdShow) {
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
const char* pvm = "VM"; const char* pvm = "VM";
#else #else
const char* pvm = "TLB"; const char* pvm = "VTLB";
#endif #endif
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD

View File

@ -85,10 +85,310 @@ void checkregs()
if( g_EEFreezeRegs ) assert( g_globalMMXSaved ); if( g_EEFreezeRegs ) assert( g_globalMMXSaved );
} }
#endif #endif
__declspec(align(16)) u8 _xmm_backup[16*2];
//this one checks for alligments too ...
__declspec(naked) void __fastcall memcpy_raz_u(void *dest, const void *src, size_t bytes)
{
__asm
{
test edx,0xf;
jz memcpy_raz_;
}
//THIS CODE IS COPY PASTED FROM memcpy_raz_
#define MOVSRC movups
__asm
{
//Reads before reads, to avoid stalls
mov eax,[esp+4];
//Make sure to save xmm0, it must be preserved ...
movaps [_xmm_backup+0x00],xmm0;
//if >=128 bytes use 128 byte unrolled loop
//i use cmp ..,127 + jna because 127 is encodable using the simm8 form
cmp eax,127;
jna _loop_1;
//unrolled version also toiches xmm1, save it :)
movaps [_xmm_backup+0x10],xmm1;
//since this is a common branch target it could be good to align it -- no idea if it has any effect :p
align 16
//128 byte unrolled loop
_loop_8:
MOVSRC xmm0,[edx+0x00]; //read first to avoid read-after-write stalls
MOVSRC xmm1,[edx+0x10];
sub edx,-128; //edx won't be used for a while, so update it here. sub/-128 for simm8 encoding
movaps [ecx+0x00],xmm0; //then write :p
movaps [ecx+0x10],xmm1;
sub ecx,-128; //ecx won't be used for a while, so update it here. sub/-128 for simm8 encoding
MOVSRC xmm0,[edx+0x20-128];
MOVSRC xmm1,[edx+0x30-128];
add eax,-128; //eax won't be used for a while, so update it here. add/-128 for simm8 encoding
movaps [ecx+0x20-128],xmm0;
movaps [ecx+0x30-128],xmm1;
MOVSRC xmm0,[edx+0x40-128];
MOVSRC xmm1,[edx+0x50-128];
movaps [ecx+0x40-128],xmm0;
movaps [ecx+0x50-128],xmm1;
MOVSRC xmm0,[edx+0x60-128];
MOVSRC xmm1,[edx+0x70-128];
movaps [ecx+0x60-128],xmm0;
movaps [ecx+0x70-128],xmm1;
//127~ja, 127 is encodable as simm8 :)
cmp eax,127;
ja _loop_8;
//restore xmm1 :)
movaps xmm1,[_xmm_backup+0x10];
//direct copy for 0~7 qwords
//in order to avoid the inc/dec of all 3 registers
//i use negative relative addressing from the top of the buffers
//[top-current index]
_loop_1:
//prepare the regs for 'negative relative addressing'
add edx,eax;
add ecx,eax;
neg eax;
jz cleanup; //exit if nothing to do
_loop_1_inner:
MOVSRC xmm0,[edx+eax];
movaps [ecx+eax],xmm0;
add eax,16; //while the offset is still negative we have data to copy
js _loop_1_inner;
//done !
cleanup:
//restore xmm and exit ~)
movaps xmm0,[_xmm_backup+0x00];
ret 4;
}
#undef MOVSRC
}
//Custom memcpy, only for 16 byte aligned stuff (used for mtgs)
//These functions are optimised for medium-small transfer sizes (<2048, >=128).No prefetching is used since the reads are linear
//and the cache logic can predict em :)
//this implementation use forward copy, in 128 byte blocks, and then does the remaining in 16 byte blocks :)
//MOVSRC = opcode used to read.I use the same code for the unaligned version, with a different define :)
#define MOVSRC movaps
__declspec(naked) void __fastcall memcpy_raz_(void *dest, const void *src, size_t bytes)
{
__asm
{
//Reads before reads, to avoid stalls
mov eax,[esp+4];
//Make sure to save xmm0, it must be preserved ...
movaps [_xmm_backup+0x00],xmm0;
//if >=128 bytes use 128 byte unrolled loop
//i use cmp ..,127 + jna because 127 is encodable using the simm8 form
cmp eax,127;
jna _loop_1;
//unrolled version also toiches xmm1, save it :)
movaps [_xmm_backup+0x10],xmm1;
//since this is a common branch target it could be good to align it -- no idea if it has any effect :p
align 16
//128 byte unrolled loop
_loop_8:
MOVSRC xmm0,[edx+0x00]; //read first to avoid read-after-write stalls
MOVSRC xmm1,[edx+0x10];
sub edx,-128; //edx won't be used for a while, so update it here. sub/-128 for simm8 encoding
movaps [ecx+0x00],xmm0; //then write :p
movaps [ecx+0x10],xmm1;
sub ecx,-128; //ecx won't be used for a while, so update it here. sub/-128 for simm8 encoding
MOVSRC xmm0,[edx+0x20-128];
MOVSRC xmm1,[edx+0x30-128];
add eax,-128; //eax won't be used for a while, so update it here. add/-128 for simm8 encoding
movaps [ecx+0x20-128],xmm0;
movaps [ecx+0x30-128],xmm1;
MOVSRC xmm0,[edx+0x40-128];
MOVSRC xmm1,[edx+0x50-128];
movaps [ecx+0x40-128],xmm0;
movaps [ecx+0x50-128],xmm1;
MOVSRC xmm0,[edx+0x60-128];
MOVSRC xmm1,[edx+0x70-128];
movaps [ecx+0x60-128],xmm0;
movaps [ecx+0x70-128],xmm1;
//127~ja, 127 is encodable as simm8 :)
cmp eax,127;
ja _loop_8;
//restore xmm1 :)
movaps xmm1,[_xmm_backup+0x10];
//direct copy for 0~7 qwords
//in order to avoid the inc/dec of all 3 registers
//i use negative relative addressing from the top of the buffers
//[top-current index]
_loop_1:
//prepare the regs for 'negative relative addressing'
add edx,eax;
add ecx,eax;
neg eax;
jz cleanup; //exit if nothing to do
_loop_1_inner:
MOVSRC xmm0,[edx+eax];
movaps [ecx+eax],xmm0;
add eax,16; //while the offset is still negative we have data to copy
js _loop_1_inner;
//done !
cleanup:
//restore xmm and exit ~)
movaps xmm0,[_xmm_backup+0x00];
ret 4;
}
}
#undef MOVSRC
//these are not used, but are here for reference.Check memcpy_raz_ for comments on the implementation ...
//First implementation, uses backward copy, 128/16 blocks
__declspec(naked) void __fastcall memcpy_raz_0(void *dest, const void *src, size_t bytes)
{
__asm
{
mov eax,[esp+4];
movaps [_xmm_backup+0x00],xmm0;
movaps [_xmm_backup+0x10],xmm1;
sub eax,16;
js retnow;
cmp eax,(127-16);
jna _loop_1;
align 16
_loop_8:
sub eax,16*8;
movaps xmm0,[edx+eax+0x80];
movaps xmm1,[edx+eax+0x70];
movaps [ecx+eax+0x80],xmm0;
movaps [ecx+eax+0x70],xmm1;
movaps xmm0,[edx+eax+0x60];
movaps xmm1,[edx+eax+0x50];
movaps [ecx+eax+0x60],xmm0;
movaps [ecx+eax+0x50],xmm1;
movaps xmm0,[edx+eax+0x40];
movaps xmm1,[edx+eax+0x30];
movaps [ecx+eax+0x40],xmm0;
movaps [ecx+eax+0x30],xmm1;
movaps xmm0,[edx+eax+0x20];
movaps xmm1,[edx+eax+0x10];
movaps [ecx+eax+0x20],xmm0;
movaps [ecx+eax+0x10],xmm1;
js retnow_restore;
cmp eax,(127-16);
ja _loop_8;
_loop_1:
movaps xmm0,[edx+eax];
movaps [ecx+eax],xmm0;
sub eax,16;
jns _loop_1;
retnow_restore:
movaps xmm0,[_xmm_backup+0x00];
movaps xmm1,[_xmm_backup+0x10];
retnow:
ret 4;
}
}
//a more optimised version of the above, used as a base for the forward version
__declspec(naked) void __fastcall memcpy_raz_2(void *dest, const void *src, size_t bytes)
{
__asm
{
mov eax,[esp+4];
movaps [_xmm_backup+0x00],xmm0;
sub eax,16;
js retnow;
cmp eax,(127-16);
jna _loop_1;
movaps [_xmm_backup+0x10],xmm1;
align 16
_loop_8:
//eax= 'remaining' bytes
//<128 bytes
movaps xmm0,[edx+eax+0x80-0x80];
movaps xmm1,[edx+eax+0x70-0x80];
sub eax,16*8;
movaps [ecx+eax+0x80],xmm0;
movaps [ecx+eax+0x70],xmm1;
movaps xmm0,[edx+eax+0x60];
movaps xmm1,[edx+eax+0x50];
movaps [ecx+eax+0x60],xmm0;
movaps [ecx+eax+0x50],xmm1;
movaps xmm0,[edx+eax+0x40];
movaps xmm1,[edx+eax+0x30];
movaps [ecx+eax+0x40],xmm0;
movaps [ecx+eax+0x30],xmm1;
movaps xmm0,[edx+eax+0x20];
movaps xmm1,[edx+eax+0x10];
movaps [ecx+eax+0x20],xmm0;
movaps [ecx+eax+0x10],xmm1;
cmp eax,(127-16);
jg _loop_8;
movaps xmm1,[_xmm_backup+0x10];
test eax,eax;
js retnow_restore;
_loop_1:
sub eax,16;
movaps xmm0,[edx+eax+0x10];
movaps [ecx+eax+0x10],xmm0;
jns _loop_1;
retnow_restore:
movaps xmm0,[_xmm_backup+0x00];
retnow:
ret 4;
}
}
void * memcpy_amd_(void *dest, const void *src, size_t n) void * memcpy_amd_(void *dest, const void *src, size_t n)
{ {
#ifdef _DEBUG #ifdef _DEBUG
__asm call checkregs __asm call checkregs
#endif #endif

View File

@ -58,7 +58,7 @@ _vuopinfo g_cop2info = {0, 0, 1, 1, 1, 0, 0};
void recCop2BranchCall( void (*func)() ) void recCop2BranchCall( void (*func)() )
{ {
X86_32CODE(SetFPUstate()); X86_32CODE(SetFPUstate());
recBranchCall( func ); EE::Dynarec::recBranchCall( func );
_freeX86regs(); _freeX86regs();
} }

View File

@ -329,14 +329,14 @@ void recMTC0()
void recERET() void recERET()
{ {
recBranchCall( ERET ); EE::Dynarec::recBranchCall( ERET );
} }
void recEI() void recEI()
{ {
// must branch after enabling interrupts, so that anything // must branch after enabling interrupts, so that anything
// pending gets triggered properly. // pending gets triggered properly.
recBranchCall( EI ); EE::Dynarec::recBranchCall( EI );
} }
void recDI() void recDI()

View File

@ -1096,6 +1096,7 @@ __forceinline void FreezeXMMRegs_(int save)
return; return;
} }
// TODO: really need to backup all regs?
g_globalXMMSaved--; g_globalXMMSaved--;
if( g_globalXMMSaved > 0 ) return; if( g_globalXMMSaved > 0 ) return;

View File

@ -1284,7 +1284,7 @@ void recDIV_S_xmm(int info)
_freeXMMreg(t0reg); _freeXMMreg(t0reg);
} }
FPURECOMPILE_CONSTCODE_PENALTY(DIV_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT,InstCycles_FPU_Sqrt); FPURECOMPILE_CONSTCODE(DIV_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1670,7 +1670,7 @@ void recMUL_S_xmm(int info)
ClampValues(recCommutativeOp(info, EEREC_D, 1)); ClampValues(recCommutativeOp(info, EEREC_D, 1));
} }
FPURECOMPILE_CONSTCODE_PENALTY(MUL_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT,InstCycles_FPU_Sqrt/2); FPURECOMPILE_CONSTCODE(MUL_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
void recMULA_S_xmm(int info) void recMULA_S_xmm(int info)
{ {
@ -1811,7 +1811,7 @@ void recSQRT_S_xmm(int info)
_freeX86reg(tempReg); _freeX86reg(tempReg);
} }
FPURECOMPILE_CONSTCODE_PENALTY(SQRT_S, XMMINFO_WRITED|XMMINFO_READT, InstCycles_FPU_Sqrt); FPURECOMPILE_CONSTCODE(SQRT_S, XMMINFO_WRITED|XMMINFO_READT);
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1916,7 +1916,7 @@ void recRSQRT_S_xmm(int info)
_freeXMMreg(t0reg); _freeXMMreg(t0reg);
} }
FPURECOMPILE_CONSTCODE_PENALTY(RSQRT_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT,InstCycles_FPU_Sqrt*2); FPURECOMPILE_CONSTCODE(RSQRT_S, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
#endif // FPU_RECOMPILE #endif // FPU_RECOMPILE

View File

@ -29,6 +29,9 @@
#include "iR5900.h" #include "iR5900.h"
#include "iMMI.h" #include "iMMI.h"
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
#ifndef MMI_RECOMPILE #ifndef MMI_RECOMPILE
REC_FUNC( PLZCW, _Rd_ ); REC_FUNC( PLZCW, _Rd_ );
@ -255,7 +258,7 @@ CPU_SSE2_XMMCACHE_START(XMMINFO_WRITED|XMMINFO_READLO|XMMINFO_READHI)
_deleteEEreg(XMMGPR_LO, 1); _deleteEEreg(XMMGPR_LO, 1);
_deleteEEreg(XMMGPR_HI, 1); _deleteEEreg(XMMGPR_HI, 1);
iFlushCall(FLUSH_CACHED_REGS); // since calling CALLFunc iFlushCall(FLUSH_CACHED_REGS); // since calling CALLFunc
CALLFunc( (uptr)PMFHL ); CALLFunc( (uptr)Interpreter::OpcodeImpl::PMFHL );
break; break;
case 0x03: // LH case 0x03: // LH
@ -566,7 +569,7 @@ void recPLZCW( void )
void recMMI0( void ) void recMMI0( void )
{ {
recMMI0t[ _Sa_ ]( ); EE::OpcodeTables::MMI0[ _Sa_ ].recompile( );
} }
#endif #endif
@ -575,7 +578,7 @@ void recMMI0( void )
void recMMI1( void ) void recMMI1( void )
{ {
recMMI1t[ _Sa_ ]( ); EE::OpcodeTables::MMI1[ _Sa_ ].recompile( );
} }
#endif #endif
@ -584,7 +587,7 @@ void recMMI1( void )
void recMMI2( void ) void recMMI2( void )
{ {
recMMI2t[ _Sa_ ]( ); EE::OpcodeTables::MMI2[ _Sa_ ].recompile( );
} }
#endif #endif
@ -593,7 +596,7 @@ void recMMI2( void )
void recMMI3( void ) void recMMI3( void )
{ {
recMMI3t[ _Sa_ ]( ); EE::OpcodeTables::MMI3[ _Sa_ ].recompile( );
} }
#endif #endif
@ -1045,7 +1048,7 @@ void recPADDSW( void )
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
CALLFunc( (uptr)PADDSW ); CALLFunc( (uptr)Interpreter::OpcodeImpl::PADDSW );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -1136,7 +1139,7 @@ void recPSUBSW( void )
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
CALLFunc( (uptr)PSUBSW ); CALLFunc( (uptr)Interpreter::OpcodeImpl::PSUBSW );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -1564,7 +1567,7 @@ CPU_SSE_XMMCACHE_END
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
CALLFunc( (uptr)PABSW ); CALLFunc( (uptr)Interpreter::OpcodeImpl::PABSW );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -1588,7 +1591,7 @@ CPU_SSE_XMMCACHE_END
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
CALLFunc( (uptr)PABSW ); CALLFunc( (uptr)Interpreter::OpcodeImpl::PABSW );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -2222,8 +2225,6 @@ void recPSRLVW()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPMSUBW() void recPMSUBW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
EEINST_SETSIGNEXT(_Rs_); EEINST_SETSIGNEXT(_Rs_);
EEINST_SETSIGNEXT(_Rt_); EEINST_SETSIGNEXT(_Rt_);
if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_); if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_);
@ -2264,7 +2265,6 @@ void recPMSUBW()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPMULTW() void recPMULTW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
EEINST_SETSIGNEXT(_Rs_); EEINST_SETSIGNEXT(_Rs_);
EEINST_SETSIGNEXT(_Rt_); EEINST_SETSIGNEXT(_Rt_);
if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_); if( _Rd_ ) EEINST_SETSIGNEXT(_Rd_);
@ -2273,7 +2273,6 @@ void recPMULTW()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPDIVW() void recPDIVW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Div;
EEINST_SETSIGNEXT(_Rs_); EEINST_SETSIGNEXT(_Rs_);
EEINST_SETSIGNEXT(_Rt_); EEINST_SETSIGNEXT(_Rt_);
REC_FUNC_INLINE( PDIVW, _Rd_ ); REC_FUNC_INLINE( PDIVW, _Rd_ );
@ -2282,7 +2281,6 @@ void recPDIVW()
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPDIVBW() void recPDIVBW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Div;
REC_FUNC_INLINE( PDIVBW, _Rd_ ); //-- REC_FUNC_INLINE( PDIVBW, _Rd_ ); //--
} }
@ -2291,8 +2289,6 @@ PCSX2_ALIGNED16(int s_mask1[4]) = {~0, 0, ~0, 0};
void recPHMADH() void recPHMADH()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _Rd_ ? EEREC_D : _allocTempXMMreg(XMMT_INT, -1); int t0reg = _Rd_ ? EEREC_D : _allocTempXMMreg(XMMT_INT, -1);
@ -2352,8 +2348,6 @@ CPU_SSE_XMMCACHE_END
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPMSUBH() void recPMSUBH()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
int t1reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
@ -2397,8 +2391,6 @@ CPU_SSE_XMMCACHE_END
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPHMSBH() void recPHMSBH()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
@ -2553,8 +2545,6 @@ CPU_SSE_XMMCACHE_END
void recPMULTH( void ) void recPMULTH( void )
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0)|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0)|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
@ -2807,8 +2797,6 @@ CPU_SSE_XMMCACHE_END
void recPMADDH( void ) void recPMADDH( void )
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START((_Rd_?XMMINFO_WRITED:0)|XMMINFO_READS|XMMINFO_READT|XMMINFO_READLO|XMMINFO_READHI|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
int t1reg = _allocTempXMMreg(XMMT_INT, -1); int t1reg = _allocTempXMMreg(XMMT_INT, -1);
@ -2933,7 +2921,17 @@ REC_FUNC( PEXCH, _Rd_);
#else #else
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
REC_FUNC( PSRAVW, _Rd_ ); //REC_FUNC( PSRAVW, _Rd_ );
void recPSRAVW( void )
{
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
if( _Rd_ > 0 ) _deleteEEreg(_Rd_, 0);
CALLFunc( (uptr)Interpreter::OpcodeImpl::PSRAVW );
}
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
PCSX2_ALIGNED16(u32 s_tempPINTEH[4]) = {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff }; PCSX2_ALIGNED16(u32 s_tempPINTEH[4]) = {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff };
@ -2993,8 +2991,6 @@ CPU_SSE_XMMCACHE_END
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPMULTUW() void recPMULTUW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI) CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
EEINST_SETSIGNEXT(_Rs_); EEINST_SETSIGNEXT(_Rs_);
@ -3028,8 +3024,6 @@ CPU_SSE_XMMCACHE_END
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recPMADDUW() void recPMADDUW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Mult;
CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI|XMMINFO_READLO|XMMINFO_READHI) CPU_SSE2_XMMCACHE_START(XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI|XMMINFO_READLO|XMMINFO_READHI)
int t0reg = _allocTempXMMreg(XMMT_INT, -1); int t0reg = _allocTempXMMreg(XMMT_INT, -1);
EEINST_SETSIGNEXT(_Rs_); EEINST_SETSIGNEXT(_Rs_);
@ -3070,7 +3064,6 @@ CPU_SSE_XMMCACHE_END
//do EEINST_SETSIGNEXT //do EEINST_SETSIGNEXT
void recPDIVUW() void recPDIVUW()
{ {
g_eeCyclePenalty = InstCycles_MMI_Div;
REC_FUNC_INLINE( PDIVUW, _Rd_ ); REC_FUNC_INLINE( PDIVUW, _Rd_ );
} }
@ -3337,6 +3330,8 @@ CPU_SSE_XMMCACHE_END
//POP32R( EBX ); //POP32R( EBX );
} }
#endif #endif // else MMI3_RECOMPILE
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
//btw, nice box ya got there !
/********************************************************* /*********************************************************
* MMI opcodes * * MMI opcodes *
* * * *
@ -23,110 +24,114 @@
#ifndef __IMMI_H__ #ifndef __IMMI_H__
#define __IMMI_H__ #define __IMMI_H__
void recMADD(); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recMADDU(); {
void recPLZCW(); void recMADD();
void recMMI0(); void recMADDU();
void recMMI1(); void recPLZCW();
void recMMI2(); void recMMI0();
void recMMI3(); void recMMI1();
void recMADD1(); void recMMI2();
void recMADDU1(); void recMMI3();
void recPMFHL(); void recMADD1();
void recPMTHL(); void recMADDU1();
void recPMAXW(); void recPMFHL();
void recPMINW(); void recPMTHL();
void recPPACW(); void recPMAXW();
void recPEXTLH(); void recPMINW();
void recPPACH(); void recPPACW();
void recPEXTLB(); void recPEXTLH();
void recPPACB(); void recPPACH();
void recPEXT5(); void recPEXTLB();
void recPPAC5(); void recPPACB();
void recPABSW(); void recPEXT5();
void recPADSBH(); void recPPAC5();
void recPABSH(); void recPABSW();
void recPADDUW(); void recPADSBH();
void recPSUBUW(); void recPABSH();
void recPSUBUH(); void recPADDUW();
void recPEXTUH(); void recPSUBUW();
void recPSUBUB(); void recPSUBUH();
void recPEXTUB(); void recPEXTUH();
void recQFSRV(); void recPSUBUB();
void recPMADDW(); void recPEXTUB();
void recPSLLVW(); void recQFSRV();
void recPSRLVW(); void recPMADDW();
void recPMSUBW(); void recPSLLVW();
void recPINTH(); void recPSRLVW();
void recPMULTW(); void recPMSUBW();
void recPDIVW(); void recPINTH();
void recPMADDH(); void recPMULTW();
void recPHMADH(); void recPDIVW();
void recPMSUBH(); void recPMADDH();
void recPHMSBH(); void recPHMADH();
void recPEXEH(); void recPMSUBH();
void recPREVH(); void recPHMSBH();
void recPMULTH(); void recPEXEH();
void recPDIVBW(); void recPREVH();
void recPEXEW(); void recPMULTH();
void recPROT3W(); void recPDIVBW();
void recPMADDUW(); void recPEXEW();
void recPSRAVW(); void recPROT3W();
void recPINTEH(); void recPMADDUW();
void recPMULTUW(); void recPSRAVW();
void recPDIVUW(); void recPINTEH();
void recPEXCH(); void recPMULTUW();
void recPEXCW(); void recPDIVUW();
void recPEXCH();
void recPEXCW();
void recPSRLH(); void recPSRLH();
void recPSRLW(); void recPSRLW();
void recPSRAH(); void recPSRAH();
void recPSRAW(); void recPSRAW();
void recPSLLH(); void recPSLLH();
void recPSLLW(); void recPSLLW();
void recMTHI1(); void recMTHI1();
void recMTLO1(); void recMTLO1();
void recMFHI1(); void recMFHI1();
void recMFLO1(); void recMFLO1();
void recMULT1(); void recMULT1();
void recMULTU1(); void recMULTU1();
void recDIV1(); void recDIV1();
void recDIVU1(); void recDIVU1();
void recPMAXH(); void recPMAXH();
void recPCGTB(); void recPCGTB();
void recPCGTH(); void recPCGTH();
void recPCGTW(); void recPCGTW();
void recPADDSB(); void recPADDSB();
void recPADDSH(); void recPADDSH();
void recPADDSW(); void recPADDSW();
void recPSUBSB(); void recPSUBSB();
void recPSUBSH(); void recPSUBSH();
void recPSUBSW(); void recPSUBSW();
void recPADDB(); void recPADDB();
void recPADDH(); void recPADDH();
void recPADDW(); void recPADDW();
void recPSUBB(); void recPSUBB();
void recPSUBH(); void recPSUBH();
void recPSUBW(); void recPSUBW();
void recPEXTLW(); void recPEXTLW();
void recPEXTUW(); void recPEXTUW();
void recPMINH(); void recPMINH();
void recPCEQB(); void recPCEQB();
void recPCEQH(); void recPCEQH();
void recPCEQW(); void recPCEQW();
void recPADDUB(); void recPADDUB();
void recPADDUH(); void recPADDUH();
void recPMFHI(); void recPMFHI();
void recPMFLO(); void recPMFLO();
void recPAND(); void recPAND();
void recPXOR(); void recPXOR();
void recPCPYLD(); void recPCPYLD();
void recPNOR(); void recPNOR();
void recPMTHI(); void recPMTHI();
void recPMTLO(); void recPMTLO();
void recPCPYUD(); void recPCPYUD();
void recPOR(); void recPOR();
void recPCPYH(); void recPCPYH();
} } }
#endif #endif

View File

@ -47,6 +47,8 @@
#include "iCore.h" #include "iCore.h"
#include "iR3000A.h" #include "iR3000A.h"
#include "SamplProf.h"
u32 g_psxMaxRecMem = 0; u32 g_psxMaxRecMem = 0;
extern const char *disRNameGPR[]; extern const char *disRNameGPR[];
extern char* disR3000Fasm(u32 code, u32 pc); extern char* disR3000Fasm(u32 code, u32 pc);
@ -539,7 +541,7 @@ static int recInit() {
} }
else break; else break;
} }
ProfilerRegisterSource("IOPRec",recMem, RECMEM_SIZE);
if( recMem == NULL ) { if( recMem == NULL ) {
SysPrintf("R3000A bad rec memory allocation\n"); SysPrintf("R3000A bad rec memory allocation\n");
return 1; return 1;
@ -1162,10 +1164,6 @@ void psxRecompileNextInstruction(int delayslot)
// peephole optimizations // peephole optimizations
if( g_pCurInstInfo->info & EEINSTINFO_COREC ) { if( g_pCurInstInfo->info & EEINSTINFO_COREC ) {
assert(0); assert(0);
// recBSC_co[cpuRegs.code>>26]();
// psxpc += 4;
// s_psxBlockCycles++;
// g_pCurInstInfo++;
} }
else { else {
assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) ); assert( !(g_pCurInstInfo->info & EEINSTINFO_NOREC) );

View File

@ -40,50 +40,6 @@
#define CP0_RECOMPILE #define CP0_RECOMPILE
#define CP2_RECOMPILE #define CP2_RECOMPILE
// We're working on new hopefully better cycle ratios, but they're still a WIP.
// And yes this whole thing is an ugly hack. I'll clean it up once we have
// a better idea how exactly the cycle ratios will work best.
//#define EXPERIMENTAL_CYCLE_TIMINGS
#ifdef EXPERIMENTAL_CYCLE_TIMINGS
// Number of cycles for basic instructions (add/sub, etc).
// On the EE these normally run in less than 1 cycle thanks to
// the superscalar nature of the CPU.
static const int InstCycles_Default = 7; // 0.75 cycles for base instructions.
static const int _ic_basemod = 4 - InstCycles_Default; // don't change me unless you're changing the fixed point accuracy of cycle counting.
// Cycle penalties for particuarly slow instructions.
static const int InstCycles_Mult = _ic_basemod + 2*8;
static const int InstCycles_Div = _ic_basemod + 13*8;
static const int InstCycles_FPU_Sqrt = _ic_basemod + 4*8;
static const int InstCycles_MMI_Mult = _ic_basemod + 4*8;
static const int InstCycles_MMI_Div = _ic_basemod + 22*8;
static const int InstCycles_Peephole_Store = _ic_basemod + 22;
static const int InstCycles_Peephole_Load = _ic_basemod + 7;
static const int InstCycles_Store = _ic_basemod + 22;
static const int InstCycles_Load = _ic_basemod + 7;
#else
static const int InstCycles_Default = 9;
static const int _ic_basemod = 8 - InstCycles_Default; // don't change me unless you're changing the fixed point accuracy of cycle counting.
static const int InstCycles_Mult = _ic_basemod + 1*8;
static const int InstCycles_Div = _ic_basemod + 13*8;
static const int InstCycles_FPU_Sqrt = _ic_basemod + 3*8;
static const int InstCycles_MMI_Mult = _ic_basemod + 2*8;
static const int InstCycles_MMI_Div = _ic_basemod + 22*8;
static const int InstCycles_Peephole_Store = _ic_basemod + 10; //_ic_basemod + 12 for snes emu
static const int InstCycles_Peephole_Load = _ic_basemod + 2; //_ic_basemod + 4 for snes emu
static const int InstCycles_Store = _ic_basemod + 10; //_ic_basemod + 12 for snes emu
static const int InstCycles_Load = _ic_basemod + 2; //_ic_basemod + 4 for snes emu
#endif
#define EE_CONST_PROP // rec2 - enables constant propagation (faster) #define EE_CONST_PROP // rec2 - enables constant propagation (faster)
//#define EE_FPU_REGCACHING 1 // Not used anymore, its always on! //#define EE_FPU_REGCACHING 1 // Not used anymore, its always on!
@ -101,22 +57,20 @@ extern u32 pc;
extern int branch; extern int branch;
extern uptr* recLUT; extern uptr* recLUT;
extern u32 maxrecmem;
extern u32 pc; // recompiler pc extern u32 pc; // recompiler pc
extern int branch; // set for branch extern int branch; // set for branch
extern u32 target; // branch target extern u32 target; // branch target
extern u16 x86FpuState; extern u16 x86FpuState;
extern u16 iCWstate; extern u16 iCWstate;
extern u32 s_nBlockCycles; // cycles of current block recompiling extern u32 s_nBlockCycles; // cycles of current block recompiling
extern u32 g_eeCyclePenalty;
void recBranchCall( void (*func)() );
#define REC_FUNC_INLINE( f, delreg ) \ #define REC_FUNC_INLINE( f, delreg ) \
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \ MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \ MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \
iFlushCall(FLUSH_EVERYTHING); \ iFlushCall(FLUSH_EVERYTHING); \
if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \ if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \
CALLFunc( (uptr)f ); CALLFunc( (uptr)EE::Interpreter::OpcodeImpl::f );
#define REC_FUNC( f, delreg ) \ #define REC_FUNC( f, delreg ) \
void f( void ); \ void f( void ); \
@ -126,7 +80,7 @@ void recBranchCall( void (*func)() );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \ MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \
iFlushCall(FLUSH_EVERYTHING); \ iFlushCall(FLUSH_EVERYTHING); \
if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \ if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \
CALLFunc( (uptr)f ); \ CALLFunc( (uptr)Interpreter::OpcodeImpl::f ); \
} }
#define REC_SYS( f ) \ #define REC_SYS( f ) \
@ -152,9 +106,6 @@ void iFlushCall(int flushtype);
void SaveCW(); void SaveCW();
void LoadCW(); void LoadCW();
extern void (*recBSC[64])();
extern void (*recSPC[64])();
extern void (*recREG[32])();
extern void (*recCP0[32])(); extern void (*recCP0[32])();
extern void (*recCP0BC0[32])(); extern void (*recCP0BC0[32])();
extern void (*recCP0C0[64])(); extern void (*recCP0C0[64])();
@ -162,11 +113,13 @@ extern void (*recCP1[32])();
extern void (*recCP1BC1[32])(); extern void (*recCP1BC1[32])();
extern void (*recCP1S[64])(); extern void (*recCP1S[64])();
extern void (*recCP1W[64])(); extern void (*recCP1W[64])();
extern void (*recMMIt[64])();
extern void (*recMMI0t[32])(); namespace EE { namespace Dynarec {
extern void (*recMMI1t[32])();
extern void (*recMMI2t[32])(); extern void (*recBSC_co[64])();
extern void (*recMMI3t[32])(); void recBranchCall( void (*func)() );
} }
u32* _eeGetConstReg(int reg); // gets a memory pointer to the constant reg u32* _eeGetConstReg(int reg); // gets a memory pointer to the constant reg
@ -193,20 +146,6 @@ void rec##fn(void) \
eeRecompileCode0(rec##fn##_const, rec##fn##_consts, rec##fn##_constt, rec##fn##_, xmminfo); \ eeRecompileCode0(rec##fn##_const, rec##fn##_consts, rec##fn##_constt, rec##fn##_, xmminfo); \
} }
#define EERECOMPILE_CODE0_PENALTY(fn, xmminfo, cycles) \
void rec##fn(void) \
{ \
eeRecompileCode0(rec##fn##_const, rec##fn##_consts, rec##fn##_constt, rec##fn##_, xmminfo); \
g_eeCyclePenalty = (cycles); \
}
#define EERECOMPILE_CODE0_PENALTY(fn, xmminfo, cycles) \
void rec##fn(void) \
{ \
eeRecompileCode0(rec##fn##_const, rec##fn##_consts, rec##fn##_constt, rec##fn##_, xmminfo); \
g_eeCyclePenalty = (cycles); \
}
#define EERECOMPILE_CODEX(codename, fn) \ #define EERECOMPILE_CODEX(codename, fn) \
void rec##fn(void) \ void rec##fn(void) \
{ \ { \
@ -298,13 +237,6 @@ void rec##fn(void) \
eeFPURecompileCode(rec##fn##_xmm, fn, xmminfo); \ eeFPURecompileCode(rec##fn##_xmm, fn, xmminfo); \
} }
#define FPURECOMPILE_CONSTCODE_PENALTY(fn, xmminfo, cycles) \
void rec##fn(void) \
{ \
eeFPURecompileCode(rec##fn##_xmm, fn, xmminfo); \
g_eeCyclePenalty = (cycles); \
}
// rd = rs op rt (all regs need to be in xmm) // rd = rs op rt (all regs need to be in xmm)
int eeRecompileCodeXMM(int xmminfo); int eeRecompileCodeXMM(int xmminfo);
void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo); void eeFPURecompileCode(R5900FNPTR_INFO xmmcode, R5900FNPTR fpucode, int xmminfo);
@ -356,4 +288,13 @@ protected:
}; };
// perf counters
#ifdef PCSX2_DEVBUILD
extern void StartPerfCounter();
extern void StopPerfCounter();
#else
#define StartPerfCounter()
#define StopPerfCounter()
#endif
#endif // __IR5900_H__ #endif // __IR5900_H__

View File

@ -19,27 +19,26 @@
#ifndef __IR5900ARIT_H__ #ifndef __IR5900ARIT_H__
#define __IR5900ARIT_H__ #define __IR5900ARIT_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Register arithmetic * * Register arithmetic *
* Format: OP rd, rs, rt * * Format: OP rd, rs, rt *
*********************************************************/ *********************************************************/
void recADD( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recADDU( void ); {
void recDADD( void ); void recADD( void );
void recDADDU( void ); void recADDU( void );
void recSUB( void ); void recDADD( void );
void recSUBU( void ); void recDADDU( void );
void recDSUB( void ); void recSUB( void );
void recDSUBU( void ); void recSUBU( void );
void recAND( void ); void recDSUB( void );
void recOR( void ); void recDSUBU( void );
void recXOR( void ); void recAND( void );
void recNOR( void ); void recOR( void );
void recSLT( void ); void recXOR( void );
void recSLTU( void ); void recNOR( void );
void recSLT( void );
void recSLTU( void );
} } }
#endif #endif

View File

@ -19,23 +19,22 @@
#ifndef __IR5900ARITIMM_H__ #ifndef __IR5900ARITIMM_H__
#define __IR5900ARITIMM_H__ #define __IR5900ARITIMM_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Arithmetic with immediate operand * * Arithmetic with immediate operand *
* Format: OP rt, rs, immediate * * Format: OP rt, rs, immediate *
*********************************************************/ *********************************************************/
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
void recADDI( void );
void recADDIU( void );
void recDADDI( void );
void recDADDIU( void );
void recANDI( void );
void recORI( void );
void recXORI( void );
void recADDI( void ); void recSLTI( void );
void recADDIU( void ); void recSLTIU( void );
void recDADDI( void ); } } }
void recDADDIU( void );
void recANDI( void );
void recORI( void );
void recXORI( void );
void recSLTI( void );
void recSLTIU( void );
#endif #endif

View File

@ -19,29 +19,29 @@
#ifndef __IR5900BRANCH_H__ #ifndef __IR5900BRANCH_H__
#define __IR5900BRANCH_H__ #define __IR5900BRANCH_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Shift arithmetic with constant shift * * Shift arithmetic with constant shift *
* Format: OP rd, rt, sa * * Format: OP rd, rt, sa *
*********************************************************/ *********************************************************/
void recBEQ( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recBEQL( void ); {
void recBNE( void ); void recBEQ( void );
void recBNEL( void ); void recBEQL( void );
void recBLTZ( void ); void recBNE( void );
void recBLTZL( void ); void recBNEL( void );
void recBLTZAL( void ); void recBLTZ( void );
void recBLTZALL( void ); void recBLTZL( void );
void recBGTZ( void ); void recBLTZAL( void );
void recBGTZL( void ); void recBLTZALL( void );
void recBLEZ( void ); void recBGTZ( void );
void recBLEZL( void ); void recBGTZL( void );
void recBGEZ( void ); void recBLEZ( void );
void recBGEZL( void ); void recBLEZL( void );
void recBGEZAL( void ); void recBGEZ( void );
void recBGEZALL( void ); void recBGEZL( void );
void recBGEZAL( void );
void recBGEZALL( void );
} } }
#endif #endif

View File

@ -19,17 +19,17 @@
#ifndef __IR5900JUMP_H__ #ifndef __IR5900JUMP_H__
#define __IR5900JUMP_H__ #define __IR5900JUMP_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Jump to target * * Jump to target *
* Format: OP target * * Format: OP target *
*********************************************************/ *********************************************************/
void recJ( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recJAL( void ); {
void recJR( void ); void recJ( void );
void recJALR( void ); void recJAL( void );
void recJR( void );
void recJALR( void );
} } }
#endif #endif

View File

@ -23,68 +23,71 @@
* Format: OP rt, offset(base) * * Format: OP rt, offset(base) *
*********************************************************/ *********************************************************/
void recLB( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recLBU( void ); {
void recLH( void ); void recLB( void );
void recLHU( void ); void recLBU( void );
void recLW( void ); void recLH( void );
void recLWU( void ); void recLHU( void );
void recLWL( void ); void recLW( void );
void recLWR( void ); void recLWU( void );
void recLD( void ); void recLWL( void );
void recLDR( void ); void recLWR( void );
void recLDL( void ); void recLD( void );
void recLQ( void ); void recLDR( void );
void recSB( void ); void recLDL( void );
void recSH( void ); void recLQ( void );
void recSW( void ); void recSB( void );
void recSWL( void ); void recSH( void );
void recSWR( void ); void recSW( void );
void recSD( void ); void recSWL( void );
void recSDL( void ); void recSWR( void );
void recSDR( void ); void recSD( void );
void recSQ( void ); void recSDL( void );
void recLWC1( void ); void recSDR( void );
void recSWC1( void ); void recSQ( void );
void recLQC2( void ); void recLWC1( void );
void recSQC2( void ); void recSWC1( void );
void recLQC2( void );
void recSQC2( void );
// coissues // coissues
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
void recLB_co( void ); void recLB_co( void );
void recLBU_co( void ); void recLBU_co( void );
void recLH_co( void ); void recLH_co( void );
void recLHU_co( void ); void recLHU_co( void );
void recLW_co( void ); void recLW_co( void );
void recLWU_co( void ); void recLWU_co( void );
void recLWL_co( void ); void recLWL_co( void );
void recLWR_co( void ); void recLWR_co( void );
void recLD_co( void ); void recLD_co( void );
void recLDR_co( void ); void recLDR_co( void );
void recLDL_co( void ); void recLDL_co( void );
void recLQ_co( void ); void recLQ_co( void );
void recSB_co( void ); void recSB_co( void );
void recSH_co( void ); void recSH_co( void );
void recSW_co( void ); void recSW_co( void );
void recSWL_co( void ); void recSWL_co( void );
void recSWR_co( void ); void recSWR_co( void );
void recSD_co( void ); void recSD_co( void );
void recSDL_co( void ); void recSDL_co( void );
void recSDR_co( void ); void recSDR_co( void );
void recSQ_co( void ); void recSQ_co( void );
void recLWC1_co( void ); void recLWC1_co( void );
void recSWC1_co( void ); void recSWC1_co( void );
void recLQC2_co( void ); void recLQC2_co( void );
void recSQC2_co( void ); void recSQC2_co( void );
// coissue-X
void recLD_coX(int num);
void recLQ_coX(int num);
void recLWC1_coX(int num);
void recSD_coX(int num, int align);
void recSQ_coX(int num);
void recSWC1_coX(int num);
// coissue-X
void recLD_coX(int num);
void recLQ_coX(int num);
void recLWC1_coX(int num);
void recSD_coX(int num, int align);
void recSQ_coX(int num);
void recSWC1_coX(int num);
#endif #endif
} } }
#endif #endif

View File

@ -19,15 +19,15 @@
#ifndef __IR5900MOVE_H__ #ifndef __IR5900MOVE_H__
#define __IR5900MOVE_H__ #define __IR5900MOVE_H__
#include "Common.h" namespace EE { namespace Dynarec { namespace OpcodeImpl
#include "InterTables.h" {
void recLUI( void );
void recLUI( void ); void recMFLO( void );
void recMFLO( void ); void recMFHI( void );
void recMFHI( void ); void recMTLO( void );
void recMTLO( void ); void recMTHI( void );
void recMTHI( void ); void recMOVN( void );
void recMOVN( void ); void recMOVZ( void );
void recMOVZ( void ); } } }
#endif #endif

View File

@ -19,17 +19,17 @@
#ifndef __IR5900MULTDIV_H__ #ifndef __IR5900MULTDIV_H__
#define __IR5900MULTDIV_H__ #define __IR5900MULTDIV_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Register mult/div & Register trap logic * * Register mult/div & Register trap logic *
* Format: OP rs, rt * * Format: OP rs, rt *
*********************************************************/ *********************************************************/
void recMULT( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recMULTU( void ); {
void recDIV( void ); void recMULT( void );
void recDIVU( void ); void recMULTU( void );
void recDIV( void );
void recDIVU( void );
} } }
#endif #endif

View File

@ -19,29 +19,29 @@
#ifndef __IR5900SHIFT_H__ #ifndef __IR5900SHIFT_H__
#define __IR5900SHIFT_H__ #define __IR5900SHIFT_H__
#include "Common.h"
#include "InterTables.h"
/********************************************************* /*********************************************************
* Shift arithmetic with constant shift * * Shift arithmetic with constant shift *
* Format: OP rd, rt, sa * * Format: OP rd, rt, sa *
*********************************************************/ *********************************************************/
void recSLL( void ); namespace EE { namespace Dynarec { namespace OpcodeImpl
void recSRL( void ); {
void recSRA( void ); void recSLL( void );
void recDSLL( void ); void recSRL( void );
void recDSRL( void ); void recSRA( void );
void recDSRA( void ); void recDSLL( void );
void recDSLL32( void ); void recDSRL( void );
void recDSRL32( void ); void recDSRA( void );
void recDSRA32( void ); void recDSLL32( void );
void recDSRL32( void );
void recDSRA32( void );
void recSLLV( void ); void recSLLV( void );
void recSRLV( void ); void recSRLV( void );
void recSRAV( void ); void recSRAV( void );
void recDSLLV( void ); void recDSLLV( void );
void recDSRLV( void ); void recDSRLV( void );
void recDSRAV( void ); void recDSRAV( void );
} } }
#endif #endif

View File

@ -43,6 +43,7 @@
#include "iR5900.h" #include "iR5900.h"
#include "iVUzerorec.h" #include "iVUzerorec.h"
#include "SamplProf.h"
// temporary externs // temporary externs
extern u32 vudump; extern u32 vudump;
@ -338,6 +339,7 @@ void SuperVUInit(int vuindex)
s_recVUMem = (u8*)SysMmap(0x0c000000, VU_EXESIZE); s_recVUMem = (u8*)SysMmap(0x0c000000, VU_EXESIZE);
if( (uptr)s_recVUMem > 0x80000000 ) if( (uptr)s_recVUMem > 0x80000000 )
SysPrintf("bad SuperVU alloc %x\n", s_recVUMem); SysPrintf("bad SuperVU alloc %x\n", s_recVUMem);
ProfilerRegisterSource("VURec",s_recVUMem, VU_EXESIZE);
memset(s_recVUMem, 0xcd, VU_EXESIZE); memset(s_recVUMem, 0xcd, VU_EXESIZE);
s_recVUPtr = s_recVUMem; s_recVUPtr = s_recVUMem;
recVUStack = new u8[SUPERVU_STACKSIZE * 4]; recVUStack = new u8[SUPERVU_STACKSIZE * 4];

View File

@ -17,7 +17,7 @@
*/ */
// stop compiling if NORECBUILD build (only for Visual Studio) // stop compiling if NORECBUILD build (only for Visual Studio)
#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD)) #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD) && defined(PCSX2_VIRTUAL_MEM))
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>

View File

@ -44,28 +44,207 @@
#include "iCP0.h" #include "iCP0.h"
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
static void recNULL( void ) void recNULL( void )
{ {
SysPrintf("EE: Unimplemented op %x\n", cpuRegs.code); SysPrintf("EE: Unimplemented op %x\n", cpuRegs.code);
} }
//////////////////////////////////////////////////// namespace EE { namespace Dynarec
static void recREGIMM( void )
{ {
recREG[ _Rt_ ]( ); // 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.
//////////////////////////////////////////////////// branch = 2;
static void recSPECIAL( void ) MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
{ MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
recSPC[ _Funct_ ]( ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
} MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
//////////////////////////////////////////////////// // Might as well flush everything -- it'll all get flushed when the
static void recCOP0( void ) // recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
}
namespace OpcodeImpl
{ {
recCP0[ _Rs_ ]( ); ////////////////////////////////////////////////////
} void recUnknown()
{
// TODO : Unknown ops should throw an exception.
SysPrintf("EE: Unrecognized op %x\n", cpuRegs.code);
}
void recMMI_Unknown()
{
// TODO : Unknown ops should throw an exception.
SysPrintf("EE: Unrecognized MMI op %x\n", cpuRegs.code);
}
////////////////////////////////////////////////////
void recREGIMM( void )
{
EE::OpcodeTables::RegImm[ _Rt_ ].recompile();
}
////////////////////////////////////////////////////
void recSPECIAL( void )
{
EE::OpcodeTables::Special[ _Funct_ ].recompile( );
}
////////////////////////////////////////////////////
void recCOP0( void )
{
recCP0[ _Rs_ ]( );
}
////////////////////////////////////////////////////
void recCOP1( void )
{
recCP1[ _Rs_ ]( );
}
////////////////////////////////////////////////////
void recMMI( void )
{
EE::OpcodeTables::MMI[ _Funct_ ].recompile( );
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
////////////////////////////////////////////////////
//REC_SYS(PREF);
////////////////////////////////////////////////////
//REC_SYS(MFSA);
////////////////////////////////////////////////////
//REC_SYS(MTSA);
////////////////////////////////////////////////////
//REC_SYS(TGE);
////////////////////////////////////////////////////
//REC_SYS(TGEU);
////////////////////////////////////////////////////
//REC_SYS(TLT);
////////////////////////////////////////////////////
//REC_SYS(TLTU);
////////////////////////////////////////////////////
//REC_SYS(TEQ);
////////////////////////////////////////////////////
//REC_SYS(TNE);
////////////////////////////////////////////////////
//REC_SYS(TGEI);
////////////////////////////////////////////////////
//REC_SYS(TGEIU);
////////////////////////////////////////////////////
//REC_SYS(TLTI);
////////////////////////////////////////////////////
//REC_SYS(TLTIU);
////////////////////////////////////////////////////
//REC_SYS(TEQI);
////////////////////////////////////////////////////
//REC_SYS(TNEI);
////////////////////////////////////////////////////
//REC_SYS(MTSAB);
////////////////////////////////////////////////////
//REC_SYS(MTSAH);
////////////////////////////////////////////////////
//REC_SYS(CACHE);
void recCACHE()
{
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)Interpreter::OpcodeImpl::CACHE );
branch = 2;
}
void recTGE( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGE );
}
void recTGEU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEU );
}
void recTLT( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLT );
}
void recTLTU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTU );
}
void recTEQ( void )
{
recBranchCall( Interpreter::OpcodeImpl::TEQ );
}
void recTNE( void )
{
recBranchCall( Interpreter::OpcodeImpl::TNE );
}
void recTGEI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEI );
}
void recTGEIU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEIU );
}
void recTLTI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTI );
}
void recTLTIU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTIU );
}
void recTEQI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TEQI );
}
void recTNEI( void )
{
recBranchCall( 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
} } // End namespace EE::Dynarec
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
static void recCOP0BC0( void ) static void recCOP0BC0( void )
@ -79,195 +258,9 @@ static void recCOP0C0( void )
recCP0C0[ _Funct_ ]( ); recCP0C0[ _Funct_ ]( );
} }
////////////////////////////////////////////////////
static void recCOP1( void ) {
recCP1[ _Rs_ ]( );
}
////////////////////////////////////////////////////
static void recMMI( void )
{
recMMIt[ _Funct_ ]( );
}
// 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.
branch = 2;
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
////////////////////////////////////////////////////
//REC_SYS(PREF);
////////////////////////////////////////////////////
//REC_SYS(MFSA);
////////////////////////////////////////////////////
//REC_SYS(MTSA);
////////////////////////////////////////////////////
//REC_SYS(TGE);
////////////////////////////////////////////////////
//REC_SYS(TGEU);
////////////////////////////////////////////////////
//REC_SYS(TLT);
////////////////////////////////////////////////////
//REC_SYS(TLTU);
////////////////////////////////////////////////////
//REC_SYS(TEQ);
////////////////////////////////////////////////////
//REC_SYS(TNE);
////////////////////////////////////////////////////
//REC_SYS(TGEI);
////////////////////////////////////////////////////
//REC_SYS(TGEIU);
////////////////////////////////////////////////////
//REC_SYS(TLTI);
////////////////////////////////////////////////////
//REC_SYS(TLTIU);
////////////////////////////////////////////////////
//REC_SYS(TEQI);
////////////////////////////////////////////////////
//REC_SYS(TNEI);
////////////////////////////////////////////////////
//REC_SYS(MTSAB);
////////////////////////////////////////////////////
//REC_SYS(MTSAH);
////////////////////////////////////////////////////
REC_SYS(CACHE);
void recTGE( void )
{
recBranchCall( TGE );
}
void recTGEU( void )
{
recBranchCall( TGEU );
}
void recTLT( void )
{
recBranchCall( TLT );
}
void recTLTU( void )
{
recBranchCall( TLTU );
}
void recTEQ( void )
{
recBranchCall( TEQ );
}
void recTNE( void )
{
recBranchCall( TNE );
}
void recTGEI( void )
{
recBranchCall( TGEI );
}
void recTGEIU( void )
{
recBranchCall( TGEIU );
}
void recTLTI( void )
{
recBranchCall( TLTI );
}
void recTLTIU( void )
{
recBranchCall( TLTIU );
}
void recTEQI( void )
{
recBranchCall( TEQI );
}
void recTNEI( void )
{
recBranchCall( TNEI );
}
///////////////////////////////// /////////////////////////////////
// Foward-Prob Function Tables // // Foward-Prob Function Tables //
///////////////////////////////// /////////////////////////////////
extern void recCOP2( void );
extern void recSYSCALL( void );
extern void recBREAK( void );
extern void recPREF( void );
extern void recSYNC( void );
extern void recMFSA( void );
extern void recMTSA( void );
extern void recMTSAB( void );
extern void recMTSAH( void );
void (*recBSC[64] )() = {
recSPECIAL, recREGIMM, recJ, recJAL, recBEQ, recBNE, recBLEZ, recBGTZ,
recADDI, recADDIU, recSLTI, recSLTIU, recANDI, recORI, recXORI, recLUI,
recCOP0, recCOP1, recCOP2, recNULL, recBEQL, recBNEL, recBLEZL, recBGTZL,
recDADDI, recDADDIU, recLDL, recLDR, recMMI, recNULL, recLQ, recSQ,
recLB, recLH, recLWL, recLW, recLBU, recLHU, recLWR, recLWU,
recSB, recSH, recSWL, recSW, recSDL, recSDR, recSWR, recCACHE,
recNULL, recLWC1, recNULL, recPREF, recNULL, recNULL, recLQC2, recLD,
recNULL, recSWC1, recNULL, recNULL, recNULL, recNULL, recSQC2, recSD
};
#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
void (*recSPC[64] )() = {
recSLL, recNULL, recSRL, recSRA, recSLLV, recNULL, recSRLV, recSRAV,
recJR, recJALR, recMOVZ, recMOVN, recSYSCALL, recBREAK, recNULL, recSYNC,
recMFHI, recMTHI, recMFLO, recMTLO, recDSLLV, recNULL, recDSRLV, recDSRAV,
recMULT, recMULTU, recDIV, recDIVU, recNULL, recNULL, recNULL, recNULL,
recADD, recADDU, recSUB, recSUBU, recAND, recOR, recXOR, recNOR,
recMFSA, recMTSA, recSLT, recSLTU, recDADD, recDADDU, recDSUB, recDSUBU,
recTGE, recTGEU, recTLT, recTLTU, recTEQ, recNULL, recTNE, recNULL,
recDSLL, recNULL, recDSRL, recDSRA, recDSLL32, recNULL, recDSRL32, recDSRA32
};
void (*recREG[32] )() = {
recBLTZ, recBGEZ, recBLTZL, recBGEZL, recNULL, recNULL, recNULL, recNULL,
recTGEI, recTGEIU, recTLTI, recTLTIU, recTEQI, recNULL, recTNEI, recNULL,
recBLTZAL, recBGEZAL, recBLTZALL, recBGEZALL, recNULL, recNULL, recNULL, recNULL,
recMTSAB, recMTSAH, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
};
void (*recCP0[32] )() = { void (*recCP0[32] )() = {
recMFC0, recNULL, recNULL, recNULL, recMTC0, recNULL, recNULL, recNULL, recMFC0, recNULL, recNULL, recNULL, recMTC0, recNULL, recNULL, recNULL,
@ -330,61 +323,6 @@ void (*recCP1W[64] )() = {
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
}; };
void (*recMMIt[64] )() = {
recMADD, recMADDU, recNULL, recNULL, recPLZCW, recNULL, recNULL, recNULL,
recMMI0, recMMI2, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recMFHI1, recMTHI1, recMFLO1, recMTLO1, recNULL, recNULL, recNULL, recNULL,
recMULT1, recMULTU1, recDIV1, recDIVU1, recNULL, recNULL, recNULL, recNULL,
recMADD1, recMADDU1, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recMMI1 , recMMI3, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recPMFHL, recPMTHL, recNULL, recNULL, recPSLLH, recNULL, recPSRLH, recPSRAH,
recNULL, recNULL, recNULL, recNULL, recPSLLW, recNULL, recPSRLW, recPSRAW,
};
void (*recMMI0t[32] )() = {
recPADDW, recPSUBW, recPCGTW, recPMAXW,
recPADDH, recPSUBH, recPCGTH, recPMAXH,
recPADDB, recPSUBB, recPCGTB, recNULL,
recNULL, recNULL, recNULL, recNULL,
recPADDSW, recPSUBSW, recPEXTLW, recPPACW,
recPADDSH, recPSUBSH, recPEXTLH, recPPACH,
recPADDSB, recPSUBSB, recPEXTLB, recPPACB,
recNULL, recNULL, recPEXT5, recPPAC5,
};
void (*recMMI1t[32] )() = {
recNULL, recPABSW, recPCEQW, recPMINW,
recPADSBH, recPABSH, recPCEQH, recPMINH,
recNULL, recNULL, recPCEQB, recNULL,
recNULL, recNULL, recNULL, recNULL,
recPADDUW, recPSUBUW, recPEXTUW, recNULL,
recPADDUH, recPSUBUH, recPEXTUH, recNULL,
recPADDUB, recPSUBUB, recPEXTUB, recQFSRV,
recNULL, recNULL, recNULL, recNULL,
};
void (*recMMI2t[32] )() = {
recPMADDW, recNULL, recPSLLVW, recPSRLVW,
recPMSUBW, recNULL, recNULL, recNULL,
recPMFHI, recPMFLO, recPINTH, recNULL,
recPMULTW, recPDIVW, recPCPYLD, recNULL,
recPMADDH, recPHMADH, recPAND, recPXOR,
recPMSUBH, recPHMSBH, recNULL, recNULL,
recNULL, recNULL, recPEXEH, recPREVH,
recPMULTH, recPDIVBW, recPEXEW, recPROT3W,
};
void (*recMMI3t[32] )() = {
recPMADDUW, recNULL, recNULL, recPSRAVW,
recNULL, recNULL, recNULL, recNULL,
recPMTHI, recPMTLO, recPINTEH, recNULL,
recPMULTUW, recPDIVUW, recPCPYUD, recNULL,
recNULL, recNULL, recPOR, recPNOR,
recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recPEXCH, recPCPYH,
recNULL, recNULL, recPEXCW, recNULL,
};
//////////////////////////////////////////////// ////////////////////////////////////////////////
// Back-Prob Function Tables - Gathering Info // // Back-Prob Function Tables - Gathering Info //
//////////////////////////////////////////////// ////////////////////////////////////////////////

View File

@ -28,6 +28,7 @@
#include <assert.h> #include <assert.h>
#include <malloc.h> #include <malloc.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string>
#include "Common.h" #include "Common.h"
#include "Memory.h" #include "Memory.h"
@ -53,6 +54,9 @@
#include "iVUzerorec.h" #include "iVUzerorec.h"
#include "vtlb.h"
#include "SamplProf.h"
#ifdef _WIN32 #ifdef _WIN32
#pragma warning(disable:4244) #pragma warning(disable:4244)
#pragma warning(disable:4761) #pragma warning(disable:4761)
@ -81,13 +85,11 @@ bool g_EEFreezeRegs = false; // if set, should freeze the regs
static BASEBLOCK* s_pCurBlock = NULL; static BASEBLOCK* s_pCurBlock = NULL;
static BASEBLOCKEX* s_pCurBlockEx = NULL; static BASEBLOCKEX* s_pCurBlockEx = NULL;
static BASEBLOCK* s_pDispatchBlock = NULL; static BASEBLOCK* s_pDispatchBlock = NULL;
static u32 s_nEndBlock = 0; // what pc the current block ends static u32 s_nEndBlock = 0; // what pc the current block ends
static u32 s_nHasDelay = 0;
static u32 s_nNextBlock = 0; // next free block in recBlocks static u32 s_nNextBlock = 0; // next free block in recBlocks
extern void (*recBSC[64])();
extern void (*recBSC_co[64])();
// save states for branches // save states for branches
static u16 s_savex86FpuState, s_saveiCWstate; static u16 s_savex86FpuState, s_saveiCWstate;
static GPR_reg64 s_ConstGPRreg; static GPR_reg64 s_ConstGPRreg;
@ -95,13 +97,13 @@ static u32 s_saveConstGPRreg = 0, s_saveHasConstReg = 0, s_saveFlushedConstReg =
static EEINST* s_psaveInstInfo = NULL; static EEINST* s_psaveInstInfo = NULL;
u32 s_nBlockCycles = 0; // cycles of current block recompiling u32 s_nBlockCycles = 0; // cycles of current block recompiling
u32 g_eeCyclePenalty; // cycle penalty of the current recompiled instruction
static u32 s_savenBlockCycles = 0; static u32 s_savenBlockCycles = 0;
void recCOP2RecompileInst(); void recCOP2RecompileInst();
int recCOP2AnalyzeBlock(u32 startpc, u32 endpc); int recCOP2AnalyzeBlock(u32 startpc, u32 endpc);
void recCOP2EndBlock(void); void recCOP2EndBlock(void);
u8* dyna_block_discard_recmem=0;
#ifdef _DEBUG #ifdef _DEBUG
u32 dumplog = 0; u32 dumplog = 0;
@ -117,10 +119,10 @@ LARGE_INTEGER lbase = {0}, lfinal = {0};
//static u32 s_startcount = 0; //static u32 s_startcount = 0;
//#endif //#endif
const char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n"; static const char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
const char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n"; static const char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n";
const char *txt1 = "REG[%d] = %x_%x\n"; static const char *txt1 = "REG[%d] = %x_%x\n";
const char *txt2 = "M32 = %x\n"; static const char *txt2 = "M32 = %x\n";
void _cop2AnalyzeOp(EEINST* pinst, int dostalls); // reccop2.c void _cop2AnalyzeOp(EEINST* pinst, int dostalls); // reccop2.c
static void iBranchTest(u32 newpc, u32 cpuBranch); static void iBranchTest(u32 newpc, u32 cpuBranch);
@ -173,10 +175,13 @@ static void iDumpBlock( int startpc, u8 * ptr )
f = fopen( filename, "w" ); f = fopen( filename, "w" );
std::string output;
if( disR5900GetSym(startpc) != NULL ) if( disR5900GetSym(startpc) != NULL )
fprintf(f, "%s\n", disR5900GetSym(startpc)); fprintf(f, "%s\n", disR5900GetSym(startpc));
for ( i = startpc; i < s_nEndBlock; i += 4 ) { for ( i = startpc; i < s_nEndBlock; i += 4 ) {
fprintf( f, "%s\n", disR5900Fasm( PSMu32( i ), i ) ); disR5900Fasm( output, PSMu32( i ), i );
fprintf( f, output.c_str() );
} }
// write the instruction info // write the instruction info
@ -1482,6 +1487,7 @@ void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR)
} }
#define REC_CACHEMEM 0x01000000 #define REC_CACHEMEM 0x01000000
void __fastcall dyna_block_discard(u32 start,u32 sz);
int recInit( void ) int recInit( void )
{ {
@ -1492,8 +1498,8 @@ int recInit( void )
memset( recLUT, 0, 0x010000 * sizeof(uptr) ); memset( recLUT, 0, 0x010000 * sizeof(uptr) );
// can't have upper 4 bits nonzero! // can't have upper 4 bits nonzero!
recMem = (u8*)SysMmap(0x0d000000, REC_CACHEMEM); recMem = (u8*)SysMmap(0x0d000000, REC_CACHEMEM+0x1000); // +0x1000 ? vtlb check.
ProfilerRegisterSource("EERec",recMem, REC_CACHEMEM+0x1000);
// 32 alignment necessary // 32 alignment necessary
recRAM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x02000000 , 4*sizeof(BASEBLOCK)); recRAM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x02000000 , 4*sizeof(BASEBLOCK));
recROM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00400000 , 4*sizeof(BASEBLOCK)); recROM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x00400000 , 4*sizeof(BASEBLOCK));
@ -1536,6 +1542,12 @@ int recInit( void )
memset(recMem, 0xcd, REC_CACHEMEM); memset(recMem, 0xcd, REC_CACHEMEM);
memset(recStack, 0, RECSTACK_SIZE); memset(recStack, 0, RECSTACK_SIZE);
x86SetPtr(recMem+REC_CACHEMEM);
dyna_block_discard_recmem=(u8*)x86Ptr;
JMP32( (uptr)&dyna_block_discard - ( (u32)x86Ptr + 5 ));
// SSE3 detection, manually create the code // SSE3 detection, manually create the code
x86SetPtr(recMem); x86SetPtr(recMem);
SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0); SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0);
@ -1611,6 +1623,9 @@ static void recReset( void ) {
memset( recBlocks, 0, sizeof(BASEBLOCKEX)*EE_NUMBLOCKS ); memset( recBlocks, 0, sizeof(BASEBLOCKEX)*EE_NUMBLOCKS );
if( s_pInstCache ) memset( s_pInstCache, 0, sizeof(EEINST)*s_nInstCacheSize ); if( s_pInstCache ) memset( s_pInstCache, 0, sizeof(EEINST)*s_nInstCacheSize );
ResetBaseBlockEx(0); ResetBaseBlockEx(0);
#ifndef PCSX2_VIRTUAL_MEM
mmap_ResetBlockTracking();
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
__asm emms; __asm emms;
@ -1973,24 +1988,6 @@ void StopPerfCounter()
#endif #endif
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recClear64(BASEBLOCK* p)
{
int left = 4 - ((u32)p % 16)/sizeof(BASEBLOCK);
recClearMem(p);
if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1);
}
void recClear128(BASEBLOCK* p)
{
int left = 4 - ((u32)p % 32)/sizeof(BASEBLOCK);
recClearMem(p);
if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1);
if( left > 2 && *(u32*)(p+2) ) recClearMem(p+2);
if( left > 3 && *(u32*)(p+3) ) recClearMem(p+3);
}
void recClear( u32 Addr, u32 Size ) void recClear( u32 Addr, u32 Size )
{ {
u32 i; u32 i;
@ -2268,20 +2265,20 @@ static u32 eeScaleBlockCycles()
if( s_nBlockCycles <= (5<<3) || !CHECK_EESYNC_HACK ) return s_nBlockCycles >> 3; if( s_nBlockCycles <= (5<<3) || !CHECK_EESYNC_HACK ) return s_nBlockCycles >> 3;
u32 scalar = CHECK_EE_IOP_EXTRA ? 14 : 9; // 3.5 and 2.25 scales (4 bit fixed) u32 scalar = CHECK_EE_IOP_EXTRA ? 16 : 10; // 4.0 and 2.25 scales (4 bit fixed)
if( s_nBlockCycles <= (10<<3) ) if( s_nBlockCycles <= (10<<3) )
{ {
// Mid-size blocks should get a mid-sized scale: // Mid-size blocks should get a mid-sized scale:
// (using an additional 2 bits fixed point math here) // (using an additional 2 bits fixed point math here)
scalar = CHECK_EE_IOP_EXTRA ? 9 : 7; // 2.25 and 1.75 scales scalar = CHECK_EE_IOP_EXTRA ? 10 : 7; // 2.50 and 1.75 scales
} }
else if( s_nBlockCycles >= (22<<3) ) else if( s_nBlockCycles >= (22<<3) )
{ {
// larger blocks get a smaller scalar as well, to help keep // larger blocks get a smaller scalar as well, to help keep
// them from becoming "too fat" and delaying branch tests. // them from becoming "too fat" and delaying branch tests.
scalar = CHECK_EE_IOP_EXTRA ? 10 : 7; // 2.5 and 1.75 scales scalar = CHECK_EE_IOP_EXTRA ? 11 : 8; // 2.5 and 2.0 scales
} }
s_nBlockCycles *= scalar; s_nBlockCycles *= scalar;
@ -2321,6 +2318,8 @@ static void iBranchTest(u32 newpc, u32 cpuBranch)
x86SetJ8( j8Ptr[0] ); x86SetJ8( j8Ptr[0] );
} }
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
#ifndef CP2_RECOMPILE #ifndef CP2_RECOMPILE
@ -2331,7 +2330,7 @@ REC_SYS(COP2);
void recCOP2( void ) void recCOP2( void )
{ {
CPU_LOG( "Recompiling COP2:%s\n", disR5900Fasm( cpuRegs.code, cpuRegs.pc ) ); CPU_LOG( "Recompiling COP2:%s\n", disR5900Current.getString() );
recCOP22( ); recCOP22( );
} }
@ -2342,7 +2341,7 @@ void recSYSCALL( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_NODESTROY); iFlushCall(FLUSH_NODESTROY);
CALLFunc( (uptr)SYSCALL ); CALLFunc( (uptr)Interpreter::OpcodeImpl::SYSCALL );
CMP32ItoM((uptr)&cpuRegs.pc, pc); CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0); j8Ptr[0] = JE8(0);
@ -2357,7 +2356,7 @@ void recBREAK( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc ); MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)BREAK ); CALLFunc( (uptr)EE::Interpreter::OpcodeImpl::BREAK );
CMP32ItoM((uptr)&cpuRegs.pc, pc); CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0); j8Ptr[0] = JE8(0);
@ -2461,6 +2460,8 @@ void recMTSAH( void )
} }
} }
}}} // end Namespace EE::Dynarec::OpcodeImpl
static void checkcodefn() static void checkcodefn()
{ {
int pctemp; int pctemp;
@ -2556,7 +2557,6 @@ void recompileNextInstruction(int delayslot)
#endif #endif
cpuRegs.code = *(int *)s_pCode; cpuRegs.code = *(int *)s_pCode;
s_nBlockCycles += InstCycles_Default;
pc += 4; pc += 4;
//#ifdef _DEBUG //#ifdef _DEBUG
@ -2608,38 +2608,32 @@ void recompileNextInstruction(int delayslot)
} }
} }
const EE::OPCODE& opcode = EE::GetCurrentInstruction();
// peephole optimizations // peephole optimizations
if( g_pCurInstInfo->info & EEINSTINFO_COREC ) { if( g_pCurInstInfo->info & EEINSTINFO_COREC ) {
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
if( g_pCurInstInfo->numpeeps > 1 ) { if( g_pCurInstInfo->numpeeps > 1 ) {
g_eeCyclePenalty = InstCycles_Store; switch(_Opcode_) {
switch(cpuRegs.code>>26) { case 30: EE::Dynarec::OpcodeImpl::recLQ_coX(g_pCurInstInfo->numpeeps); break;
case 30: recLQ_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break; case 31: EE::Dynarec::OpcodeImpl::recSQ_coX(g_pCurInstInfo->numpeeps); break;
case 31: recSQ_coX(g_pCurInstInfo->numpeeps); break; case 49: EE::Dynarec::OpcodeImpl::recLWC1_coX(g_pCurInstInfo->numpeeps); break;
case 49: recLWC1_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break; case 57: EE::Dynarec::OpcodeImpl::recSWC1_coX(g_pCurInstInfo->numpeeps); break;
case 57: recSWC1_coX(g_pCurInstInfo->numpeeps); break; case 55: EE::Dynarec::OpcodeImpl::recLD_coX(g_pCurInstInfo->numpeeps); break;
case 55: recLD_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break; case 63: EE::Dynarec::OpcodeImpl::recSD_coX(g_pCurInstInfo->numpeeps, 1); break; //not sure if should be set to 1 or 0; looks like "1" handles alignment, so i'm going with that for now
case 63: recSD_coX(g_pCurInstInfo->numpeeps, 1); break; //not sure if should be set to 1 or 0; looks like "1" handles alignment, so i'm going with that for now
default: default:
assert(0); assert(0);
} }
pc += g_pCurInstInfo->numpeeps*4; pc += g_pCurInstInfo->numpeeps*4;
s_nBlockCycles += g_pCurInstInfo->numpeeps * (g_eeCyclePenalty+InstCycles_Default); s_nBlockCycles += (g_pCurInstInfo->numpeeps+1) * opcode.cycles;
g_pCurInstInfo += g_pCurInstInfo->numpeeps; g_pCurInstInfo += g_pCurInstInfo->numpeeps;
} }
else { else {
g_eeCyclePenalty = 0; EE::Dynarec::recBSC_co[_Opcode_]();
recBSC_co[cpuRegs.code>>26]();
pc += 4; pc += 4;
g_pCurInstInfo++; g_pCurInstInfo++;
s_nBlockCycles += opcode.cycles*2;
// ugh! we're actually writing two instructions as one load/store opt here,
// so we need to factor the cycle penalty*2, and add 1 for the actual instruction
// base cycle counter. And to confuse further, the blockcycle count was already
// updated above, for the current instruction.
s_nBlockCycles += (g_eeCyclePenalty*2) + InstCycles_Default;
} }
#else #else
assert(0); assert(0);
@ -2650,7 +2644,7 @@ void recompileNextInstruction(int delayslot)
// if this instruction is a jump or a branch, exit right away // if this instruction is a jump or a branch, exit right away
if( delayslot ) { if( delayslot ) {
switch(cpuRegs.code>>26) { switch(_Opcode_) {
case 1: case 1:
switch(_Rt_) { switch(_Rt_) {
case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13: case 0: case 1: case 2: case 3: case 0x10: case 0x11: case 0x12: case 0x13:
@ -2670,9 +2664,8 @@ void recompileNextInstruction(int delayslot)
return; return;
} }
} }
g_eeCyclePenalty = 0; opcode.recompile();
recBSC[ cpuRegs.code >> 26 ](); s_nBlockCycles += opcode.cycles;
s_nBlockCycles += g_eeCyclePenalty;
} }
if( !delayslot ) { if( !delayslot ) {
@ -2735,10 +2728,10 @@ extern int rdram_sdevid;
void iDumpRegisters(u32 startpc, u32 temp) void iDumpRegisters(u32 startpc, u32 temp)
{ {
int i; int i;
char* pstr;// = temp ? "t" : ""; const char* pstr;// = temp ? "t" : "";
const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 }; const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 };
extern const char *disRNameGPR[]; extern const char *disRNameGPR[];
char* psymb; const char* psymb;
if (temp) if (temp)
pstr = "t"; pstr = "t";
@ -2816,6 +2809,12 @@ void badespfn() {
#define OPTIMIZE_COP2 0//CHECK_VU0REC #define OPTIMIZE_COP2 0//CHECK_VU0REC
void __fastcall dyna_block_discard(u32 start,u32 sz)
{
SysPrintf("dyna_block_discard %08X , count %d\n",start,sz);
Cpu->Clear(start,sz);
return;
}
void recRecompile( u32 startpc ) void recRecompile( u32 startpc )
{ {
u32 i = 0; u32 i = 0;
@ -2950,6 +2949,7 @@ void recRecompile( u32 startpc )
// go until the next branch // go until the next branch
i = startpc; i = startpc;
s_nEndBlock = 0xffffffff; s_nEndBlock = 0xffffffff;
s_nHasDelay = 0;
while(1) { while(1) {
BASEBLOCK* pblock = PC_GETBLOCK(i); BASEBLOCK* pblock = PC_GETBLOCK(i);
@ -2962,7 +2962,7 @@ void recRecompile( u32 startpc )
break; break;
} }
} }
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
cpuRegs.code = *(int *)PSM(i); cpuRegs.code = *(int *)PSM(i);
switch(cpuRegs.code >> 26) { switch(cpuRegs.code >> 26) {
@ -2970,6 +2970,7 @@ void recRecompile( u32 startpc )
if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR
s_nEndBlock = i + 8; s_nEndBlock = i + 8;
s_nHasDelay = 1;
goto StartRecomp; goto StartRecomp;
} }
@ -2978,6 +2979,8 @@ void recRecompile( u32 startpc )
if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) { if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) {
// branches // branches
if( _Rt_ == 2 || _Rt_ == 3 || _Rt_ == 18 || _Rt_ == 19 ) s_nHasDelay = 1;
else s_nHasDelay = 2;
branchTo = _Imm_ * 4 + i + 4; branchTo = _Imm_ * 4 + i + 4;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
@ -2990,6 +2993,7 @@ void recRecompile( u32 startpc )
case 2: // J case 2: // J
case 3: // JAL case 3: // JAL
s_nHasDelay = 1;
s_nEndBlock = i + 8; s_nEndBlock = i + 8;
goto StartRecomp; goto StartRecomp;
@ -2997,6 +3001,9 @@ void recRecompile( u32 startpc )
case 4: case 5: case 6: case 7: case 4: case 5: case 6: case 7:
case 20: case 21: case 22: case 23: case 20: case 21: case 22: case 23:
if( (cpuRegs.code >> 26) >= 20 ) s_nHasDelay = 1;
else s_nHasDelay = 2;
branchTo = _Imm_ * 4 + i + 4; branchTo = _Imm_ * 4 + i + 4;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
else s_nEndBlock = i+8; else s_nEndBlock = i+8;
@ -3017,6 +3024,8 @@ void recRecompile( u32 startpc )
if( _Rs_ == 8 ) { if( _Rs_ == 8 ) {
// BC1F, BC1T, BC1FL, BC1TL // BC1F, BC1T, BC1FL, BC1TL
// BC2F, BC2T, BC2FL, BC2TL // BC2F, BC2T, BC2FL, BC2TL
if( _Rt_ >= 2 ) s_nHasDelay = 1;
else s_nHasDelay = 2;
branchTo = _Imm_ * 4 + i + 4; branchTo = _Imm_ * 4 + i + 4;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo; if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
@ -3092,7 +3101,7 @@ StartRecomp:
if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) { if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) {
u32 curcode = cpuRegs.code; u32 curcode = cpuRegs.code;
u32 nextcode = *(u32*)PSM(i+4); u32 nextcode = *(u32*)PSM(i+4);
if( _eeIsLoadStoreCoIssue(curcode, nextcode) && recBSC_co[curcode>>26] != NULL ) { if( _eeIsLoadStoreCoIssue(curcode, nextcode) && EE::Dynarec::recBSC_co[curcode>>26] != NULL ) {
// rs has to be the same, and cannot be just written // rs has to be the same, and cannot be just written
if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) { if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) {
@ -3218,6 +3227,60 @@ StartRecomp:
iDumpBlock(startpc, recPtr); iDumpBlock(startpc, recPtr);
#endif #endif
u32 sz=(s_nEndBlock-startpc)>>2;
#ifdef lulz
/*
Block checking (ADDED BY RAZ-TEMP)
*/
MOV32ItoR(ECX,startpc);
MOV32ItoR(EDX,sz);
#endif
u32 inpage_offs=startpc&0xFFF;
u32 inpage_ptr=startpc;
u32 inpage_sz=sz*4;
MOV32ItoR(ECX,startpc);
MOV32ItoR(EDX,sz);
#ifndef PCSX2_VIRTUAL_MEM
while(inpage_sz)
{
int PageType=mmap_GetRamPageInfo((u32*)PSM(inpage_ptr));
u32 pgsz=min(0x1000-inpage_offs,inpage_sz);
if(PageType!=-1)
{
if (PageType==0)
{
//MOV32ItoR(EAX,*pageVer);
//CMP32MtoR(EAX,(uptr)pageVer);
//JNE32(((u32)dyna_block_discard_recmem)- ( (u32)x86Ptr + 6 ));
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
}
else
{
u32 lpc=inpage_ptr;
u32 stg=pgsz;
while(stg>0)
{
CMP32ItoM((uptr)PSM(lpc),*(u32*)PSM(lpc));
JNE32(((u32)dyna_block_discard_recmem)- ( (u32)x86Ptr + 6 ));
stg-=4;
lpc+=4;
}
SysPrintf("Manual block @ %08X : %08X %d %d %d %d\n",startpc,inpage_ptr,pgsz,0x1000-inpage_offs,inpage_sz,sz*4);
}
}
inpage_ptr+=pgsz;
inpage_sz-=pgsz;
inpage_offs=inpage_ptr&0xFFF;
}
#endif
// finally recompile // // finally recompile //
g_pCurInstInfo = s_pInstCache; g_pCurInstInfo = s_pInstCache;
while (!branch && pc < s_nEndBlock) { while (!branch && pc < s_nEndBlock) {

View File

@ -34,6 +34,10 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Register arithmetic * * Register arithmetic *
* Format: OP rd, rs, rt * * Format: OP rd, rs, rt *
@ -1993,4 +1997,6 @@ void recSLTU( void )
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -33,6 +33,18 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
#ifdef ARITHMETICIMM_RECOMPILE
extern void LogicalOpRtoR(x86MMXRegType to, x86MMXRegType from, int op);
extern void LogicalOpMtoR(x86MMXRegType to, u32 from, int op);
extern void LogicalOp32RtoM(u32 to, x86IntRegType from, int op);
extern void LogicalOp32MtoR(x86IntRegType to, u32 from, int op);
extern void LogicalOp32ItoR(x86IntRegType to, u32 from, int op);
extern void LogicalOp32ItoM(u32 to, u32 from, int op);
#endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Arithmetic with immediate operand * * Arithmetic with immediate operand *
* Format: OP rt, rs, immediate * * Format: OP rt, rs, immediate *
@ -337,13 +349,6 @@ void recANDI_const()
g_cpuConstRegs[_Rt_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & (u64)_ImmU_; // Zero-extended Immediate g_cpuConstRegs[_Rt_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & (u64)_ImmU_; // Zero-extended Immediate
} }
extern void LogicalOpRtoR(x86MMXRegType to, x86MMXRegType from, int op);
extern void LogicalOpMtoR(x86MMXRegType to, u32 from, int op);
extern void LogicalOp32RtoM(u32 to, x86IntRegType from, int op);
extern void LogicalOp32MtoR(x86IntRegType to, u32 from, int op);
extern void LogicalOp32ItoR(x86IntRegType to, u32 from, int op);
extern void LogicalOp32ItoM(u32 to, u32 from, int op);
void recLogicalOpI(int info, int op) void recLogicalOpI(int info, int op)
{ {
if( info & PROCESS_EE_MMX ) { if( info & PROCESS_EE_MMX ) {
@ -647,4 +652,6 @@ void recXORI( void )
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -36,6 +36,9 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Register branch logic * * Register branch logic *
* Format: OP rs, rt, offset * * Format: OP rs, rt, offset *
@ -570,7 +573,7 @@ void recBGEZAL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (int)BGEZAL ); CALLFunc( (int)Interpreter::OpcodeImpl::BGEZAL );
branch = 2; branch = 2;
} }
} }
@ -583,7 +586,7 @@ void recBLTZALL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (int)BLTZALL ); CALLFunc( (int)Interpreter::OpcodeImpl::BLTZALL );
branch = 2; branch = 2;
} }
@ -595,7 +598,7 @@ void recBGEZALL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (int)BGEZALL ); CALLFunc( (int)Interpreter::OpcodeImpl::BGEZALL );
branch = 2; branch = 2;
} }
@ -1147,8 +1150,8 @@ void recBGTZL( void )
SetBranchImm(pc); SetBranchImm(pc);
} }
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -35,6 +35,9 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Jump to target * * Jump to target *
* Format: OP target * * Format: OP target *
@ -133,4 +136,6 @@ void recJALR( void )
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -32,6 +32,14 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec {
// Implemented at the bottom of the module:
void SetFastMemory(int bSetFast);
namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Load and store for GPR * * Load and store for GPR *
* Format: OP rt, offset(base) * * Format: OP rt, offset(base) *
@ -64,12 +72,9 @@ REC_FUNC(SWC1);
REC_FUNC(LQC2); REC_FUNC(LQC2);
REC_FUNC(SQC2); REC_FUNC(SQC2);
void SetFastMemory(int bSetFast) {}
#else #else
PCSX2_ALIGNED16(u64 retValues[2]); PCSX2_ALIGNED16(u64 retValues[2]);
extern u32 maxrecmem;
static u32 s_bCachingMem = 0; static u32 s_bCachingMem = 0;
static u32 s_nAddMemOffset = 0; static u32 s_nAddMemOffset = 0;
static u32 s_tempaddr = 0; static u32 s_tempaddr = 0;
@ -97,19 +102,8 @@ void _eeOnLoadWrite(int reg)
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
extern void iMemRead32Check();
#define _Imm_co_ (*(s16*)PSM(pc)) #define _Imm_co_ (*(s16*)PSM(pc))
// perf counters
#ifdef PCSX2_DEVBUILD
extern void StartPerfCounter();
extern void StopPerfCounter();
#else
#define StartPerfCounter()
#define StopPerfCounter()
#endif
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//#define REC_SLOWREAD //#define REC_SLOWREAD
//#define REC_SLOWWRITE //#define REC_SLOWWRITE
@ -197,22 +191,6 @@ static u16 g_MemMasks16[16] ={0x0000, 0x8001, 0x0002, 0x0003,
0x0005, 0x8005, 0x0005, 0x8005, 0x0005, 0x8005, 0x0005, 0x8005,
0x0001, 0x0001, 0x0001, 0x0005 }; 0x0001, 0x0001, 0x0001, 0x0005 };
static int s_bFastMemory = 0;
void SetFastMemory(int bSetFast)
{
s_bFastMemory = bSetFast;
if( bSetFast) {
g_MemMasks0[0] = 0x00f0; g_MemMasks0[1] = 0x80f1; g_MemMasks0[2] = 0x00f0; g_MemMasks0[3] = 0x00f1;
g_MemMasks8[0] = 0x0080; g_MemMasks8[1] = 0x8081; g_MemMasks8[2] = 0x0080; g_MemMasks8[3] = 0x0081;
g_MemMasks16[0] = 0x0000; g_MemMasks16[1] = 0x8001; g_MemMasks16[2] = 0x0000; g_MemMasks16[3] = 0x0001;
}
else {
g_MemMasks0[0] = 0x00f0; g_MemMasks0[1] = 0x80f1; g_MemMasks0[2] = 0x00f2; g_MemMasks0[3] = 0x00f3;
g_MemMasks8[0] = 0x0080; g_MemMasks8[1] = 0x8081; g_MemMasks8[2] = 0x0082; g_MemMasks8[3] = 0x0083;
g_MemMasks16[0] = 0x0000; g_MemMasks16[1] = 0x8001; g_MemMasks16[2] = 0x0002; g_MemMasks16[3] = 0x0003;
}
}
void assertmem() void assertmem()
{ {
__asm mov s_tempaddr, ecx __asm mov s_tempaddr, ecx
@ -630,28 +608,26 @@ void recLoad32_co(u32 bit, u32 sign)
} }
} }
void recLB( void ) { recLoad32(8, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; } void recLB( void ) { recLoad32(8, _Imm_, 1); }
void recLB_co( void ) { recLoad32_co(8, 1); g_eeCyclePenalty = InstCycles_Load; } void recLB_co( void ) { recLoad32_co(8, 1); }
void recLBU( void ) { recLoad32(8, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; } void recLBU( void ) { recLoad32(8, _Imm_, 0); }
void recLBU_co( void ) { recLoad32_co(8, 0); g_eeCyclePenalty = InstCycles_Load; } void recLBU_co( void ) { recLoad32_co(8, 0); }
void recLH( void ) { recLoad32(16, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; } void recLH( void ) { recLoad32(16, _Imm_, 1); }
void recLH_co( void ) { recLoad32_co(16, 1); g_eeCyclePenalty = InstCycles_Load; } void recLH_co( void ) { recLoad32_co(16, 1); }
void recLHU( void ) { recLoad32(16, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; } void recLHU( void ) { recLoad32(16, _Imm_, 0); }
void recLHU_co( void ) { recLoad32_co(16, 0); g_eeCyclePenalty = InstCycles_Load; } void recLHU_co( void ) { recLoad32_co(16, 0); }
void recLW( void ) { recLoad32(32, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; } void recLW( void ) { recLoad32(32, _Imm_, 1); }
void recLW_co( void ) { recLoad32_co(32, 1); g_eeCyclePenalty = InstCycles_Load; } void recLW_co( void ) { recLoad32_co(32, 1); }
void recLWU( void ) { recLoad32(32, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; } void recLWU( void ) { recLoad32(32, _Imm_, 0); }
void recLWU_co( void ) { recLoad32_co(32, 0); g_eeCyclePenalty = InstCycles_Load; } void recLWU_co( void ) { recLoad32_co(32, 0); }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// paired with LWR // paired with LWR
void recLWL_co(void) { recLoad32(32, _Imm_-3, 1); g_eeCyclePenalty = InstCycles_Load; } void recLWL_co(void) { recLoad32(32, _Imm_-3, 1); }
void recLWL( void ) void recLWL( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD #ifdef REC_SLOWREAD
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
#else #else
@ -732,11 +708,10 @@ void recLWL( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// paired with LWL // paired with LWL
void recLWR_co(void) { recLoad32(32, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; } void recLWR_co(void) { recLoad32(32, _Imm_, 1); }
void recLWR( void ) void recLWR( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD #ifdef REC_SLOWREAD
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
#else #else
@ -934,7 +909,7 @@ void recLoad64(u32 imm, int align)
if( _Rt_ ) _eeOnWriteReg(_Rt_, 0); if( _Rt_ ) _eeOnWriteReg(_Rt_, 0);
} }
void recLD(void) { recLoad64(_Imm_, 1); g_eeCyclePenalty = InstCycles_Load; } void recLD(void) { recLoad64(_Imm_, 1); }
void recLD_co( void ) void recLD_co( void )
{ {
@ -1196,13 +1171,11 @@ void recLD_coX( int num )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLDL_co(void) void recLDL_co(void)
{ {
g_eeCyclePenalty = InstCycles_Load;
recLoad64(_Imm_-7, 0); recLoad64(_Imm_-7, 0);
} }
void recLDL( void ) void recLDL( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
iFlushCall(FLUSH_NOCONST); iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) { if( GPR_IS_CONST1( _Rs_ ) ) {
@ -1220,15 +1193,14 @@ void recLDL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
CALLFunc( (int)LDL ); CALLFunc( (int)Interpreter::OpcodeImpl::LDL );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLDR_co(void) { recLoad64(_Imm_, 0); g_eeCyclePenalty = InstCycles_Load; } void recLDR_co(void) { recLoad64(_Imm_, 0); }
void recLDR( void ) void recLDR( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
iFlushCall(FLUSH_NOCONST); iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) { if( GPR_IS_CONST1( _Rs_ ) ) {
@ -1246,14 +1218,12 @@ void recLDR( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
CALLFunc( (int)LDR ); CALLFunc( (int)Interpreter::OpcodeImpl::LDR );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLQ( void ) void recLQ( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
int mmreg = -1; int mmreg = -1;
#ifdef REC_SLOWREAD #ifdef REC_SLOWREAD
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
@ -1383,8 +1353,6 @@ void recLQ( void )
void recLQ_co( void ) void recLQ_co( void )
{ {
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD #ifdef REC_SLOWREAD
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
#else #else
@ -1597,8 +1565,23 @@ void recLQ_coX(int num)
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
extern void recClear64(BASEBLOCK* p); static void recClear64(BASEBLOCK* p)
extern void recClear128(BASEBLOCK* p); {
int left = 4 - ((u32)p % 16)/sizeof(BASEBLOCK);
recClearMem(p);
if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1);
}
static void recClear128(BASEBLOCK* p)
{
int left = 4 - ((u32)p % 32)/sizeof(BASEBLOCK);
recClearMem(p);
if( left > 1 && *(u32*)(p+1) ) recClearMem(p+1);
if( left > 2 && *(u32*)(p+2) ) recClearMem(p+2);
if( left > 3 && *(u32*)(p+3) ) recClearMem(p+3);
}
// check if clearing executable code, size is in dwords // check if clearing executable code, size is in dwords
void recMemConstClear(u32 mem, u32 size) void recMemConstClear(u32 mem, u32 size)
@ -2424,20 +2407,18 @@ void recStore_co(int bit, int align)
_clearNeededXMMregs(); // needed since allocing _clearNeededXMMregs(); // needed since allocing
} }
void recSB( void ) { recStore(8, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; } void recSB( void ) { recStore(8, _Imm_, 1); }
void recSB_co( void ) { recStore_co(8, 1); g_eeCyclePenalty = InstCycles_Store; } void recSB_co( void ) { recStore_co(8, 1); }
void recSH( void ) { recStore(16, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; } void recSH( void ) { recStore(16, _Imm_, 1); }
void recSH_co( void ) { recStore_co(16, 1); g_eeCyclePenalty = InstCycles_Store; } void recSH_co( void ) { recStore_co(16, 1); }
void recSW( void ) { recStore(32, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; } void recSW( void ) { recStore(32, _Imm_, 1); }
void recSW_co( void ) { recStore_co(32, 1); g_eeCyclePenalty = InstCycles_Store; } void recSW_co( void ) { recStore_co(32, 1); }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSWL_co(void) { recStore(32, _Imm_-3, 0); g_eeCyclePenalty = InstCycles_Store; } void recSWL_co(void) { recStore(32, _Imm_-3, 0); }
void recSWL( void ) void recSWL( void )
{ {
g_eeCyclePenalty = InstCycles_Store;
#ifdef REC_SLOWWRITE #ifdef REC_SLOWWRITE
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
#else #else
@ -2525,12 +2506,10 @@ void recSWL( void )
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSWR_co(void) { recStore(32, _Imm_, 0); g_eeCyclePenalty = InstCycles_Store; } void recSWR_co(void) { recStore(32, _Imm_, 0); }
void recSWR( void ) void recSWR( void )
{ {
g_eeCyclePenalty = InstCycles_Store;
#ifdef REC_SLOWWRITE #ifdef REC_SLOWWRITE
_flushConstReg(_Rs_); _flushConstReg(_Rs_);
#else #else
@ -2618,8 +2597,8 @@ void recSWR( void )
} }
} }
void recSD( void ) { recStore(64, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; } void recSD( void ) { recStore(64, _Imm_, 1); }
void recSD_co( void ) { recStore_co(64, 1); g_eeCyclePenalty = InstCycles_Store; } void recSD_co( void ) { recStore_co(64, 1); }
// coissues more than 2 SDs // coissues more than 2 SDs
void recSD_coX(int num, int align) void recSD_coX(int num, int align)
@ -2736,12 +2715,10 @@ void recSD_coX(int num, int align)
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSDL_co(void) { recStore(64, _Imm_-7, 0); g_eeCyclePenalty = InstCycles_Store; } void recSDL_co(void) { recStore(64, _Imm_-7, 0); }
void recSDL( void ) void recSDL( void )
{ {
g_eeCyclePenalty = InstCycles_Store;
iFlushCall(FLUSH_NOCONST); iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) { if( GPR_IS_CONST1( _Rs_ ) ) {
@ -2758,16 +2735,14 @@ void recSDL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
CALLFunc( (int)SDL ); CALLFunc( (int)Interpreter::OpcodeImpl::SDL );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSDR_co(void) { recStore(64, _Imm_, 0); g_eeCyclePenalty = InstCycles_Store; } void recSDR_co(void) { recStore(64, _Imm_, 0); }
void recSDR( void ) void recSDR( void )
{ {
g_eeCyclePenalty = InstCycles_Store;
iFlushCall(FLUSH_NOCONST); iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) { if( GPR_IS_CONST1( _Rs_ ) ) {
@ -2784,12 +2759,12 @@ void recSDR( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code ); MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc ); MOV32ItoM( (int)&cpuRegs.pc, pc );
CALLFunc( (int)SDR ); CALLFunc( (int)Interpreter::OpcodeImpl::SDR );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSQ( void ) { recStore(128, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; } void recSQ( void ) { recStore(128, _Imm_, 1); }
void recSQ_co( void ) { recStore_co(128, 1); g_eeCyclePenalty = InstCycles_Store; } void recSQ_co( void ) { recStore_co(128, 1); }
// coissues more than 2 SQs // coissues more than 2 SQs
void recSQ_coX(int num) void recSQ_coX(int num)
@ -3814,6 +3789,8 @@ void recSQC2_co( void )
#else #else
using namespace Interpreter::OpcodeImpl;
PCSX2_ALIGNED16(u32 dummyValue[4]); PCSX2_ALIGNED16(u32 dummyValue[4]);
void SetFastMemory(int bSetFast) void SetFastMemory(int bSetFast)
@ -3821,9 +3798,112 @@ void SetFastMemory(int bSetFast)
// nothing // nothing
} }
void vtlb_DynGenOp(bool Read,u32 sz)
{
int reg=-1;
if (sz==64 && _hasFreeMMXreg())
{
reg=_allocMMXreg(-1, MMX_TEMP, 0);
}
else if (sz==128 && _hasFreeXMMreg())
{
reg=_allocTempXMMreg(XMMT_FPS,-1);
}
if (Read)
vtlb_DynGenRead(sz,reg);
else
vtlb_DynGenWrite(sz,reg);
if (reg!=-1)
{
if (sz==128)
_freeXMMreg(reg);
else
_freeMMXreg(reg);
}
}
void recLoad(u32 sz,bool sx)
{
//no int 3? i love to get my hands dirty ;p - Raz
//write8(0xCC);
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
if (sz>=64)
{
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension -> what does this really do ?
}
_deleteEEreg(_Rt_, 0);
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 )
{
ADD32ItoR( ECX, _Imm_ );
}
if (sz==128)
{
AND32I8toR(ECX,0xF0);
}
if ( _Rt_ && sz>=64)
{
MOV32ItoR(EDX, (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
}
else
{
MOV32ItoR(EDX, (int)&dummyValue[0] );
}
vtlb_DynGenOp(true,sz);
/*
if (sz==8)
CALLFunc( (int)memRead8 );
else if (sz==16)
CALLFunc( (int)memRead16 );
else if (sz==32)
CALLFunc( (int)memRead32 );
else if (sz==64)
CALLFunc( (int)memRead64 );
else if (sz==128)
CALLFunc( (int)memRead128 );
*/
if ( _Rt_ && sz<64)
{
MOV32MtoR( EAX, (int)&dummyValue[0] ); //ewww, lame ! movsx /zx has r/m forms too ...
if (sz==8)
{
if (sx)
MOVSX32R8toR( EAX, EAX );
else
MOVZX32R8toR( EAX, EAX );
}
else if (sz==16)
{
if (sx)
MOVSX32R16toR( EAX, EAX );
else
MOVZX32R16toR( EAX, EAX );
}
if (sx)
CDQ( );
else
XOR32RtoR(EDX,EDX);
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
}
}
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLB( void ) void recLB( void )
{ {
recLoad(8,true);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -3850,11 +3930,14 @@ void recLB( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLBU( void ) void recLBU( void )
{ {
recLoad(8,false);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -3880,11 +3963,14 @@ void recLBU( void )
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 ); MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLH( void ) void recLH( void )
{ {
recLoad(16,true);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -3911,11 +3997,14 @@ void recLH( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLHU( void ) void recLHU( void )
{ {
recLoad(16,false);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -3939,12 +4028,14 @@ void recLHU( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 ); MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLW( void ) void recLW( void )
{ {
recLoad(32,true);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -3971,12 +4062,14 @@ void recLW( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLWU( void ) void recLWU( void )
{ {
recLoad(32,false);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0); _deleteEEreg(_Rt_, 0);
@ -4001,6 +4094,7 @@ void recLWU( void )
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 ); MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd ); x86SetJ8( linkEnd );
} }
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4028,6 +4122,8 @@ extern void MOV64RmtoR( x86IntRegType to, x86IntRegType from );
void recLD( void ) void recLD( void )
{ {
recLoad(64,false);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
@ -4050,6 +4146,7 @@ void recLD( void )
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memRead64 ); CALLFunc( (int)memRead64 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4079,6 +4176,8 @@ void recLDR( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recLQ( void ) void recLQ( void )
{ {
recLoad(128,false);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_); _eeOnLoadWrite(_Rt_);
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
@ -4102,12 +4201,59 @@ void recLQ( void )
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memRead128 ); CALLFunc( (int)memRead128 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );
*/
} }
void recStore(u32 sz)
{
//no int 3? i love to get my hands dirty ;p - Raz
//write8(0xCC);
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 )
{
ADD32ItoR( ECX, _Imm_);
}
if (sz==128)
{
AND32I8toR(ECX,0xF0);
}
if (sz<64)
{
if (_Rt_)
MOV32MtoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
else
XOR32RtoR(EDX,EDX);
}
else if (sz==128 || sz==64)
{
MOV32ItoR(EDX,(int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ]);
}
vtlb_DynGenOp(false,sz);
/*
if (sz==8)
CALLFunc( (int)memWrite8 );
else if (sz==16)
CALLFunc( (int)memWrite16 );
else if (sz==32)
CALLFunc( (int)memWrite32 );
else if (sz==64)
CALLFunc( (int)memWrite64 );
else if (sz==128)
CALLFunc( (int)memWrite128 );
*/
}
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSB( void ) void recSB( void )
{ {
recStore(8);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4118,12 +4264,15 @@ void recSB( void )
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memWrite8 ); CALLFunc( (int)memWrite8 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSH( void ) void recSH( void )
{ {
recStore(16);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
@ -4136,11 +4285,14 @@ void recSH( void )
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memWrite16 ); CALLFunc( (int)memWrite16 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSW( void ) void recSW( void )
{ {
recStore(32);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
@ -4154,6 +4306,7 @@ void recSW( void )
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memWrite32 ); CALLFunc( (int)memWrite32 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4179,6 +4332,8 @@ void recSWR( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSD( void ) void recSD( void )
{ {
recStore(64);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4192,6 +4347,7 @@ void recSD( void )
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memWrite64 ); CALLFunc( (int)memWrite64 );
ADD32ItoR( ESP, 12 ); ADD32ItoR( ESP, 12 );
*/
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4217,6 +4373,8 @@ void recSDR( void )
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recSQ( void ) void recSQ( void )
{ {
recStore(128);
/*
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1); _deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4229,7 +4387,7 @@ void recSQ( void )
PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] ); PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] );
PUSH32R( EAX ); PUSH32R( EAX );
CALLFunc( (int)memWrite128 ); CALLFunc( (int)memWrite128 );
ADD32ItoR( ESP, 8 ); ADD32ItoR( ESP, 8 );*/
} }
/********************************************************* /*********************************************************
@ -4243,16 +4401,15 @@ void recLWC1( void )
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteFPtoXMMreg(_Rt_, 2); _deleteFPtoXMMreg(_Rt_, 2);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 ) if ( _Imm_ != 0 )
{ {
ADD32ItoR( EAX, _Imm_ ); ADD32ItoR( ECX, _Imm_ );
} }
PUSH32I( (int)&fpuRegs.fpr[ _Rt_ ].UL ); MOV32ItoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); //no 0 for fpu ?
PUSH32R( EAX ); //CALLFunc( (int)memRead32 );
CALLFunc( (int)memRead32 ); vtlb_DynGenOp(true,32);
ADD32ItoR( ESP, 8 );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4261,16 +4418,15 @@ void recSWC1( void )
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteFPtoXMMreg(_Rt_, 0); _deleteFPtoXMMreg(_Rt_, 0);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 ) if ( _Imm_ != 0 )
{ {
ADD32ItoR( EAX, _Imm_ ); ADD32ItoR( ECX, _Imm_ );
} }
PUSH32M( (int)&fpuRegs.fpr[ _Rt_ ].UL ); MOV32MtoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL );
PUSH32R( EAX ); //CALLFunc( (int)memWrite32 );
CALLFunc( (int)memWrite32 ); vtlb_DynGenOp(false,32);
ADD32ItoR( ESP, 8 );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4284,23 +4440,22 @@ void recLQC2( void )
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteVFtoXMMreg(_Ft_, 0, 2); _deleteVFtoXMMreg(_Ft_, 0, 2);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 ) if ( _Imm_ != 0 )
{ {
ADD32ItoR( EAX, _Imm_); ADD32ItoR( ECX, _Imm_);
} }
if ( _Rt_ ) if ( _Rt_ )
{ {
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] ); MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
} }
else else
{ {
PUSH32I( (int)&dummyValue[0] ); MOV32ItoR(EDX, (int)&dummyValue[0] );
} }
PUSH32R( EAX ); //CALLFunc( (int)memRead128 );
CALLFunc( (int)memRead128 ); vtlb_DynGenOp(true,128);
ADD32ItoR( ESP, 8 );
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -4309,20 +4464,51 @@ void recSQC2( void )
_deleteEEreg(_Rs_, 1); _deleteEEreg(_Rs_, 1);
_deleteVFtoXMMreg(_Ft_, 0, 0); _deleteVFtoXMMreg(_Ft_, 0, 0);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 ) if ( _Imm_ != 0 )
{ {
ADD32ItoR( EAX, _Imm_ ); ADD32ItoR( ECX, _Imm_ );
} }
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] ); MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
PUSH32R( EAX ); //CALLFunc( (int)memWrite128 );
CALLFunc( (int)memWrite128 ); vtlb_DynGenOp(false,128);
ADD32ItoR( ESP, 8 );
} }
#endif #endif
#endif #endif
} // end namespace OpcodeImpl
#ifdef PCSX2_VIRTUAL_MEM
using namespace OpcodeImpl;
#ifndef LOADSTORE_RECOMPILE
void SetFastMemory(int bSetFast) {}
#else
static int s_bFastMemory = 0;
void SetFastMemory(int bSetFast)
{
s_bFastMemory = bSetFast;
if( bSetFast ) {
g_MemMasks0[0] = 0x00f0; g_MemMasks0[1] = 0x80f1; g_MemMasks0[2] = 0x00f0; g_MemMasks0[3] = 0x00f1;
g_MemMasks8[0] = 0x0080; g_MemMasks8[1] = 0x8081; g_MemMasks8[2] = 0x0080; g_MemMasks8[3] = 0x0081;
g_MemMasks16[0] = 0x0000; g_MemMasks16[1] = 0x8001; g_MemMasks16[2] = 0x0000; g_MemMasks16[3] = 0x0001;
}
else {
g_MemMasks0[0] = 0x00f0; g_MemMasks0[1] = 0x80f1; g_MemMasks0[2] = 0x00f2; g_MemMasks0[3] = 0x00f3;
g_MemMasks8[0] = 0x0080; g_MemMasks8[1] = 0x8081; g_MemMasks8[2] = 0x0082; g_MemMasks8[3] = 0x0083;
g_MemMasks16[0] = 0x0000; g_MemMasks16[1] = 0x8001; g_MemMasks16[2] = 0x0002; g_MemMasks16[3] = 0x0003;
}
}
#endif
#else // VTLB version
void SetFastMemory(int bSetFast) {}
#endif
} }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -34,6 +34,9 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Shift arithmetic with constant shift * * Shift arithmetic with constant shift *
* Format: OP rd, rt, sa * * Format: OP rd, rt, sa *
@ -820,4 +823,6 @@ REC_FUNC( MTLO1, 0 );
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -33,6 +33,9 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Register mult/div & Register trap logic * * Register mult/div & Register trap logic *
* Format: OP rs, rt * * Format: OP rs, rt *
@ -424,7 +427,7 @@ void recMULT_constt(int info)
} }
// don't set XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI // don't set XMMINFO_WRITED|XMMINFO_WRITELO|XMMINFO_WRITEHI
EERECOMPILE_CODE0_PENALTY(MULT, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0), InstCycles_Mult ); EERECOMPILE_CODE0(MULT, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0) );
//// MULTU //// MULTU
void recMULTU_const() void recMULTU_const()
@ -537,7 +540,7 @@ void recMULTU_constt(int info)
} }
// don't specify XMMINFO_WRITELO or XMMINFO_WRITEHI, that is taken care of // don't specify XMMINFO_WRITELO or XMMINFO_WRITEHI, that is taken care of
EERECOMPILE_CODE0_PENALTY(MULTU, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0), InstCycles_Mult); EERECOMPILE_CODE0(MULTU, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0));
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recMULT1_const() void recMULT1_const()
@ -571,7 +574,7 @@ void recMULT1_constt(int info)
else recMULTUsuper(info, 1, PROCESS_CONSTT); else recMULTUsuper(info, 1, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(MULT1, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0), InstCycles_Mult ); EERECOMPILE_CODE0(MULT1, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0) );
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
void recMULTU1_const() void recMULTU1_const()
@ -596,7 +599,7 @@ void recMULTU1_constt(int info)
recMULTUsuper(info, 1, PROCESS_CONSTT); recMULTUsuper(info, 1, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(MULTU1, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0), InstCycles_Mult); EERECOMPILE_CODE0(MULTU1, XMMINFO_READS|XMMINFO_READT|(_Rd_?XMMINFO_WRITED:0));
//// DIV //// DIV
void recDIV_const() void recDIV_const()
@ -661,7 +664,7 @@ void recDIV_constt(int info)
recDIVsuper(info, 1, 0, PROCESS_CONSTT); recDIVsuper(info, 1, 0, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(DIV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI, InstCycles_Div); EERECOMPILE_CODE0(DIV, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI);
//// DIVU //// DIVU
void recDIVU_const() void recDIVU_const()
@ -689,7 +692,7 @@ void recDIVU_constt(int info)
recDIVsuper(info, 0, 0, PROCESS_CONSTT); recDIVsuper(info, 0, 0, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(DIVU, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI, InstCycles_Div); EERECOMPILE_CODE0(DIVU, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITELO|XMMINFO_WRITEHI);
void recDIV1_const() void recDIV1_const()
{ {
@ -716,7 +719,7 @@ void recDIV1_constt(int info)
recDIVsuper(info, 1, 1, PROCESS_CONSTT); recDIVsuper(info, 1, 1, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(DIV1, XMMINFO_READS|XMMINFO_READT, InstCycles_Div); EERECOMPILE_CODE0(DIV1, XMMINFO_READS|XMMINFO_READT);
void recDIVU1_const() void recDIVU1_const()
{ {
@ -743,7 +746,7 @@ void recDIVU1_constt(int info)
recDIVsuper(info, 0, 1, PROCESS_CONSTT); recDIVsuper(info, 0, 1, PROCESS_CONSTT);
} }
EERECOMPILE_CODE0_PENALTY(DIVU1, XMMINFO_READS|XMMINFO_READT, InstCycles_Div); EERECOMPILE_CODE0(DIVU1, XMMINFO_READS|XMMINFO_READT);
//do EEINST_SETSIGNEXT //do EEINST_SETSIGNEXT
REC_FUNC( MADD, _Rd_ ); REC_FUNC( MADD, _Rd_ );
@ -955,4 +958,6 @@ REC_FUNC( MADDU1, _Rd_ );
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -34,6 +34,9 @@
#pragma warning(disable:4761) #pragma warning(disable:4761)
#endif #endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/********************************************************* /*********************************************************
* Shift arithmetic with constant shift * * Shift arithmetic with constant shift *
* Format: OP rd, rt, sa * * Format: OP rd, rt, sa *
@ -1351,4 +1354,6 @@ void recDSRAV( void )
} }
#endif #endif
} } }
#endif // PCSX2_NORECBUILD #endif // PCSX2_NORECBUILD

View File

@ -31,8 +31,6 @@
#include <assert.h> #include <assert.h>
#include "ix86.h" #include "ix86.h"
XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT };
#define SWAP(x, y) { *(u32*)&y ^= *(u32*)&x; *(u32*)&x ^= *(u32*)&y; *(u32*)&y ^= *(u32*)&x; } #define SWAP(x, y) { *(u32*)&y ^= *(u32*)&x; *(u32*)&x ^= *(u32*)&y; *(u32*)&y ^= *(u32*)&x; }
#ifdef __x86_64__ #ifdef __x86_64__

View File

@ -26,7 +26,7 @@ PCSX2_ALIGNED16(unsigned int p2[4]);
PCSX2_ALIGNED16(float f[4]); PCSX2_ALIGNED16(float f[4]);
//XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT }; XMMSSEType g_xmmtypes[XMMREGS] = { XMMT_INT };
/********************/ /********************/
/* SSE instructions */ /* SSE instructions */

View File

@ -174,7 +174,7 @@ int LoadGroup(TiXmlNode *group,int gParent)
// only valid for recompilers // only valid for recompilers
TiXmlNode *fastmemory=group->FirstChild("FASTMEMORY"); TiXmlNode *fastmemory=group->FirstChild("FASTMEMORY");
if(fastmemory!=NULL) if(fastmemory!=NULL)
SetFastMemory(1); EE::Dynarec::SetFastMemory(1);
#endif #endif
TiXmlNode *zerogs=group->FirstChild("ZEROGS"); TiXmlNode *zerogs=group->FirstChild("ZEROGS");
@ -324,11 +324,11 @@ int LoadGroup(TiXmlNode *group,int gParent)
if(strcmp(place,"EE")==0) if(strcmp(place,"EE")==0)
{ {
patch[patchnumber].cpu= EE; patch[patchnumber].cpu= CPU_EE;
} else } else
if(strcmp(place,"IOP")==0) if(strcmp(place,"IOP")==0)
{ {
patch[patchnumber].cpu= IOP; patch[patchnumber].cpu= CPU_IOP;
} else } else
{ {
SysPrintf("XML Patch Loader: ERROR: Invalid place attribute.\n"); SysPrintf("XML Patch Loader: ERROR: Invalid place attribute.\n");

View File

@ -5,23 +5,26 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2", "pcsx2\windows\VCpr
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug TLB|Win32 = Debug TLB|Win32 Debug vm|Win32 = Debug vm|Win32
Debug|Win32 = Debug|Win32 Debug vtlb|Win32 = Debug vtlb|Win32
Release (to Public)|Win32 = Release (to Public)|Win32 Release vm (to Public)|Win32 = Release vm (to Public)|Win32
Release TLB|Win32 = Release TLB|Win32 Release vm|Win32 = Release vm|Win32
Release|Win32 = Release|Win32 Release vtlb (to Public)|Win32 = Release vtlb (to Public)|Win32
Release vtlb|Win32 = Release vtlb|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug TLB|Win32.ActiveCfg = Debug TLB|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.ActiveCfg = Debug vm|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug TLB|Win32.Build.0 = Debug TLB|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.Build.0 = Debug vm|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.ActiveCfg = Debug|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.ActiveCfg = Debug vtlb|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.Build.0 = Debug|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.Build.0 = Debug vtlb|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release (to Public)|Win32.ActiveCfg = Release (to Public)|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm (to Public)|Win32.ActiveCfg = Release VM (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release (to Public)|Win32.Build.0 = Release (to Public)|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm (to Public)|Win32.Build.0 = Release VM (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release TLB|Win32.ActiveCfg = Release TLB|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.ActiveCfg = Release VM|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release TLB|Win32.Build.0 = Release TLB|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.Build.0 = Release VM|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.ActiveCfg = Release|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb (to Public)|Win32.ActiveCfg = Release vtlb (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.Build.0 = Release|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb (to Public)|Win32.Build.0 = Release vtlb (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.ActiveCfg = Release vtlb|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.Build.0 = Release vtlb|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE