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;
@ -387,3 +389,5 @@ 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
{
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);
}
void SWC1() {
u32 addr; u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff); 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? if (addr & 0x00000003) { SysPrintf( "FPU (SWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memWrite32(addr, fpuRegs.fpr[_Rt_].UL); 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,52 +20,367 @@
#include "InterTables.h" #include "InterTables.h"
void (*Int_OpcodePrintTable[64])() = namespace EE
{ {
namespace Opcodes
{
// 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 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 );
// Multimedia Instructions!
MakeOpcode( PLZCW, Default );
MakeOpcode( PMFHL, Default );
MakeOpcode( PMTHL, Default );
MakeOpcode( PSLLH, Default );
MakeOpcode( PSRLH, Default );
MakeOpcode( PSRAH, Default );
MakeOpcode( PSLLW, Default );
MakeOpcode( PSRLW, Default );
MakeOpcode( PSRAW, Default );
MakeOpcode( PADDW, Default );
MakeOpcode( PADDH, Default );
MakeOpcode( PADDB, Default );
MakeOpcode( PADDSW, Default );
MakeOpcode( PADDSH, Default );
MakeOpcode( PADDSB, Default );
MakeOpcode( PADDUW, Default );
MakeOpcode( PADDUH, Default );
MakeOpcode( PADDUB, Default );
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 );
MakeOpcode( PCGTW, Default );
MakeOpcode( PMAXW, Default );
MakeOpcode( PMAXH, Default );
MakeOpcode( PCGTH, Default );
MakeOpcode( PCGTB, Default );
MakeOpcode( PEXTLW, Default );
MakeOpcode( PEXTLH, Default );
MakeOpcode( PEXTLB, Default );
MakeOpcode( PEXT5, Default );
MakeOpcode( PPACW, Default );
MakeOpcode( PPACH, Default );
MakeOpcode( PPACB, Default );
MakeOpcode( PPAC5, Default );
MakeOpcode( PABSW, Default );
MakeOpcode( PABSH, Default );
MakeOpcode( PCEQW, Default );
MakeOpcode( PMINW, Default );
MakeOpcode( PMINH, Default );
MakeOpcode( PADSBH, Default );
MakeOpcode( PCEQH, Default );
MakeOpcode( PCEQB, Default );
MakeOpcode( PEXTUW, Default );
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, SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI, ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, UnknownOpcode, BEQL, BNEL, BLEZL, BGTZL, COP0, COP1, COP2, Unknown, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, MMI, UnknownOpcode, LQ, SQ, DADDI, DADDIU, LDL, LDR, Opcodes::MMI, Unknown, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU, LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE, SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
UnknownOpcode, LWC1, UnknownOpcode, PREF, UnknownOpcode,UnknownOpcode, LQC2, LD, Unknown, LWC1, Unknown, PREF, Unknown, Unknown, LQC2, LD,
UnknownOpcode, SWC1, UnknownOpcode, UnknownOpcode, UnknownOpcode,UnknownOpcode, SQC2, SD Unknown, SWC1, Unknown, Unknown, Unknown, Unknown, SQC2, SD
}; };
const OPCODE Special[64] =
void (*Int_SpecialPrintTable[64])() = {
{ SLL, Unknown, SRL, SRA, SLLV, Unknown, SRLV, SRAV,
SLL, UnknownOpcode, SRL, SRA, SLLV, UnknownOpcode, SRLV, SRAV, JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, Unknown, SYNC,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, UnknownOpcode, SYNC, MFHI, MTHI, MFLO, MTLO, DSLLV, Unknown, DSRLV, DSRAV,
MFHI, MTHI, MFLO, MTLO, DSLLV, UnknownOpcode, DSRLV, DSRAV, MULT, MULTU, DIV, DIVU, Unknown, Unknown, Unknown, Unknown,
MULT, MULTU, DIV, DIVU, UnknownOpcode,UnknownOpcode,UnknownOpcode,UnknownOpcode,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR, ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA , MTSA , SLT, SLTU, DADD, DADDU, DSUB, DSUBU, MFSA, MTSA, SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, UnknownOpcode, TNE, UnknownOpcode, TGE, TGEU, TLT, TLTU, TEQ, Unknown, TNE, Unknown,
DSLL, UnknownOpcode, DSRL, DSRA, DSLL32, UnknownOpcode, DSRL32, DSRA32 DSLL, Unknown, DSRL, DSRA, DSLL32, Unknown, DSRL32, DSRA32
}; };
void (*Int_REGIMMPrintTable[32])() = { const OPCODE RegImm[32] = {
BLTZ, BGEZ, BLTZL, BGEZL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, BLTZ, BGEZ, BLTZL, BGEZL, Unknown, Unknown, Unknown, Unknown,
TGEI, TGEIU, TLTI, TLTIU, TEQI, UnknownOpcode, TNEI, UnknownOpcode, TGEI, TGEIU, TLTI, TLTIU, TEQI, Unknown, TNEI, Unknown,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, BLTZAL, BGEZAL, BLTZALL, BGEZALL, Unknown, Unknown, Unknown, Unknown,
MTSAB, MTSAH , UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, MTSAB, MTSAH , Unknown, Unknown, Unknown, Unknown, Unknown, Unknown,
}; };
void (*Int_MMIPrintTable[64])() = const OPCODE MMI[64] =
{ {
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown, MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI0, MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, 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, MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, 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, MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI1 , MMI3, 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, PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
}; };
void (*Int_MMI0PrintTable[32])() = const OPCODE MMI0[32] =
{ {
PADDW, PSUBW, PCGTW, PMAXW, PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH, PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown, PADDB, PSUBB, PCGTB, MMI_Unknown,
@ -74,10 +389,10 @@ void (*Int_MMI0PrintTable[32])() =
PADDSH, PSUBSH, PEXTLH, PPACH, PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB, PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5, MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
}; };
void (*Int_MMI1PrintTable[32])() = const OPCODE MMI1[32] =
{ {
MMI_Unknown, PABSW, PCEQW, PMINW, MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH, PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown, MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
@ -86,11 +401,11 @@ void (*Int_MMI1PrintTable[32])() =
PADDUH, PSUBUH, PEXTUH, MMI_Unknown, PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV, PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, 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,
@ -99,10 +414,10 @@ void (*Int_MMI2PrintTable[32])() =
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,
@ -111,7 +426,10 @@ void (*Int_MMI3PrintTable[32])() =
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,23 +502,25 @@ 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;
} }
} }
@ -445,11 +528,12 @@ 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,6 +710,7 @@ u64 psxRcntCycles(int index)
extern u32 dwCurSaveStateVer; extern u32 dwCurSaveStateVer;
int psxRcntFreeze(gzFile f, int Mode) int psxRcntFreeze(gzFile f, int Mode)
{ {
#ifdef PCSX2_VIRTUAL_MEM
if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) ) if( Mode == 0 && (dwCurSaveStateVer < 0x7a300010) )
{ {
// --- Reading Mode, Old Version --- // --- Reading Mode, Old Version ---
@ -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,7 +64,9 @@ 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
{
void LQC2() {
u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code; u32 addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s16)cpuRegs.code;
if (_Ft_) { if (_Ft_) {
memRead128(addr, &VU0.VF[_Ft_].UD[0]); memRead128(addr, &VU0.VF[_Ft_].UD[0]);
@ -75,15 +74,18 @@ void LQC2() {
u64 val[2]; u64 val[2];
memRead128(addr, val); memRead128(addr, val);
} }
} }
// Asadr.Changed // Asadr.Changed
void SQC2() { //TODO: check this
// HUH why ? doesn;t make any sense ...
void SQC2() {
u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0]; u32 addr = _Imm_ + cpuRegs.GPR.r[_Rs_].UL[0];
memWrite64(addr, VU0.VF[_Ft_].UD[0]); //memWrite64(addr, VU0.VF[_Ft_].UD[0]);
memWrite64(addr+8,VU0.VF[_Ft_].UD[1]); //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);
}
else
{
sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp); sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
} output.append( buf );
EE::OpcodeTables::Standard[_Opcode_].decode( output );
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,57 +44,17 @@
#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_ ]( );
}
////////////////////////////////////////////////////
static void recSPECIAL( void )
{
recSPC[ _Funct_ ]( );
}
////////////////////////////////////////////////////
static void recCOP0( void )
{
recCP0[ _Rs_ ]( );
}
////////////////////////////////////////////////////
static void recCOP0BC0( void )
{
recCP0BC0[ ( cpuRegs.code >> 16 ) & 0x03 ]( );
}
////////////////////////////////////////////////////
static void recCOP0C0( void )
{
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)() )
{ {
// 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 // In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle. // to the current cpu cycle.
@ -108,138 +68,171 @@ void recBranchCall( void (*func)() )
// recompiler inserts the branchtest anyway. // recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING); iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func ); CALLFunc( (uptr)func );
} }
/********************************************************** namespace OpcodeImpl
* 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 recUnknown()
{
// TODO : Unknown ops should throw an exception.
SysPrintf("EE: Unrecognized op %x\n", cpuRegs.code);
}
void recTGEU( void ) void recMMI_Unknown()
{ {
recBranchCall( TGEU ); // TODO : Unknown ops should throw an exception.
} SysPrintf("EE: Unrecognized MMI op %x\n", cpuRegs.code);
}
void recTLT( void ) ////////////////////////////////////////////////////
{ void recREGIMM( void )
recBranchCall( TLT ); {
} EE::OpcodeTables::RegImm[ _Rt_ ].recompile();
}
void recTLTU( void ) ////////////////////////////////////////////////////
{ void recSPECIAL( void )
recBranchCall( TLTU ); {
} EE::OpcodeTables::Special[ _Funct_ ].recompile( );
}
void recTEQ( void ) ////////////////////////////////////////////////////
{ void recCOP0( void )
recBranchCall( TEQ ); {
} recCP0[ _Rs_ ]( );
}
void recTNE( void ) ////////////////////////////////////////////////////
{ void recCOP1( void )
recBranchCall( TNE ); {
} recCP1[ _Rs_ ]( );
}
void recTGEI( void ) ////////////////////////////////////////////////////
{ void recMMI( void )
recBranchCall( TGEI ); {
} EE::OpcodeTables::MMI[ _Funct_ ].recompile( );
}
void recTGEIU( void ) /**********************************************************
{ * UNHANDLED YET OPCODES
recBranchCall( TGEIU ); *
} **********************************************************/
void recTLTI( void ) ////////////////////////////////////////////////////
{ //REC_SYS(PREF);
recBranchCall( TLTI ); ////////////////////////////////////////////////////
} //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 recTLTIU( void ) void recCACHE()
{ {
recBranchCall( TLTIU ); MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
} MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)Interpreter::OpcodeImpl::CACHE );
branch = 2;
}
void recTEQI( void ) void recTGE( void )
{ {
recBranchCall( TEQI ); recBranchCall( Interpreter::OpcodeImpl::TGE );
} }
void recTNEI( void ) void recTGEU( void )
{ {
recBranchCall( TNEI ); recBranchCall( Interpreter::OpcodeImpl::TGEU );
} }
void recTLT( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLT );
}
///////////////////////////////// void recTLTU( void )
// Foward-Prob Function Tables // {
///////////////////////////////// recBranchCall( Interpreter::OpcodeImpl::TLTU );
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] )() = { void recTEQ( void )
recSPECIAL, recREGIMM, recJ, recJAL, recBEQ, recBNE, recBLEZ, recBGTZ, {
recADDI, recADDIU, recSLTI, recSLTIU, recANDI, recORI, recXORI, recLUI, recBranchCall( Interpreter::OpcodeImpl::TEQ );
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 void recTNE( void )
// coissued insts {
void (*recBSC_co[64] )() = { 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, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
@ -248,26 +241,26 @@ void (*recBSC_co[64] )() = {
recSB_co, recSH_co, recSWL_co, recSW_co, recSDL_co, recSDR_co, recSWR_co, recNULL, 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, recLWC1_co, recNULL, recNULL, recNULL, recNULL, recLQC2_co, recLD_co,
recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co
}; };
#endif #endif
void (*recSPC[64] )() = { } } // End namespace EE::Dynarec
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, static void recCOP0BC0( void )
recTGEI, recTGEIU, recTLTI, recTLTIU, recTEQI, recNULL, recTNEI, recNULL, {
recBLTZAL, recBGEZAL, recBLTZALL, recBGEZALL, recNULL, recNULL, recNULL, recNULL, recCP0BC0[ ( cpuRegs.code >> 16 ) & 0x03 ]( );
recMTSAB, recMTSAH, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, }
};
////////////////////////////////////////////////////
static void recCOP0C0( void )
{
recCP0C0[ _Funct_ ]( );
}
/////////////////////////////////
// Foward-Prob Function Tables //
/////////////////////////////////
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)
@ -82,12 +86,10 @@ 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 ] );
@ -4119,11 +4265,14 @@ void recSB( void )
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