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->fileLBA = internalTocEntry->fileLBA;
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){
// This is a Joliet Filesystem, so use Unicode to ISO string copy

View File

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

View File

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

View File

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

View File

@ -755,8 +755,7 @@ int rcntFreeze(gzFile f, int Mode) {
if( Mode == 0 )
{
int i;
#ifdef PCSX2_VIRTUAL_MEM
// Sanity check for loading older savestates:
if( counters[4].sCycle == 0 )
@ -764,9 +763,10 @@ int rcntFreeze(gzFile f, int Mode) {
if( counters[5].sCycle == 0 )
counters[5].sCycle = cpuRegs.cycle;
#endif
// 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 );
}

View File

@ -22,19 +22,23 @@
#include <stdio.h>
#include <zlib.h>
#include <string>
#include "Misc.h"
extern FILE *emuLog;
char* disR5900F(u32 code, u32 pc);
char* disR5900Fasm(u32 code, u32 pc);
void disR5900F( std::string& output, u32 code, u32 pc);
void disR5900Fasm( std::string& output, u32 code, u32 pc);
char* disR3000Fasm(u32 code, u32 pc);
void disR5900AddSym(u32 addr, char *name);
char* disR5900GetSym(u32 addr);
char* disR5900GetUpperSym(u32 addr);
void disR5900AddSym(u32 addr, const char *name);
const char* disR5900GetSym(u32 addr);
const char* disR5900GetUpperSym(u32 addr);
void disR5900FreeSyms();
void dFindSym( std::string& output, u32 addr );
void strAppend( std::string& output, const char *fmt, ... );
char* disVU0MicroUF(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 *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
#ifdef PCSX2_DEVBUILD

View File

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

View File

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

View File

@ -144,30 +144,6 @@
intDoBranch( _BranchTarget_ ); \
} 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
@ -267,13 +243,6 @@ void DIV_S() {
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
determining the flags that are set. Hopefully this shorter
method provides a similar outcome and is faster. (cottonvibes)
@ -386,9 +355,19 @@ void SUBA_S() {
checkUnderflow( _FAValUl_, FPUflagU | FPUflagSU, 1 );
}
void SWC1() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff);
if (addr & 0x00000003) { SysPrintf( "FPU (SWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memWrite32(addr, fpuRegs.fpr[_Rt_].UL);
}
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;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + (s32)(s16)(cpuRegs.code & 0xffff);
if (addr & 0x00000003) { SysPrintf( "FPU (SWC1 Opcode): Invalid Memory Address\n" ); return; } // Should signal an exception?
memWrite32(addr, fpuRegs.fpr[_Rt_].UL);
}
}}}

View File

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

View File

@ -287,7 +287,8 @@ u32 CSRw;
extern uptr pDsp;
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
#define gif ((DMACh*)&PS2MEM_HW[0xA000])
@ -412,7 +413,7 @@ void gsInit()
if( CHECK_MULTIGS ) {
#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
// setup linux vm
g_pGSRingPos = (u8*)SysMmap((uptr)GS_RINGBUFFERBASE, GS_RINGBUFFERSIZE);
@ -602,8 +603,63 @@ void gsShutdown()
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 )
{
#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,
// 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
@ -711,6 +767,18 @@ u8* GSRingBufCopy( u32 size, u32 type )
#endif
*(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;
}
@ -1285,9 +1353,9 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
{
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);
GSRINGBUF_DONECOPY(pgsmem, sizetoread);

View File

@ -45,10 +45,11 @@ extern u8 g_RealGSMem[0x2000];
#define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080))
#endif
#define GS_RINGBUFFERBASE (u8*)(0x10200000)
#define GS_RINGBUFFERBASE GS_RINGBUFF_STOREAGE
#define GS_RINGBUFFERSIZE 0x00300000 // 3Mb
#define GS_RINGBUFFEREND (u8*)(GS_RINGBUFFERBASE+GS_RINGBUFFERSIZE)
__declspec(align(4096)) extern u8 GS_RINGBUFF_STOREAGE[GS_RINGBUFFERSIZE];
enum GS_RINGTYPE
{
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) {
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 ConstReadFIFO(u32 mem);
void WriteFIFO(u32 mem, u64 *value);
void WriteFIFO(u32 mem, const u64 *value);
void ConstWriteFIFO(u32 mem);
@ -354,12 +354,12 @@ static __forceinline void *dmaGetAddr(u32 addr) {
return (void*)&psS[addr & 0x3ff0];
}
ptr = (u8*)memLUTR[addr >> 12];
ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0);
if (ptr == NULL) {
SysPrintf("*PCSX2*: DMA error: %8.8x\n", addr);
return NULL;
}
return (void*)(ptr + (addr & 0xff0));
return ptr;
}
#endif
@ -397,7 +397,7 @@ void hwConstWrite32(u32 mem, int mmreg);
void hwWrite64(u32 mem, u64 value);
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 hwIntcIrq(int n);
@ -409,6 +409,10 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size);
int hwDmacSrcChainWithStack(DMACh *dma, int id);
int hwDmacSrcChain(DMACh *dma, int id);
#ifdef PCSX2_VIRTUAL_MEM
void iMemRead32Check();
#endif
extern void intcInterrupt();
extern void dmacInterrupt();

View File

@ -20,98 +20,416 @@
#include "InterTables.h"
void (*Int_OpcodePrintTable[64])() =
namespace EE
{
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, UnknownOpcode, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, MMI, UnknownOpcode, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
UnknownOpcode, LWC1, UnknownOpcode, PREF, UnknownOpcode,UnknownOpcode, LQC2, LD,
UnknownOpcode, SWC1, UnknownOpcode, UnknownOpcode, UnknownOpcode,UnknownOpcode, SQC2, SD
};
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 );
void (*Int_SpecialPrintTable[64])() =
{
SLL, UnknownOpcode, SRL, SRA, SLLV, UnknownOpcode, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, UnknownOpcode, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, UnknownOpcode, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, UnknownOpcode,UnknownOpcode,UnknownOpcode,UnknownOpcode,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA , MTSA , SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, UnknownOpcode, TNE, UnknownOpcode,
DSLL, UnknownOpcode, DSRL, DSRA, DSLL32, UnknownOpcode, DSRL32, DSRA32
};
// Multimedia Instructions!
void (*Int_REGIMMPrintTable[32])() = {
BLTZ, BGEZ, BLTZL, BGEZL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
TGEI, TGEIU, TLTI, TLTIU, TEQI, UnknownOpcode, TNEI, UnknownOpcode,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
MTSAB, MTSAH , UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode, UnknownOpcode,
};
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 );
void (*Int_MMIPrintTable[64])() =
{
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,
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI1 , MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
};
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 );
void (*Int_MMI0PrintTable[32])() =
{
PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDSW, PSUBSW, PEXTLW, PPACW,
PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
};
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 );
void (*Int_MMI1PrintTable[32])() =
{
MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDUW, PSUBUW, PEXTUW, MMI_Unknown,
PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
};
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,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, Unknown, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, Opcodes::MMI, Unknown, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
Unknown, LWC1, Unknown, PREF, Unknown, Unknown, LQC2, LD,
Unknown, SWC1, Unknown, Unknown, Unknown, Unknown, SQC2, SD
};
const OPCODE Special[64] =
{
SLL, Unknown, SRL, SRA, SLLV, Unknown, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, Unknown, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, Unknown, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, Unknown, Unknown, Unknown, Unknown,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA, MTSA, SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, Unknown, TNE, Unknown,
DSLL, Unknown, DSRL, DSRA, DSLL32, Unknown, DSRL32, DSRA32
};
const OPCODE RegImm[32] = {
BLTZ, BGEZ, BLTZL, BGEZL, Unknown, Unknown, Unknown, Unknown,
TGEI, TGEIU, TLTI, TLTIU, TEQI, Unknown, TNEI, Unknown,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, Unknown, Unknown, Unknown, Unknown,
MTSAB, MTSAH , Unknown, Unknown, Unknown, Unknown, Unknown, Unknown,
};
const OPCODE MMI[64] =
{
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
Opcodes::MMI0, Opcodes::MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
Opcodes::MMI1, Opcodes::MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
};
const OPCODE MMI0[32] =
{
PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDSW, PSUBSW, PEXTLW, PPACW,
PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
};
const OPCODE MMI1[32] =
{
MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDUW, PSUBUW, PEXTUW, MMI_Unknown,
PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
};
void (*Int_MMI2PrintTable[32])() =
{
PMADDW, MMI_Unknown, PSLLVW, PSRLVW,
PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHI, PMFLO, PINTH, MMI_Unknown,
PMULTW, PDIVW, PCPYLD, MMI_Unknown,
PMADDH, PHMADH, PAND, PXOR,
PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXEH, PREVH,
PMULTH, PDIVBW, PEXEW, PROT3W,
};
const OPCODE MMI2[32] =
{
PMADDW, MMI_Unknown, PSLLVW, PSRLVW,
PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHI, PMFLO, PINTH, MMI_Unknown,
PMULTW, PDIVW, PCPYLD, MMI_Unknown,
PMADDH, PHMADH, PAND, PXOR,
PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXEH, PREVH,
PMULTH, PDIVBW, PEXEW, PROT3W,
};
void (*Int_MMI3PrintTable[32])() =
{
PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMTHI, PMTLO, PINTEH, MMI_Unknown,
PMULTUW, PDIVUW, PCPYUD, MMI_Unknown,
MMI_Unknown, MMI_Unknown, POR, PNOR,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXCH, PCPYH,
MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown,
};
const OPCODE MMI3[32] =
{
PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMTHI, PMTLO, PINTEH, MMI_Unknown,
PMULTUW, PDIVUW, PCPYUD, MMI_Unknown,
MMI_Unknown, MMI_Unknown, POR, PNOR,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXCH, PCPYH,
MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown,
};
} // end namespace EE::OpcodeTables
} // end namespace EE
void (*Int_COP0PrintTable[32])() =
{

View File

@ -18,14 +18,62 @@
#ifndef INTERTABLES_H
#define INTERTABLES_H
extern void (*Int_OpcodePrintTable[64])();
extern void (*Int_SpecialPrintTable[64])();
extern void (*Int_REGIMMPrintTable[32])();
extern void (*Int_MMIPrintTable[64])();
extern void (*Int_MMI0PrintTable[32])();
extern void (*Int_MMI1PrintTable[32])();
extern void (*Int_MMI2PrintTable[32])();
extern void (*Int_MMI3PrintTable[32])();
#include <string>
#include "PS2ETypes.h"
#include "iR5900AritImm.h"
#include "iR5900Arit.h"
#include "iR5900MultDiv.h"
#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_COP0BC0PrintTable[32])();
extern void (*Int_COP0C0PrintTable[64])();
@ -38,18 +86,6 @@ extern void (*Int_COP2BC2PrintTable[32])();
extern void (*Int_COP2SPECIAL1PrintTable[64])();
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_BC0();
void COP0_Func();
@ -62,240 +98,602 @@ void COP2_SPECIAL();
void COP2_Unknown();
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**************************
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();
void J( std::string& output );
void JAL( std::string& output );
void BEQ( std::string& output );
void BNE( std::string& output );
void BLEZ( std::string& output );
void BGTZ( std::string& output );
void ADDI( std::string& output );
void ADDIU( std::string& output );
void SLTI( std::string& output );
void SLTIU( std::string& output );
void ANDI( std::string& output );
void ORI( std::string& output );
void XORI( std::string& output );
void LUI( std::string& output );
void BEQL( std::string& output );
void BNEL( std::string& output );
void BLEZL( std::string& output );
void BGTZL( std::string& output );
void DADDI( std::string& output );
void DADDIU( std::string& output );
void LDL( std::string& output );
void LDR( std::string& output );
void LB( std::string& output );
void LH( std::string& output );
void LWL( std::string& output );
void LW( std::string& output );
void LBU( std::string& output );
void LHU( std::string& output );
void LWR( std::string& output );
void LWU( std::string& output );
void SB( std::string& output );
void SH( std::string& output );
void SWL( std::string& output );
void SW( std::string& output );
void SDL( std::string& output );
void SDR( std::string& output );
void SWR( std::string& output );
void CACHE( std::string& output );
void LWC1( std::string& output );
void PREF( std::string& output );
void LQC2( std::string& output );
void LD( std::string& output );
void SQC2( std::string& output );
void SD( std::string& output );
void LQ( std::string& output );
void SQ( std::string& output );
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*************************
//***************SPECIAL OPCODES**********************************
void SLL();
void SRL();
void SRA();
void SLLV();
void SRLV();
void SRAV();
void JR();
void JALR();
void SYSCALL();
void BREAK();
void SYNC();
void MFHI();
void MTHI();
void MFLO();
void MTLO();
void DSLLV();
void DSRLV();
void DSRAV();
void MULT();
void MULTU();
void DIV();
void DIVU();
void ADD();
void ADDU();
void SUB();
void SUBU();
void AND();
void OR();
void XOR();
void NOR();
void SLT();
void SLTU();
void DADD();
void DADDU();
void DSUB();
void DSUBU();
void TGE();
void TGEU();
void TLT();
void TLTU();
void TEQ();
void TNE();
void DSLL();
void DSRL();
void DSRA();
void DSLL32();
void DSRL32();
void DSRA32();
void MOVZ();
void MOVN();
void MFSA();
void MTSA();
void SLL();
void SRL();
void SRA();
void SLLV();
void SRLV();
void SRAV();
void JR();
void JALR();
void SYSCALL();
void BREAK();
void SYNC();
void MFHI();
void MTHI();
void MFLO();
void MTLO();
void DSLLV();
void DSRLV();
void DSRAV();
void MULT();
void MULTU();
void DIV();
void DIVU();
void ADD();
void ADDU();
void SUB();
void SUBU();
void AND();
void OR();
void XOR();
void NOR();
void SLT();
void SLTU();
void DADD();
void DADDU();
void DSUB();
void DSUBU();
void TGE();
void TGEU();
void TLT();
void TLTU();
void TEQ();
void TNE();
void DSLL();
void DSRL();
void DSRA();
void DSLL32();
void DSRL32();
void DSRA32();
void MOVZ();
void MOVN();
void MFSA();
void MTSA();
//******************END OF SPECIAL OPCODES**************************
//******************REGIMM OPCODES**********************************
void BLTZ();
void BGEZ();
void BLTZL();
void BGEZL();
void TGEI();
void TGEIU();
void TLTI();
void TLTIU();
void TEQI();
void TNEI();
void BLTZAL();
void BGEZAL();
void BLTZALL();
void BGEZALL();
void MTSAB();
void MTSAH();
void BLTZ();
void BGEZ();
void BLTZL();
void BGEZL();
void TGEI();
void TGEIU();
void TLTI();
void TLTIU();
void TEQI();
void TNEI();
void BLTZAL();
void BGEZAL();
void BLTZALL();
void BGEZALL();
void MTSAB();
void MTSAH();
//*****************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();
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();
//*****************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();
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******************************************
//**********MMI1 OPCODES**************************************
void PABSW();
void PCEQW();
void PMINW();
void PADSBH();
void PABSH();
void PCEQH();
void PMINH();
void PCEQB();
void PADDUW();
void PSUBUW();
void PEXTUW();
void PADDUH();
void PSUBUH();
void PEXTUH();
void PADDUB();
void PSUBUB();
void PEXTUB();
void QFSRV();
void PABSW();
void PCEQW();
void PMINW();
void PADSBH();
void PABSH();
void PCEQH();
void PMINH();
void PCEQB();
void PADDUW();
void PSUBUW();
void PEXTUW();
void PADDUH();
void PSUBUH();
void PEXTUH();
void PADDUB();
void PSUBUB();
void PEXTUB();
void QFSRV();
//********END OF MMI1 OPCODES***********************************
//*********MMI2 OPCODES***************************************
void PMADDW();
void PSLLVW();
void PSRLVW();
void PMSUBW();
void PMFHI();
void PMFLO();
void PINTH();
void PMULTW();
void PDIVW();
void PCPYLD();
void PMADDH();
void PHMADH();
void PAND();
void PXOR();
void PMSUBH();
void PHMSBH();
void PEXEH();
void PREVH();
void PMULTH();
void PDIVBW();
void PEXEW();
void PROT3W();
void PMADDW();
void PSLLVW();
void PSRLVW();
void PMSUBW();
void PMFHI();
void PMFLO();
void PINTH();
void PMULTW();
void PDIVW();
void PCPYLD();
void PMADDH();
void PHMADH();
void PAND();
void PXOR();
void PMSUBH();
void PHMSBH();
void PEXEH();
void PREVH();
void PMULTH();
void PDIVBW();
void PEXEW();
void PROT3W();
//*****END OF MMI2 OPCODES***********************************
//*************************MMI3 OPCODES************************
void PMADDUW();
void PSRAVW();
void PMTHI();
void PMTLO();
void PINTEH();
void PMULTUW();
void PDIVUW();
void PCPYUD();
void POR();
void PNOR();
void PEXCH();
void PCPYH();
void PEXCW();
void PMADDUW();
void PSRAVW();
void PMTHI();
void PMTLO();
void PINTEH();
void PMULTUW();
void PDIVUW();
void PCPYUD();
void POR();
void PNOR();
void PEXCH();
void PCPYH();
void PEXCW();
//**********************END OF MMI3 OPCODES********************
}
} // end namespace Interpreter
} // End namespace EE
//****************************************************************************
//** COP0 **
//****************************************************************************

View File

@ -25,8 +25,6 @@
#include <float.h>
extern u32 maxrecmem;
const char *bios[256]={
//0x00
"RFU000_FullReset", "ResetEE", "SetGsCrt", "RFU003",
@ -76,25 +74,40 @@ const char *bios[256]={
"Deci2Call", "PSMode", "MachineType", "GetMemorySize",
};
extern void (*LT_OpcodePrintTable[64])();
int branch2 = 0;
static u32 branchPC;
// These macros are used to assemble the repassembler functions
#ifdef CPU_LOG
#define debugI() \
if (Log) { CPU_LOG("%s\n", disR5900F(cpuRegs.code, cpuRegs.pc)); } \
#ifdef PCSX2_DEVBUILD
static void debugI()
{
//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");
}
#else
#define debugI()
static void debugI() {}
#endif
static __forceinline void execI() {
static u32 cpuBlockCycles = 0; // 3 bit fixed point version of cycle count
cpuRegs.cycle++;
//cpuRegs.CP0.n.Count++; /*count every cycles.*/
namespace EE
{
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
if (memRead32(cpuRegs.pc, &cpuRegs.code) == -1) return;
debugI();
@ -102,8 +115,17 @@ static __forceinline void execI() {
cpuRegs.code = *(u32 *)PSM(cpuRegs.pc);
#endif
cpuRegs.pc+= 4;
Int_OpcodePrintTable[cpuRegs.code >> 26]();
const EE::OPCODE& opcode = EE::GetCurrentInstruction();
/*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) {
@ -113,6 +135,8 @@ static void doBranch(u32 tar) {
cpuRegs.branch = 0;
cpuRegs.pc = branchPC;
cpuRegs.cycle += cpuBlockCycles >> 3;
cpuBlockCycles &= (1<<3)-1;
IntcpuBranchTest();
}
@ -125,11 +149,68 @@ void intSetBranch() {
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);
}
@ -385,11 +466,11 @@ void LB() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead8RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead8RS(addr, &dummy);
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s8)temp;
}
}
@ -397,11 +478,11 @@ void LBU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead8RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead8RU(addr, &dummy);
u8 temp;
const u32 rt=_Rt_;
if ((0==memRead8(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
@ -409,11 +490,11 @@ void LH() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead16RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead16RS(addr, &dummy);
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s16)temp;
}
}
@ -421,35 +502,38 @@ void LHU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead16RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead16RU(addr, &dummy);
u16 temp;
const u32 rt=_Rt_;
if ((0==memRead16(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
void LW() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead32RS(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead32RS(addr, &dummy);
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=(s32)temp;
}
}
void LWU() {
u32 addr;
addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_;
if (_Rt_) {
memRead32RU(addr, &cpuRegs.GPR.r[_Rt_].UD[0]);
} else {
u64 dummy;
memRead32RU(addr, &dummy);
u32 temp;
const u32 rt=_Rt_;
if ((0==memRead32(addr, &temp)) && (rt!=0))
{
cpuRegs.GPR.r[rt].UD[0]=temp;
}
}
@ -625,7 +709,7 @@ void SD() {
u32 addr;
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,
@ -638,9 +722,9 @@ void SDL() {
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
memWrite64(addr & ~7, (cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
( mem & SDL_MASK[shift]) );
mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) |
( mem & SDL_MASK[shift]);
memWrite64(addr & ~7, &mem);
}
u64 SDR_MASK[8] = { 0x0000000000000000LL, 0x00000000000000ffLL, 0x000000000000ffffLL, 0x0000000000ffffffLL,
@ -653,9 +737,9 @@ void SDR() {
u64 mem;
if (memRead64(addr & ~7, &mem) == -1) return;
memWrite64(addr & ~7, (cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
( mem & SDR_MASK[shift]) );
mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) |
( mem & SDR_MASK[shift]);
memWrite64(addr & ~7, &mem );
}
void SQ() {
@ -929,7 +1013,7 @@ void MTSAH() {
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 "Common.h"
#include "DebugTools/Debug.h"
#include "R5900.h"
#include "InterTables.h"
namespace EE { namespace Interpreter{ namespace OpcodeImpl
{
void MMI() {
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");
}
void MMI_Unknown() { SysPrintf ("Unknown MMI opcode called\n"); }
//*****************MMI OPCODES*********************************
@ -1564,3 +1544,4 @@ void PEXCW() {
// obs:
// 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))
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
extern u8 *psM; //32mb Main Ram
@ -87,16 +104,9 @@ extern u8 g_RealGSMem[0x2000];
#define PS2MEM_GS g_RealGSMem
//#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)
extern uptr *memLUTR;
extern uptr *memLUTW;
extern uptr *memLUTRK;
extern uptr *memLUTWK;
extern uptr *memLUTRU;
extern uptr *memLUTWU;
#endif
#define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
@ -171,23 +181,6 @@ void memSetPageAddr(u32 vaddr, u32 paddr);
void memClearPageAddr(u32 vaddr);
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
u8 recMemRead8();
u16 recMemRead16();
@ -202,39 +195,37 @@ void recMemWrite32();
void recMemWrite64();
void recMemWrite128();
// VM only functions
#ifdef PCSX2_VIRTUAL_MEM
int SysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps);
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);
#ifndef PCSX2_VIRTUAL_MEM
#include "vtlb.h"
// extra ops
void _eeWriteConstMem16OP(u32 mem, int mmreg, int op);
void _eeWriteConstMem32OP(u32 mem, int mmreg, int op);
int mmap_GetRamPageInfo(void* ptr);
void mmap_MarkCountedRamPage(void* ptr,u32 vaddr);
void mmap_ResetBlockTracking();
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 __fastcall _memRead8(u32 mem, u8 *out);
int __fastcall _memRead16(u32 mem, u16 *out);
int __fastcall _memRead32(u32 mem, u32 *out);
int __fastcall _memRead64(u32 mem, u64 *out);
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);
int recMemConstWrite16(u32 mem, int mmreg);
int recMemConstWrite32(u32 mem, int mmreg);
int recMemConstWrite64(u32 mem, int mmreg);
int recMemConstWrite128(u32 mem, int xmmreg);
#define memRead8 vtlb_memRead8
#define memRead16 vtlb_memRead16
#define memRead32 vtlb_memRead32
#define memRead64 vtlb_memRead64
#define memRead128 vtlb_memRead128
extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps);
#else
#define memWrite8 vtlb_memWrite8
#define memWrite16 vtlb_memWrite16
#define memWrite32 vtlb_memWrite32
#define memWrite64 vtlb_memWrite64
#define memWrite128 vtlb_memWrite128
#define _eeReadConstMem8 0&&
#define _eeReadConstMem16 0&&
@ -263,6 +254,38 @@ extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps);
#define recMemConstWrite64 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

View File

@ -39,12 +39,11 @@
#include "iVUzerorec.h"
#include "GS.h"
#include "COP0.h"
#include "Cache.h"
#include "Paths.h"
u32 dwSaveVersion = 0x7a300010;
u32 dwCurSaveStateVer = 0;
extern u32 s_iLastCOP0Cycle;
extern u32 s_iLastPERFCycle[2];
@ -397,7 +396,7 @@ int connected=0;
void __Log(const char *fmt, ...) {
#ifdef EMU_LOG
va_list list;
static char tmp[2024]; //hm, should be enough
char tmp[2024]; //hm, should be enough
va_start(list, fmt);
#ifdef _WIN32
@ -475,7 +474,7 @@ int SaveState(const char *file) {
f = gzopen(file, "wb");
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_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*)&fpuRegs, sizeof(fpuRegs)); // fpu regs
gzwrite(f, (void*)&tlb, sizeof(tlb)); // tlbs
gzwrite(f, &EEsCycle, sizeof(EEsCycle));
gzwrite(f, &EEoCycle, sizeof(EEoCycle));
gzwrite(f, &psxRegs.cycle, sizeof(u32)); // used to be IOPoCycle. This retains compatibility.
gzwrite(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
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_iLastPERFCycle, sizeof(u32)*2);
gzwrite(f, &g_psxWriteOk, sizeof(g_psxWriteOk));
//gzwrite(f, (void*)&ipuRegs, sizeof(IPUregisters)); // ipu regs
//hope didn't forgot any cpu....
rcntFreeze(f, 1);
@ -571,20 +568,28 @@ int LoadState(const char *file) {
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) {
gzclose(f);
SysPrintf("State to load is a different version from current.\n");
SysPrintf("Unsupported savestate version: %x.\n", dwCurSaveStateVer );
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
gsWaitGS();
for (i=0; i<48; i++) ClearTLB(i);
for (i=0; i<48; i++) UnmapTLB(i);
Cpu->Reset();
#ifndef PCSX2_NORECBUILD
@ -627,9 +632,7 @@ int LoadState(const char *file) {
gzread(f, &dud, sizeof(u32)); // was IOPoCycle
gzread(f, &g_nextBranchCycle, sizeof(g_nextBranchCycle));
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));
if( dwCurSaveStateVer >= 0x7a30000e ) {
gzread(f, s_iLastPERFCycle, sizeof(u32)*2);
@ -684,7 +687,7 @@ int LoadState(const char *file) {
//dumplog |= 4;
WriteCP0Status(cpuRegs.CP0.n.Status.val);
for (i=0; i<48; i++) WriteTLB(i);
for (i=0; i<48; i++) MapTLB(i);
return 0;
}

View File

@ -137,18 +137,24 @@ extern PcsxConfig Config;
extern u32 BiosVersion;
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 CheckCdrom();
int GetPS2ElfName(char*);
extern const char *LabelAuthors;
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 LoadState(const char *file);
int CheckState(const char *file);
@ -156,6 +162,14 @@ int CheckState(const char *file);
int SaveGSState(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);
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__)
// 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);
#define memcpy_fast memcpy_amd_
//#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_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
// cross-platform atomic operations

View File

@ -44,6 +44,7 @@ typedef unsigned __int16 u16;
typedef unsigned __int32 u32;
typedef unsigned __int64 u64;
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
#define PCSX2_ALIGNED16(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;
switch (p->cpu) {
case EE:
case CPU_EE:
switch (p->type) {
case BYTE_T:
memWrite8(p->addr, (u8)p->data);
@ -140,7 +140,7 @@ void _applypatch(int place, IniPatch *p) {
memWrite32(p->addr, (u32)p->data);
break;
case DOUBLE_T:
memWrite64(p->addr, p->data);
memWrite64(p->addr, &p->data);
break;
case EXTENDED_T:
if (SkipCount > 0){
@ -327,7 +327,7 @@ void _applypatch(int place, IniPatch *p) {
}
}
break;
case IOP: {
case CPU_IOP: {
switch (p->type) {
case BYTE_T:
psxMemWrite8(p->addr, (u8)p->data);
@ -579,7 +579,7 @@ void patchFunc_fastmemory( char * cmd, char * param )
{
#ifndef PCSX2_NORECBUILD
// only valid for recompilers
SetFastMemory(1);
EE::Dynarec::SetFastMemory(1);
#endif
}

View File

@ -43,9 +43,10 @@
enum patch_cpu_type {
NO_CPU,
EE,
IOP
CPU_EE,
CPU_IOP
};
enum patch_data_type {
NO_TYPE,
BYTE_T,
@ -128,7 +129,10 @@ void resetpatch( void );
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
extern void SetVUNanMode(int mode);

View File

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

View File

@ -883,7 +883,7 @@ void psxHwWrite32(u32 add, u32 value) {
case 0x1f801078:
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;
//SSBus registers

View File

@ -43,13 +43,11 @@ s32 EEsCycle; // used to sync the IOP to the EE
u32 EEoCycle;
u32 bExecBIOS = 0; // set if the BIOS has already been executed
extern u32 dwSaveVersion;
int cpuInit()
{
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);
cpuRegs.constzero = 0;
@ -220,7 +218,7 @@ void cpuException(u32 code, u32 bd) {
}
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) {
SysPrintf("branch delay!!\n");
}

View File

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

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");
#endif
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, "Total VSyncs: %d (%s)\n", stats.vsyncCount, Config.PsxType ? "PAL" : "NTSC");
#ifndef __x86_64__

View File

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

View File

@ -1672,11 +1672,10 @@ static int Vif1TransDirectHL(u32 *data){
u8* gsmem = GSRingBufCopy(ret<<2, GS_RINGTYPE_P2);
if( gsmem != NULL ) {
FreezeMMXRegs(1);
memcpy_fast(gsmem, data, ret<<2);
FreezeMMXRegs(0);
GSgifTransferDummy(1, data, ret>>2);
//unaligned copy.VIF handling is -very- messy, so i'l use this code til i fix it :)
memcpy_raz_u(gsmem,data,ret<<2);
GSRINGBUF_DONECOPY(gsmem, ret<<2);
GSgifTransferDummy(1, data, ret>>2);
}
}
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 <windowsx.h>
#include <stdio.h>
#include <string>
#include "resource.h"
#include "InterTables.h"
#include "Debugger.h"
#include "Common.h"
#include "win32.h"
#include "PsxMem.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 UpdateR5900op();
void RefreshIOPDebugger(void);
@ -155,24 +162,22 @@ BOOL APIENTRY DumpProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
}
else
{
std::string output;
fprintf(fp,"----------------------------------\n");
fprintf(fp,"EE DISASM TEXT DOCUMENT BY PCSX2 \n");
fprintf(fp,"----------------------------------\n");
for (temp = start_pc; temp <= end_pc; temp += 4)
{
opcode_addr=temp;
MakeDebugOpcode();
OpcodePrintTable[(cpuRegs.code) >> 26](tmp);
if (HasBreakpoint())
{
sprintf(buf, "*%08X %08X: %s", temp, cpuRegs.code, tmp);
}
else
{
sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
}
MakeDebugOpcode();
output.assign( HasBreakpoint() ? "*" : "" );
sprintf(buf, "%08X %08X: %s", temp, cpuRegs.code, tmp);
output.append( buf );
EE::OpcodeTables::Standard[_Opcode_].decode( output );
fprintf(fp, "%s\n", buf);
}
@ -636,25 +641,24 @@ void RefreshDebugger(void)
for (t = DebuggerPC, cnt = 0; t < (DebuggerPC + 0x00000074); t += 0x00000004, cnt++)
{
char syscall_str[128];
char syscall_str[256];
// Make the opcode.
u32 *mem = (u32*)PSM(t);
char *str;
if (mem == NULL) {
char nullAddr[256];
sprintf(nullAddr, "%8.8lx 00000000: NULL MEMORY", t); str = nullAddr;
sprintf(syscall_str, "%8.8lx 00000000: NULL MEMORY", t);
} else {
/* special procesing for syscall. This should probably be moved into the disR5900Fasm() call in the future. */
if (0x0c == *mem && 0x24030000 == (*(mem-1) & 0xFFFFFF00)){
/* it's a syscall preceeded by a li v1,$data instruction. */
u8 bios_call = *(mem-1) & 0xFF;
sprintf(syscall_str, "%08X:\tsyscall\t%s", t, bios[bios_call]);
str = syscall_str;
} 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
extern void (*OpcodePrintTable[64])(char *buf);
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 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>
<Configurations>
<Configuration
Name="Release|Win32"
Name="Release VM|Win32"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0"
@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2.exe"
OutputFile="$(SolutionDir)\bin\pcsx2-vm.exe"
/>
<Tool
Name="VCALinkTool"
@ -91,7 +91,7 @@
/>
</Configuration>
<Configuration
Name="Debug|Win32"
Name="Debug vm|Win32"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\virtualmem.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0"
@ -137,7 +137,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
OutputFile="$(SolutionDir)\bin\pcsx2d.exe"
OutputFile="$(SolutionDir)\bin\pcsx2d-vm.exe"
/>
<Tool
Name="VCALinkTool"
@ -163,7 +163,7 @@
/>
</Configuration>
<Configuration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\debug.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0"
@ -209,7 +209,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
OutputFile="$(SolutionDir)\bin\pcsx2td.exe"
OutputFile="$(SolutionDir)\bin\pcsx2d-vtlb.exe"
/>
<Tool
Name="VCALinkTool"
@ -235,7 +235,7 @@
/>
</Configuration>
<Configuration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\devbuild.vsprops"
UseOfMFC="0"
@ -302,7 +302,7 @@
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(SolutionDir)\bin\pcsx2t.exe"
OutputFile="$(SolutionDir)\bin\pcsx2-vtlb.exe"
/>
<Tool
Name="VCALinkTool"
@ -328,7 +328,7 @@
/>
</Configuration>
<Configuration
Name="Release (to Public)|Win32"
Name="Release VM (to Public)|Win32"
ConfigurationType="1"
InheritedPropertySheets=".\vsprops\common.vsprops;.\vsprops\release.vsprops;.\vsprops\virtualmem.vsprops"
UseOfMFC="0"
@ -377,7 +377,85 @@
/>
<Tool
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;"
/>
<Tool
@ -550,6 +628,14 @@
RelativePath="..\..\PathUtils.c"
>
</File>
<File
RelativePath="..\SamplProf.cpp"
>
</File>
<File
RelativePath="..\SamplProf.h"
>
</File>
<File
RelativePath="..\..\System.h"
>
@ -682,7 +768,7 @@
RelativePath="..\..\zlib\adler32.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -690,7 +776,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -698,7 +784,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -706,7 +792,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -714,7 +800,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -726,7 +820,7 @@
RelativePath="..\..\zlib\compress.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -734,7 +828,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -742,7 +836,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -750,7 +844,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -758,7 +852,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -770,7 +872,7 @@
RelativePath="..\..\zlib\crc32.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -778,7 +880,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -786,7 +888,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -794,7 +896,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -802,7 +904,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -818,7 +928,7 @@
RelativePath="..\..\zlib\deflate.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -826,7 +936,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -834,7 +944,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -842,7 +952,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -850,7 +960,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -866,7 +984,7 @@
RelativePath="..\..\zlib\gzio.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -874,7 +992,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -882,7 +1000,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -890,7 +1008,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -898,7 +1016,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -910,7 +1036,7 @@
RelativePath="..\..\zlib\infback.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -918,7 +1044,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -926,7 +1052,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -934,7 +1060,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -942,7 +1068,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -954,7 +1088,7 @@
RelativePath="..\..\zlib\inffast.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -962,7 +1096,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -970,7 +1104,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -978,7 +1112,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -986,7 +1120,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1006,7 +1148,7 @@
RelativePath="..\..\zlib\inflate.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1014,7 +1156,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1022,7 +1164,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1030,7 +1172,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1038,7 +1180,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1054,7 +1204,7 @@
RelativePath="..\..\zlib\inftrees.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1062,7 +1212,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1070,7 +1220,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1078,7 +1228,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1086,7 +1236,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1102,7 +1260,7 @@
RelativePath="..\..\zlib\trees.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1110,7 +1268,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1118,7 +1276,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1126,7 +1284,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1134,7 +1292,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1150,7 +1316,7 @@
RelativePath="..\..\zlib\uncompr.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1158,7 +1324,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1166,7 +1332,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1174,7 +1340,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1182,7 +1348,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1202,7 +1376,7 @@
RelativePath="..\..\zlib\zutil.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1210,7 +1384,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1218,7 +1392,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1226,7 +1400,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1234,7 +1408,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1250,6 +1432,14 @@
<Filter
Name="Ps2"
>
<File
RelativePath="..\..\vtlb.cpp"
>
</File>
<File
RelativePath="..\..\vtlb.h"
>
</File>
<Filter
Name="EE"
>
@ -1269,7 +1459,7 @@
RelativePath="..\..\Counters.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1277,7 +1467,16 @@
/>
</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
Name="VCCLCompilerTool"
@ -1369,7 +1568,7 @@
RelativePath="..\..\x86\iFPU.c"
>
<FileConfiguration
Name="Release|Win32"
Name="Release VM|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1377,7 +1576,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
Name="Debug vm|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1385,7 +1584,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Debug TLB|Win32"
Name="Debug vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1393,7 +1592,7 @@
/>
</FileConfiguration>
<FileConfiguration
Name="Release TLB|Win32"
Name="Release vtlb|Win32"
>
<Tool
Name="VCCLCompilerTool"
@ -1401,7 +1600,15 @@
/>
</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
Name="VCCLCompilerTool"
@ -1461,7 +1668,15 @@
RelativePath="..\..\x86\ir5900tables.c"
>
<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
Name="VCCLCompilerTool"

View File

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

View File

@ -85,10 +85,310 @@ void checkregs()
if( g_EEFreezeRegs ) assert( g_globalMMXSaved );
}
#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)
{
#ifdef _DEBUG
__asm call checkregs
#endif

View File

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

View File

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

View File

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

View File

@ -1284,7 +1284,7 @@ void recDIV_S_xmm(int info)
_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));
}
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)
{
@ -1811,7 +1811,7 @@ void recSQRT_S_xmm(int info)
_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);
}
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

View File

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

View File

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

View File

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

View File

@ -40,50 +40,6 @@
#define CP0_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_FPU_REGCACHING 1 // Not used anymore, its always on!
@ -101,22 +57,20 @@ extern u32 pc;
extern int branch;
extern uptr* recLUT;
extern u32 maxrecmem;
extern u32 pc; // recompiler pc
extern int branch; // set for branch
extern u32 target; // branch target
extern u16 x86FpuState;
extern u16 iCWstate;
extern u32 s_nBlockCycles; // cycles of current block recompiling
extern u32 g_eeCyclePenalty;
void recBranchCall( void (*func)() );
#define REC_FUNC_INLINE( f, delreg ) \
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code ); \
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \
iFlushCall(FLUSH_EVERYTHING); \
if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \
CALLFunc( (uptr)f );
CALLFunc( (uptr)EE::Interpreter::OpcodeImpl::f );
#define REC_FUNC( f, delreg ) \
void f( void ); \
@ -126,7 +80,7 @@ void recBranchCall( void (*func)() );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc ); \
iFlushCall(FLUSH_EVERYTHING); \
if( (delreg) > 0 ) _deleteEEreg(delreg, 0); \
CALLFunc( (uptr)f ); \
CALLFunc( (uptr)Interpreter::OpcodeImpl::f ); \
}
#define REC_SYS( f ) \
@ -152,9 +106,6 @@ void iFlushCall(int flushtype);
void SaveCW();
void LoadCW();
extern void (*recBSC[64])();
extern void (*recSPC[64])();
extern void (*recREG[32])();
extern void (*recCP0[32])();
extern void (*recCP0BC0[32])();
extern void (*recCP0C0[64])();
@ -162,11 +113,13 @@ extern void (*recCP1[32])();
extern void (*recCP1BC1[32])();
extern void (*recCP1S[64])();
extern void (*recCP1W[64])();
extern void (*recMMIt[64])();
extern void (*recMMI0t[32])();
extern void (*recMMI1t[32])();
extern void (*recMMI2t[32])();
extern void (*recMMI3t[32])();
namespace EE { namespace Dynarec {
extern void (*recBSC_co[64])();
void recBranchCall( void (*func)() );
} }
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); \
}
#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) \
void rec##fn(void) \
{ \
@ -298,13 +237,6 @@ void rec##fn(void) \
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)
int eeRecompileCodeXMM(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__

View File

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

View File

@ -19,23 +19,22 @@
#ifndef __IR5900ARITIMM_H__
#define __IR5900ARITIMM_H__
#include "Common.h"
#include "InterTables.h"
/*********************************************************
* Arithmetic with immediate operand *
* 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 recADDIU( void );
void recDADDI( void );
void recDADDIU( void );
void recANDI( void );
void recORI( void );
void recXORI( void );
void recSLTI( void );
void recSLTIU( void );
void recSLTI( void );
void recSLTIU( void );
} } }
#endif

View File

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

View File

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

View File

@ -23,68 +23,71 @@
* Format: OP rt, offset(base) *
*********************************************************/
void recLB( void );
void recLBU( void );
void recLH( void );
void recLHU( void );
void recLW( void );
void recLWU( void );
void recLWL( void );
void recLWR( void );
void recLD( void );
void recLDR( void );
void recLDL( void );
void recLQ( void );
void recSB( void );
void recSH( void );
void recSW( void );
void recSWL( void );
void recSWR( void );
void recSD( void );
void recSDL( void );
void recSDR( void );
void recSQ( void );
void recLWC1( void );
void recSWC1( void );
void recLQC2( void );
void recSQC2( void );
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
void recLB( void );
void recLBU( void );
void recLH( void );
void recLHU( void );
void recLW( void );
void recLWU( void );
void recLWL( void );
void recLWR( void );
void recLD( void );
void recLDR( void );
void recLDL( void );
void recLQ( void );
void recSB( void );
void recSH( void );
void recSW( void );
void recSWL( void );
void recSWR( void );
void recSD( void );
void recSDL( void );
void recSDR( void );
void recSQ( void );
void recLWC1( void );
void recSWC1( void );
void recLQC2( void );
void recSQC2( void );
// coissues
#ifdef PCSX2_VIRTUAL_MEM
void recLB_co( void );
void recLBU_co( void );
void recLH_co( void );
void recLHU_co( void );
void recLW_co( void );
void recLWU_co( void );
void recLWL_co( void );
void recLWR_co( void );
void recLD_co( void );
void recLDR_co( void );
void recLDL_co( void );
void recLQ_co( void );
void recSB_co( void );
void recSH_co( void );
void recSW_co( void );
void recSWL_co( void );
void recSWR_co( void );
void recSD_co( void );
void recSDL_co( void );
void recSDR_co( void );
void recSQ_co( void );
void recLWC1_co( void );
void recSWC1_co( void );
void recLQC2_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);
// coissues
#ifdef PCSX2_VIRTUAL_MEM
void recLB_co( void );
void recLBU_co( void );
void recLH_co( void );
void recLHU_co( void );
void recLW_co( void );
void recLWU_co( void );
void recLWL_co( void );
void recLWR_co( void );
void recLD_co( void );
void recLDR_co( void );
void recLDL_co( void );
void recLQ_co( void );
void recSB_co( void );
void recSH_co( void );
void recSW_co( void );
void recSWL_co( void );
void recSWR_co( void );
void recSD_co( void );
void recSDL_co( void );
void recSDR_co( void );
void recSQ_co( void );
void recLWC1_co( void );
void recSWC1_co( void );
void recLQC2_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);
#endif
} } }
#endif

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
*/
// 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 <string.h>

View File

@ -44,28 +44,207 @@
#include "iCP0.h"
////////////////////////////////////////////////////
static void recNULL( void )
void recNULL( void )
{
SysPrintf("EE: Unimplemented op %x\n", cpuRegs.code);
}
////////////////////////////////////////////////////
static void recREGIMM( void )
namespace EE { namespace Dynarec
{
recREG[ _Rt_ ]( );
}
// Use this to call into interpreter functions that require an immediate branchtest
// to be done afterward (anything that throws an exception or enables interrupts, etc).
void recBranchCall( void (*func)() )
{
// In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle.
////////////////////////////////////////////////////
static void recSPECIAL( void )
{
recSPC[ _Funct_ ]( );
}
branch = 2;
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
////////////////////////////////////////////////////
static void recCOP0( void )
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
}
namespace OpcodeImpl
{
recCP0[ _Rs_ ]( );
}
////////////////////////////////////////////////////
void recUnknown()
{
// TODO : Unknown ops should throw an exception.
SysPrintf("EE: Unrecognized op %x\n", cpuRegs.code);
}
void recMMI_Unknown()
{
// TODO : Unknown ops should throw an exception.
SysPrintf("EE: Unrecognized MMI op %x\n", cpuRegs.code);
}
////////////////////////////////////////////////////
void recREGIMM( void )
{
EE::OpcodeTables::RegImm[ _Rt_ ].recompile();
}
////////////////////////////////////////////////////
void recSPECIAL( void )
{
EE::OpcodeTables::Special[ _Funct_ ].recompile( );
}
////////////////////////////////////////////////////
void recCOP0( void )
{
recCP0[ _Rs_ ]( );
}
////////////////////////////////////////////////////
void recCOP1( void )
{
recCP1[ _Rs_ ]( );
}
////////////////////////////////////////////////////
void recMMI( void )
{
EE::OpcodeTables::MMI[ _Funct_ ].recompile( );
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
////////////////////////////////////////////////////
//REC_SYS(PREF);
////////////////////////////////////////////////////
//REC_SYS(MFSA);
////////////////////////////////////////////////////
//REC_SYS(MTSA);
////////////////////////////////////////////////////
//REC_SYS(TGE);
////////////////////////////////////////////////////
//REC_SYS(TGEU);
////////////////////////////////////////////////////
//REC_SYS(TLT);
////////////////////////////////////////////////////
//REC_SYS(TLTU);
////////////////////////////////////////////////////
//REC_SYS(TEQ);
////////////////////////////////////////////////////
//REC_SYS(TNE);
////////////////////////////////////////////////////
//REC_SYS(TGEI);
////////////////////////////////////////////////////
//REC_SYS(TGEIU);
////////////////////////////////////////////////////
//REC_SYS(TLTI);
////////////////////////////////////////////////////
//REC_SYS(TLTIU);
////////////////////////////////////////////////////
//REC_SYS(TEQI);
////////////////////////////////////////////////////
//REC_SYS(TNEI);
////////////////////////////////////////////////////
//REC_SYS(MTSAB);
////////////////////////////////////////////////////
//REC_SYS(MTSAH);
////////////////////////////////////////////////////
//REC_SYS(CACHE);
void recCACHE()
{
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)Interpreter::OpcodeImpl::CACHE );
branch = 2;
}
void recTGE( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGE );
}
void recTGEU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEU );
}
void recTLT( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLT );
}
void recTLTU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTU );
}
void recTEQ( void )
{
recBranchCall( Interpreter::OpcodeImpl::TEQ );
}
void recTNE( void )
{
recBranchCall( Interpreter::OpcodeImpl::TNE );
}
void recTGEI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEI );
}
void recTGEIU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TGEIU );
}
void recTLTI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTI );
}
void recTLTIU( void )
{
recBranchCall( Interpreter::OpcodeImpl::TLTIU );
}
void recTEQI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TEQI );
}
void recTNEI( void )
{
recBranchCall( Interpreter::OpcodeImpl::TNEI );
}
} // End OpcodeImpl
using namespace OpcodeImpl;
#ifdef PCSX2_VIRTUAL_MEM
// coissued insts
void (*recBSC_co[64] )() = {
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recLDL_co, recLDR_co, recNULL, recNULL, recLQ_co, recSQ_co,
recLB_co, recLH_co, recLWL_co, recLW_co, recLBU_co, recLHU_co, recLWR_co, recLWU_co,
recSB_co, recSH_co, recSWL_co, recSW_co, recSDL_co, recSDR_co, recSWR_co, recNULL,
recNULL, recLWC1_co, recNULL, recNULL, recNULL, recNULL, recLQC2_co, recLD_co,
recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co
};
#endif
} } // End namespace EE::Dynarec
////////////////////////////////////////////////////
static void recCOP0BC0( void )
@ -79,195 +258,9 @@ 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)() )
{
// In order to make sure a branch test is performed, the nextBranchCycle is set
// to the current cpu cycle.
branch = 2;
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
// Might as well flush everything -- it'll all get flushed when the
// recompiler inserts the branchtest anyway.
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)func );
}
/**********************************************************
* UNHANDLED YET OPCODES
*
**********************************************************/
////////////////////////////////////////////////////
//REC_SYS(PREF);
////////////////////////////////////////////////////
//REC_SYS(MFSA);
////////////////////////////////////////////////////
//REC_SYS(MTSA);
////////////////////////////////////////////////////
//REC_SYS(TGE);
////////////////////////////////////////////////////
//REC_SYS(TGEU);
////////////////////////////////////////////////////
//REC_SYS(TLT);
////////////////////////////////////////////////////
//REC_SYS(TLTU);
////////////////////////////////////////////////////
//REC_SYS(TEQ);
////////////////////////////////////////////////////
//REC_SYS(TNE);
////////////////////////////////////////////////////
//REC_SYS(TGEI);
////////////////////////////////////////////////////
//REC_SYS(TGEIU);
////////////////////////////////////////////////////
//REC_SYS(TLTI);
////////////////////////////////////////////////////
//REC_SYS(TLTIU);
////////////////////////////////////////////////////
//REC_SYS(TEQI);
////////////////////////////////////////////////////
//REC_SYS(TNEI);
////////////////////////////////////////////////////
//REC_SYS(MTSAB);
////////////////////////////////////////////////////
//REC_SYS(MTSAH);
////////////////////////////////////////////////////
REC_SYS(CACHE);
void recTGE( void )
{
recBranchCall( TGE );
}
void recTGEU( void )
{
recBranchCall( TGEU );
}
void recTLT( void )
{
recBranchCall( TLT );
}
void recTLTU( void )
{
recBranchCall( TLTU );
}
void recTEQ( void )
{
recBranchCall( TEQ );
}
void recTNE( void )
{
recBranchCall( TNE );
}
void recTGEI( void )
{
recBranchCall( TGEI );
}
void recTGEIU( void )
{
recBranchCall( TGEIU );
}
void recTLTI( void )
{
recBranchCall( TLTI );
}
void recTLTIU( void )
{
recBranchCall( TLTIU );
}
void recTEQI( void )
{
recBranchCall( TEQI );
}
void recTNEI( void )
{
recBranchCall( TNEI );
}
/////////////////////////////////
// Foward-Prob Function Tables //
/////////////////////////////////
extern void recCOP2( void );
extern void recSYSCALL( void );
extern void recBREAK( void );
extern void recPREF( void );
extern void recSYNC( void );
extern void recMFSA( void );
extern void recMTSA( void );
extern void recMTSAB( void );
extern void recMTSAH( void );
void (*recBSC[64] )() = {
recSPECIAL, recREGIMM, recJ, recJAL, recBEQ, recBNE, recBLEZ, recBGTZ,
recADDI, recADDIU, recSLTI, recSLTIU, recANDI, recORI, recXORI, recLUI,
recCOP0, recCOP1, recCOP2, recNULL, recBEQL, recBNEL, recBLEZL, recBGTZL,
recDADDI, recDADDIU, recLDL, recLDR, recMMI, recNULL, recLQ, recSQ,
recLB, recLH, recLWL, recLW, recLBU, recLHU, recLWR, recLWU,
recSB, recSH, recSWL, recSW, recSDL, recSDR, recSWR, recCACHE,
recNULL, recLWC1, recNULL, recPREF, recNULL, recNULL, recLQC2, recLD,
recNULL, recSWC1, recNULL, recNULL, recNULL, recNULL, recSQC2, recSD
};
#ifdef PCSX2_VIRTUAL_MEM
// coissued insts
void (*recBSC_co[64] )() = {
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
recNULL, recNULL, recLDL_co, recLDR_co, recNULL, recNULL, recLQ_co, recSQ_co,
recLB_co, recLH_co, recLWL_co, recLW_co, recLBU_co, recLHU_co, recLWR_co, recLWU_co,
recSB_co, recSH_co, recSWL_co, recSW_co, recSDL_co, recSDR_co, recSWR_co, recNULL,
recNULL, recLWC1_co, recNULL, recNULL, recNULL, recNULL, recLQC2_co, recLD_co,
recNULL, recSWC1_co, recNULL, recNULL, recNULL, recNULL, recSQC2_co, recSD_co
};
#endif
void (*recSPC[64] )() = {
recSLL, recNULL, recSRL, recSRA, recSLLV, recNULL, recSRLV, recSRAV,
recJR, recJALR, recMOVZ, recMOVN, recSYSCALL, recBREAK, recNULL, recSYNC,
recMFHI, recMTHI, recMFLO, recMTLO, recDSLLV, recNULL, recDSRLV, recDSRAV,
recMULT, recMULTU, recDIV, recDIVU, recNULL, recNULL, recNULL, recNULL,
recADD, recADDU, recSUB, recSUBU, recAND, recOR, recXOR, recNOR,
recMFSA, recMTSA, recSLT, recSLTU, recDADD, recDADDU, recDSUB, recDSUBU,
recTGE, recTGEU, recTLT, recTLTU, recTEQ, recNULL, recTNE, recNULL,
recDSLL, recNULL, recDSRL, recDSRA, recDSLL32, recNULL, recDSRL32, recDSRA32
};
void (*recREG[32] )() = {
recBLTZ, recBGEZ, recBLTZL, recBGEZL, recNULL, recNULL, recNULL, recNULL,
recTGEI, recTGEIU, recTLTI, recTLTIU, recTEQI, recNULL, recTNEI, recNULL,
recBLTZAL, recBGEZAL, recBLTZALL, recBGEZALL, recNULL, recNULL, recNULL, recNULL,
recMTSAB, recMTSAH, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL,
};
void (*recCP0[32] )() = {
recMFC0, recNULL, recNULL, recNULL, recMTC0, recNULL, recNULL, recNULL,
@ -330,61 +323,6 @@ void (*recCP1W[64] )() = {
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 //
////////////////////////////////////////////////

View File

@ -28,6 +28,7 @@
#include <assert.h>
#include <malloc.h>
#include <sys/stat.h>
#include <string>
#include "Common.h"
#include "Memory.h"
@ -53,6 +54,9 @@
#include "iVUzerorec.h"
#include "vtlb.h"
#include "SamplProf.h"
#ifdef _WIN32
#pragma warning(disable:4244)
#pragma warning(disable:4761)
@ -81,13 +85,11 @@ bool g_EEFreezeRegs = false; // if set, should freeze the regs
static BASEBLOCK* s_pCurBlock = NULL;
static BASEBLOCKEX* s_pCurBlockEx = 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
extern void (*recBSC[64])();
extern void (*recBSC_co[64])();
// save states for branches
static u16 s_savex86FpuState, s_saveiCWstate;
static GPR_reg64 s_ConstGPRreg;
@ -95,13 +97,13 @@ static u32 s_saveConstGPRreg = 0, s_saveHasConstReg = 0, s_saveFlushedConstReg =
static EEINST* s_psaveInstInfo = NULL;
u32 s_nBlockCycles = 0; // cycles of current block recompiling
u32 g_eeCyclePenalty; // cycle penalty of the current recompiled instruction
static u32 s_savenBlockCycles = 0;
void recCOP2RecompileInst();
int recCOP2AnalyzeBlock(u32 startpc, u32 endpc);
void recCOP2EndBlock(void);
u8* dyna_block_discard_recmem=0;
#ifdef _DEBUG
u32 dumplog = 0;
@ -117,10 +119,10 @@ LARGE_INTEGER lbase = {0}, lfinal = {0};
//static u32 s_startcount = 0;
//#endif
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";
const char *txt1 = "REG[%d] = %x_%x\n";
const char *txt2 = "M32 = %x\n";
static const char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
static const char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n";
static const char *txt1 = "REG[%d] = %x_%x\n";
static const char *txt2 = "M32 = %x\n";
void _cop2AnalyzeOp(EEINST* pinst, int dostalls); // reccop2.c
static void iBranchTest(u32 newpc, u32 cpuBranch);
@ -173,10 +175,13 @@ static void iDumpBlock( int startpc, u8 * ptr )
f = fopen( filename, "w" );
std::string output;
if( disR5900GetSym(startpc) != NULL )
fprintf(f, "%s\n", disR5900GetSym(startpc));
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
@ -1482,6 +1487,7 @@ void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR)
}
#define REC_CACHEMEM 0x01000000
void __fastcall dyna_block_discard(u32 start,u32 sz);
int recInit( void )
{
@ -1492,8 +1498,8 @@ int recInit( void )
memset( recLUT, 0, 0x010000 * sizeof(uptr) );
// 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
recRAM = (BASEBLOCK*) _aligned_malloc( sizeof(BASEBLOCK)/4*0x02000000 , 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(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
x86SetPtr(recMem);
SSE3_MOVSLDUP_XMM_to_XMM(XMM0, XMM0);
@ -1611,6 +1623,9 @@ static void recReset( void ) {
memset( recBlocks, 0, sizeof(BASEBLOCKEX)*EE_NUMBLOCKS );
if( s_pInstCache ) memset( s_pInstCache, 0, sizeof(EEINST)*s_nInstCacheSize );
ResetBaseBlockEx(0);
#ifndef PCSX2_VIRTUAL_MEM
mmap_ResetBlockTracking();
#endif
#ifdef _MSC_VER
__asm emms;
@ -1973,24 +1988,6 @@ void StopPerfCounter()
#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 )
{
u32 i;
@ -2268,20 +2265,20 @@ static u32 eeScaleBlockCycles()
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) )
{
// Mid-size blocks should get a mid-sized scale:
// (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) )
{
// larger blocks get a smaller scalar as well, to help keep
// 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;
@ -2321,6 +2318,8 @@ static void iBranchTest(u32 newpc, u32 cpuBranch)
x86SetJ8( j8Ptr[0] );
}
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
////////////////////////////////////////////////////
#ifndef CP2_RECOMPILE
@ -2331,7 +2330,7 @@ REC_SYS(COP2);
void recCOP2( void )
{
CPU_LOG( "Recompiling COP2:%s\n", disR5900Fasm( cpuRegs.code, cpuRegs.pc ) );
CPU_LOG( "Recompiling COP2:%s\n", disR5900Current.getString() );
recCOP22( );
}
@ -2342,7 +2341,7 @@ void recSYSCALL( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_NODESTROY);
CALLFunc( (uptr)SYSCALL );
CALLFunc( (uptr)Interpreter::OpcodeImpl::SYSCALL );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
@ -2357,7 +2356,7 @@ void recBREAK( void ) {
MOV32ItoM( (uptr)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (uptr)&cpuRegs.pc, pc );
iFlushCall(FLUSH_EVERYTHING);
CALLFunc( (uptr)BREAK );
CALLFunc( (uptr)EE::Interpreter::OpcodeImpl::BREAK );
CMP32ItoM((uptr)&cpuRegs.pc, pc);
j8Ptr[0] = JE8(0);
@ -2461,6 +2460,8 @@ void recMTSAH( void )
}
}
}}} // end Namespace EE::Dynarec::OpcodeImpl
static void checkcodefn()
{
int pctemp;
@ -2556,7 +2557,6 @@ void recompileNextInstruction(int delayslot)
#endif
cpuRegs.code = *(int *)s_pCode;
s_nBlockCycles += InstCycles_Default;
pc += 4;
//#ifdef _DEBUG
@ -2608,38 +2608,32 @@ void recompileNextInstruction(int delayslot)
}
}
const EE::OPCODE& opcode = EE::GetCurrentInstruction();
// peephole optimizations
if( g_pCurInstInfo->info & EEINSTINFO_COREC ) {
#ifdef PCSX2_VIRTUAL_MEM
if( g_pCurInstInfo->numpeeps > 1 ) {
g_eeCyclePenalty = InstCycles_Store;
switch(cpuRegs.code>>26) {
case 30: recLQ_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break;
case 31: recSQ_coX(g_pCurInstInfo->numpeeps); break;
case 49: recLWC1_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break;
case 57: recSWC1_coX(g_pCurInstInfo->numpeeps); break;
case 55: recLD_coX(g_pCurInstInfo->numpeeps); g_eeCyclePenalty = InstCycles_Load; break;
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
switch(_Opcode_) {
case 30: EE::Dynarec::OpcodeImpl::recLQ_coX(g_pCurInstInfo->numpeeps); break;
case 31: EE::Dynarec::OpcodeImpl::recSQ_coX(g_pCurInstInfo->numpeeps); break;
case 49: EE::Dynarec::OpcodeImpl::recLWC1_coX(g_pCurInstInfo->numpeeps); break;
case 57: EE::Dynarec::OpcodeImpl::recSWC1_coX(g_pCurInstInfo->numpeeps); break;
case 55: EE::Dynarec::OpcodeImpl::recLD_coX(g_pCurInstInfo->numpeeps); 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
default:
assert(0);
}
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;
}
else {
g_eeCyclePenalty = 0;
recBSC_co[cpuRegs.code>>26]();
EE::Dynarec::recBSC_co[_Opcode_]();
pc += 4;
g_pCurInstInfo++;
// 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;
s_nBlockCycles += opcode.cycles*2;
}
#else
assert(0);
@ -2650,7 +2644,7 @@ void recompileNextInstruction(int delayslot)
// if this instruction is a jump or a branch, exit right away
if( delayslot ) {
switch(cpuRegs.code>>26) {
switch(_Opcode_) {
case 1:
switch(_Rt_) {
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;
}
}
g_eeCyclePenalty = 0;
recBSC[ cpuRegs.code >> 26 ]();
s_nBlockCycles += g_eeCyclePenalty;
opcode.recompile();
s_nBlockCycles += opcode.cycles;
}
if( !delayslot ) {
@ -2735,10 +2728,10 @@ extern int rdram_sdevid;
void iDumpRegisters(u32 startpc, u32 temp)
{
int i;
char* pstr;// = temp ? "t" : "";
const char* pstr;// = temp ? "t" : "";
const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 };
extern const char *disRNameGPR[];
char* psymb;
const char* psymb;
if (temp)
pstr = "t";
@ -2816,6 +2809,12 @@ void badespfn() {
#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 )
{
u32 i = 0;
@ -2950,6 +2949,7 @@ void recRecompile( u32 startpc )
// go until the next branch
i = startpc;
s_nEndBlock = 0xffffffff;
s_nHasDelay = 0;
while(1) {
BASEBLOCK* pblock = PC_GETBLOCK(i);
@ -2962,7 +2962,7 @@ void recRecompile( u32 startpc )
break;
}
}
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
cpuRegs.code = *(int *)PSM(i);
switch(cpuRegs.code >> 26) {
@ -2970,6 +2970,7 @@ void recRecompile( u32 startpc )
if( _Funct_ == 8 || _Funct_ == 9 ) { // JR, JALR
s_nEndBlock = i + 8;
s_nHasDelay = 1;
goto StartRecomp;
}
@ -2978,6 +2979,8 @@ void recRecompile( u32 startpc )
if( _Rt_ < 4 || (_Rt_ >= 16 && _Rt_ < 20) ) {
// branches
if( _Rt_ == 2 || _Rt_ == 3 || _Rt_ == 18 || _Rt_ == 19 ) s_nHasDelay = 1;
else s_nHasDelay = 2;
branchTo = _Imm_ * 4 + i + 4;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
@ -2990,6 +2993,7 @@ void recRecompile( u32 startpc )
case 2: // J
case 3: // JAL
s_nHasDelay = 1;
s_nEndBlock = i + 8;
goto StartRecomp;
@ -2997,6 +3001,9 @@ void recRecompile( u32 startpc )
case 4: case 5: case 6: case 7:
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;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
else s_nEndBlock = i+8;
@ -3017,6 +3024,8 @@ void recRecompile( u32 startpc )
if( _Rs_ == 8 ) {
// BC1F, BC1T, BC1FL, BC1TL
// BC2F, BC2T, BC2FL, BC2TL
if( _Rt_ >= 2 ) s_nHasDelay = 1;
else s_nHasDelay = 2;
branchTo = _Imm_ * 4 + i + 4;
if( branchTo > startpc && branchTo < i ) s_nEndBlock = branchTo;
@ -3092,7 +3101,7 @@ StartRecomp:
if( i < s_nEndBlock-4 && recompileCodeSafe(i) ) {
u32 curcode = cpuRegs.code;
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
if( ((curcode >> 21) & 0x1F) == ((nextcode >> 21) & 0x1F) && !_eeLoadWritesRs(curcode) ) {
@ -3218,6 +3227,60 @@ StartRecomp:
iDumpBlock(startpc, recPtr);
#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 //
g_pCurInstInfo = s_pInstCache;
while (!branch && pc < s_nEndBlock) {

View File

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

View File

@ -33,6 +33,18 @@
#pragma warning(disable:4761)
#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 *
* 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
}
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)
{
if( info & PROCESS_EE_MMX ) {
@ -647,4 +652,6 @@ void recXORI( void )
#endif
} } }
#endif // PCSX2_NORECBUILD

View File

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

View File

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

View File

@ -32,6 +32,14 @@
#pragma warning(disable:4761)
#endif
namespace EE { namespace Dynarec {
// Implemented at the bottom of the module:
void SetFastMemory(int bSetFast);
namespace OpcodeImpl
{
/*********************************************************
* Load and store for GPR *
* Format: OP rt, offset(base) *
@ -64,12 +72,9 @@ REC_FUNC(SWC1);
REC_FUNC(LQC2);
REC_FUNC(SQC2);
void SetFastMemory(int bSetFast) {}
#else
PCSX2_ALIGNED16(u64 retValues[2]);
extern u32 maxrecmem;
static u32 s_bCachingMem = 0;
static u32 s_nAddMemOffset = 0;
static u32 s_tempaddr = 0;
@ -97,19 +102,8 @@ void _eeOnLoadWrite(int reg)
#ifdef PCSX2_VIRTUAL_MEM
extern void iMemRead32Check();
#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_SLOWWRITE
@ -197,22 +191,6 @@ static u16 g_MemMasks16[16] ={0x0000, 0x8001, 0x0002, 0x0003,
0x0005, 0x8005, 0x0005, 0x8005,
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()
{
__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_co( void ) { recLoad32_co(8, 1); g_eeCyclePenalty = InstCycles_Load; }
void recLBU( void ) { recLoad32(8, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLBU_co( void ) { recLoad32_co(8, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLH( void ) { recLoad32(16, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; }
void recLH_co( void ) { recLoad32_co(16, 1); g_eeCyclePenalty = InstCycles_Load; }
void recLHU( void ) { recLoad32(16, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLHU_co( void ) { recLoad32_co(16, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLW( void ) { recLoad32(32, _Imm_, 1); g_eeCyclePenalty = InstCycles_Load; }
void recLW_co( void ) { recLoad32_co(32, 1); g_eeCyclePenalty = InstCycles_Load; }
void recLWU( void ) { recLoad32(32, _Imm_, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLWU_co( void ) { recLoad32_co(32, 0); g_eeCyclePenalty = InstCycles_Load; }
void recLB( void ) { recLoad32(8, _Imm_, 1); }
void recLB_co( void ) { recLoad32_co(8, 1); }
void recLBU( void ) { recLoad32(8, _Imm_, 0); }
void recLBU_co( void ) { recLoad32_co(8, 0); }
void recLH( void ) { recLoad32(16, _Imm_, 1); }
void recLH_co( void ) { recLoad32_co(16, 1); }
void recLHU( void ) { recLoad32(16, _Imm_, 0); }
void recLHU_co( void ) { recLoad32_co(16, 0); }
void recLW( void ) { recLoad32(32, _Imm_, 1); }
void recLW_co( void ) { recLoad32_co(32, 1); }
void recLWU( void ) { recLoad32(32, _Imm_, 0); }
void recLWU_co( void ) { recLoad32_co(32, 0); }
////////////////////////////////////////////////////
// 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 )
{
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD
_flushConstReg(_Rs_);
#else
@ -732,11 +708,10 @@ void recLWL( void )
////////////////////////////////////////////////////
// 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 )
{
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD
_flushConstReg(_Rs_);
#else
@ -934,7 +909,7 @@ void recLoad64(u32 imm, int align)
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 )
{
@ -1196,13 +1171,11 @@ void recLD_coX( int num )
////////////////////////////////////////////////////
void recLDL_co(void)
{
g_eeCyclePenalty = InstCycles_Load;
recLoad64(_Imm_-7, 0);
}
void recLDL( void )
{
g_eeCyclePenalty = InstCycles_Load;
iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) {
@ -1220,15 +1193,14 @@ void recLDL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
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 )
{
g_eeCyclePenalty = InstCycles_Load;
iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) {
@ -1246,14 +1218,12 @@ void recLDR( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
MOV32ItoM( (int)&cpuRegs.pc, pc );
CALLFunc( (int)LDR );
CALLFunc( (int)Interpreter::OpcodeImpl::LDR );
}
////////////////////////////////////////////////////
void recLQ( void )
{
g_eeCyclePenalty = InstCycles_Load;
int mmreg = -1;
#ifdef REC_SLOWREAD
_flushConstReg(_Rs_);
@ -1383,8 +1353,6 @@ void recLQ( void )
void recLQ_co( void )
{
g_eeCyclePenalty = InstCycles_Load;
#ifdef REC_SLOWREAD
_flushConstReg(_Rs_);
#else
@ -1597,8 +1565,23 @@ void recLQ_coX(int num)
}
////////////////////////////////////////////////////
extern void recClear64(BASEBLOCK* p);
extern void recClear128(BASEBLOCK* p);
static void recClear64(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
void recMemConstClear(u32 mem, u32 size)
@ -2424,20 +2407,18 @@ void recStore_co(int bit, int align)
_clearNeededXMMregs(); // needed since allocing
}
void recSB( void ) { recStore(8, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSB_co( void ) { recStore_co(8, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSH( void ) { recStore(16, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSH_co( void ) { recStore_co(16, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSW( void ) { recStore(32, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSW_co( void ) { recStore_co(32, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSB( void ) { recStore(8, _Imm_, 1); }
void recSB_co( void ) { recStore_co(8, 1); }
void recSH( void ) { recStore(16, _Imm_, 1); }
void recSH_co( void ) { recStore_co(16, 1); }
void recSW( void ) { recStore(32, _Imm_, 1); }
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 )
{
g_eeCyclePenalty = InstCycles_Store;
#ifdef REC_SLOWWRITE
_flushConstReg(_Rs_);
#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 )
{
g_eeCyclePenalty = InstCycles_Store;
#ifdef REC_SLOWWRITE
_flushConstReg(_Rs_);
#else
@ -2618,8 +2597,8 @@ void recSWR( void )
}
}
void recSD( void ) { recStore(64, _Imm_, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSD_co( void ) { recStore_co(64, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSD( void ) { recStore(64, _Imm_, 1); }
void recSD_co( void ) { recStore_co(64, 1); }
// coissues more than 2 SDs
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 )
{
g_eeCyclePenalty = InstCycles_Store;
iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) {
@ -2758,16 +2735,14 @@ void recSDL( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
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 )
{
g_eeCyclePenalty = InstCycles_Store;
iFlushCall(FLUSH_NOCONST);
if( GPR_IS_CONST1( _Rs_ ) ) {
@ -2784,12 +2759,12 @@ void recSDR( void )
MOV32ItoM( (int)&cpuRegs.code, cpuRegs.code );
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_co( void ) { recStore_co(128, 1); g_eeCyclePenalty = InstCycles_Store; }
void recSQ( void ) { recStore(128, _Imm_, 1); }
void recSQ_co( void ) { recStore_co(128, 1); }
// coissues more than 2 SQs
void recSQ_coX(int num)
@ -3814,6 +3789,8 @@ void recSQC2_co( void )
#else
using namespace Interpreter::OpcodeImpl;
PCSX2_ALIGNED16(u32 dummyValue[4]);
void SetFastMemory(int bSetFast)
@ -3821,9 +3798,112 @@ void SetFastMemory(int bSetFast)
// 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 )
{
recLoad(8,true);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0);
@ -3850,11 +3930,14 @@ void recLB( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
x86SetJ8( linkEnd );
}
*/
}
////////////////////////////////////////////////////
void recLBU( void )
{
recLoad(8,false);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0);
@ -3880,11 +3963,14 @@ void recLBU( void )
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd );
}
*/
}
////////////////////////////////////////////////////
void recLH( void )
{
recLoad(16,true);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0);
@ -3911,11 +3997,14 @@ void recLH( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX );
x86SetJ8( linkEnd );
}
*/
}
////////////////////////////////////////////////////
void recLHU( void )
{
recLoad(16,false);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0);
@ -3939,12 +4028,14 @@ void recLHU( void )
MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ], EAX );
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd );
}
}*/
}
////////////////////////////////////////////////////
void recLW( void )
{
recLoad(32,true);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_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[ 1 ], EDX );
x86SetJ8( linkEnd );
}
}*/
}
////////////////////////////////////////////////////
void recLWU( void )
{
recLoad(32,false);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
_deleteEEreg(_Rt_, 0);
@ -4001,6 +4094,7 @@ void recLWU( void )
MOV32ItoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], 0 );
x86SetJ8( linkEnd );
}
*/
}
////////////////////////////////////////////////////
@ -4028,6 +4122,8 @@ extern void MOV64RmtoR( x86IntRegType to, x86IntRegType from );
void recLD( void )
{
recLoad(64,false);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
@ -4050,6 +4146,7 @@ void recLD( void )
PUSH32R( EAX );
CALLFunc( (int)memRead64 );
ADD32ItoR( ESP, 8 );
*/
}
////////////////////////////////////////////////////
@ -4079,6 +4176,8 @@ void recLDR( void )
////////////////////////////////////////////////////
void recLQ( void )
{
recLoad(128,false);
/*
_deleteEEreg(_Rs_, 1);
_eeOnLoadWrite(_Rt_);
EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension
@ -4102,12 +4201,59 @@ void recLQ( void )
PUSH32R( EAX );
CALLFunc( (int)memRead128 );
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 )
{
recStore(8);
/*
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4118,12 +4264,15 @@ void recSB( void )
PUSH32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
PUSH32R( EAX );
CALLFunc( (int)memWrite8 );
ADD32ItoR( ESP, 8 );
ADD32ItoR( ESP, 8 );
*/
}
////////////////////////////////////////////////////
void recSH( void )
{
recStore(16);
/*
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
@ -4136,11 +4285,14 @@ void recSH( void )
PUSH32R( EAX );
CALLFunc( (int)memWrite16 );
ADD32ItoR( ESP, 8 );
*/
}
////////////////////////////////////////////////////
void recSW( void )
{
recStore(32);
/*
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
@ -4154,6 +4306,7 @@ void recSW( void )
PUSH32R( EAX );
CALLFunc( (int)memWrite32 );
ADD32ItoR( ESP, 8 );
*/
}
////////////////////////////////////////////////////
@ -4179,6 +4332,8 @@ void recSWR( void )
////////////////////////////////////////////////////
void recSD( void )
{
recStore(64);
/*
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4192,6 +4347,7 @@ void recSD( void )
PUSH32R( EAX );
CALLFunc( (int)memWrite64 );
ADD32ItoR( ESP, 12 );
*/
}
////////////////////////////////////////////////////
@ -4217,6 +4373,8 @@ void recSDR( void )
////////////////////////////////////////////////////
void recSQ( void )
{
recStore(128);
/*
_deleteEEreg(_Rs_, 1);
_deleteEEreg(_Rt_, 1);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
@ -4229,7 +4387,7 @@ void recSQ( void )
PUSH32I( (int)&cpuRegs.GPR.r[ _Rt_ ].UD[ 0 ] );
PUSH32R( EAX );
CALLFunc( (int)memWrite128 );
ADD32ItoR( ESP, 8 );
ADD32ItoR( ESP, 8 );*/
}
/*********************************************************
@ -4243,16 +4401,15 @@ void recLWC1( void )
_deleteEEreg(_Rs_, 1);
_deleteFPtoXMMreg(_Rt_, 2);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 )
{
ADD32ItoR( EAX, _Imm_ );
ADD32ItoR( ECX, _Imm_ );
}
PUSH32I( (int)&fpuRegs.fpr[ _Rt_ ].UL );
PUSH32R( EAX );
CALLFunc( (int)memRead32 );
ADD32ItoR( ESP, 8 );
MOV32ItoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); //no 0 for fpu ?
//CALLFunc( (int)memRead32 );
vtlb_DynGenOp(true,32);
}
////////////////////////////////////////////////////
@ -4261,16 +4418,15 @@ void recSWC1( void )
_deleteEEreg(_Rs_, 1);
_deleteFPtoXMMreg(_Rt_, 0);
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
if ( _Imm_ != 0 )
{
ADD32ItoR( EAX, _Imm_ );
ADD32ItoR( ECX, _Imm_ );
}
PUSH32M( (int)&fpuRegs.fpr[ _Rt_ ].UL );
PUSH32R( EAX );
CALLFunc( (int)memWrite32 );
ADD32ItoR( ESP, 8 );
MOV32MtoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL );
//CALLFunc( (int)memWrite32 );
vtlb_DynGenOp(false,32);
}
////////////////////////////////////////////////////
@ -4284,23 +4440,22 @@ void recLQC2( void )
_deleteEEreg(_Rs_, 1);
_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 )
{
ADD32ItoR( EAX, _Imm_);
ADD32ItoR( ECX, _Imm_);
}
if ( _Rt_ )
{
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] );
MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
}
else
{
PUSH32I( (int)&dummyValue[0] );
MOV32ItoR(EDX, (int)&dummyValue[0] );
}
PUSH32R( EAX );
CALLFunc( (int)memRead128 );
ADD32ItoR( ESP, 8 );
//CALLFunc( (int)memRead128 );
vtlb_DynGenOp(true,128);
}
////////////////////////////////////////////////////
@ -4309,20 +4464,51 @@ void recSQC2( void )
_deleteEEreg(_Rs_, 1);
_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 )
{
ADD32ItoR( EAX, _Imm_ );
ADD32ItoR( ECX, _Imm_ );
}
PUSH32I( (int)&VU0.VF[_Ft_].UD[0] );
PUSH32R( EAX );
CALLFunc( (int)memWrite128 );
ADD32ItoR( ESP, 8 );
MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] );
//CALLFunc( (int)memWrite128 );
vtlb_DynGenOp(false,128);
}
#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

View File

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

View File

@ -33,6 +33,9 @@
#pragma warning(disable:4761)
#endif
namespace EE { namespace Dynarec { namespace OpcodeImpl
{
/*********************************************************
* Register mult/div & Register trap logic *
* Format: OP rs, rt *
@ -424,7 +427,7 @@ void recMULT_constt(int info)
}
// 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
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
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()
@ -571,7 +574,7 @@ void recMULT1_constt(int info)
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()
@ -596,7 +599,7 @@ void recMULTU1_constt(int info)
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
void recDIV_const()
@ -661,7 +664,7 @@ void recDIV_constt(int info)
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
void recDIVU_const()
@ -689,7 +692,7 @@ void recDIVU_constt(int info)
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()
{
@ -716,7 +719,7 @@ void recDIV1_constt(int info)
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()
{
@ -743,7 +746,7 @@ void recDIVU1_constt(int info)
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
REC_FUNC( MADD, _Rd_ );
@ -955,4 +958,6 @@ REC_FUNC( MADDU1, _Rd_ );
#endif
} } }
#endif // PCSX2_NORECBUILD

View File

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

View File

@ -31,8 +31,6 @@
#include <assert.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; }
#ifdef __x86_64__

View File

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

View File

@ -174,7 +174,7 @@ int LoadGroup(TiXmlNode *group,int gParent)
// only valid for recompilers
TiXmlNode *fastmemory=group->FirstChild("FASTMEMORY");
if(fastmemory!=NULL)
SetFastMemory(1);
EE::Dynarec::SetFastMemory(1);
#endif
TiXmlNode *zerogs=group->FirstChild("ZEROGS");
@ -324,11 +324,11 @@ int LoadGroup(TiXmlNode *group,int gParent)
if(strcmp(place,"EE")==0)
{
patch[patchnumber].cpu= EE;
patch[patchnumber].cpu= CPU_EE;
} else
if(strcmp(place,"IOP")==0)
{
patch[patchnumber].cpu= IOP;
patch[patchnumber].cpu= CPU_IOP;
} else
{
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug TLB|Win32 = Debug TLB|Win32
Debug|Win32 = Debug|Win32
Release (to Public)|Win32 = Release (to Public)|Win32
Release TLB|Win32 = Release TLB|Win32
Release|Win32 = Release|Win32
Debug vm|Win32 = Debug vm|Win32
Debug vtlb|Win32 = Debug vtlb|Win32
Release vm (to Public)|Win32 = Release vm (to Public)|Win32
Release vm|Win32 = Release vm|Win32
Release vtlb (to Public)|Win32 = Release vtlb (to Public)|Win32
Release vtlb|Win32 = Release vtlb|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug TLB|Win32.ActiveCfg = Debug TLB|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug TLB|Win32.Build.0 = Debug TLB|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.ActiveCfg = Debug|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug|Win32.Build.0 = Debug|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release (to Public)|Win32.ActiveCfg = Release (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release (to Public)|Win32.Build.0 = Release (to Public)|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release TLB|Win32.ActiveCfg = Release TLB|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release TLB|Win32.Build.0 = Release TLB|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.ActiveCfg = Release|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release|Win32.Build.0 = Release|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.ActiveCfg = Debug vm|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.Build.0 = Debug vm|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.ActiveCfg = Debug vtlb|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.Build.0 = Debug vtlb|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm (to Public)|Win32.ActiveCfg = Release VM (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 vm|Win32.ActiveCfg = Release VM|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.Build.0 = Release VM|Win32
{1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb (to Public)|Win32.ActiveCfg = Release vtlb (to Public)|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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE