mirror of https://github.com/PCSX2/pcsx2.git
newVif: created a custom memcmp for the vif dynarec block finder... its faster than memcmp, but not sure if it will be a noticeable speedup.
Should work in gcc Linux builds, but if not uncomment the memcmp() part in newVif_HashBucket.h's "find()"... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2367 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
c86fc2c9b9
commit
7b2c66e549
|
@ -48,19 +48,30 @@ static __aligned16 u32 nVifMask[3][4][4] = {0}; // [MaskNumber][CycleNumber][
|
|||
#define xmmRow xmm6
|
||||
#define xmmTemp xmm7
|
||||
|
||||
struct nVifBlock { // Ordered for Hashing
|
||||
u8 num; // Num Field
|
||||
u8 upkType; // Unpack Type [usn*1:mask*1:upk*4]
|
||||
u8 mode; // Mode Field
|
||||
u8 scl; // Start Cycle
|
||||
u8 cl; // CL Field
|
||||
u8 wl; // WL Field
|
||||
u32 mask; // Mask Field
|
||||
u8* startPtr; // Start Ptr of RecGen Code
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
# pragma pack(1)
|
||||
# pragma warning(disable:4996) // 'function': was declared deprecated
|
||||
#endif
|
||||
|
||||
struct __aligned16 nVifBlock { // Ordered for Hashing
|
||||
u8 num; // [00] Num Field
|
||||
u8 upkType; // [01] Unpack Type [usn*1:mask*1:upk*4]
|
||||
u8 mode; // [02] Mode Field
|
||||
u8 scl; // [03] Start Cycle
|
||||
u8 cl; // [04] CL Field
|
||||
u8 wl; // [05] WL Field
|
||||
u32 mask; // [06] Mask Field
|
||||
u8 padding[6];// [10] through [15]
|
||||
uptr startPtr; // [16] Start Ptr of RecGen Code
|
||||
u8 end[12]; // [20] through [31]
|
||||
} __packed; // 32 bytes
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma pack()
|
||||
#endif
|
||||
|
||||
#define _hSize 0x4000 // [usn*1:mask*1:upk*4:num*8] hash...
|
||||
#define _cmpS (sizeof(nVifBlock) - sizeof(uptr))
|
||||
#define _cmpS (sizeof(nVifBlock) - (16+6))
|
||||
#define _tParams nVifBlock, _hSize, _cmpS
|
||||
struct nVifStruct {
|
||||
u32 idx; // VIF0 or VIF1
|
||||
|
|
|
@ -30,6 +30,7 @@ void dVifInit(int idx) {
|
|||
nVif[idx].vifBlocks = new HashBucket<_tParams>();
|
||||
nVif[idx].recPtr = nVif[idx].vifCache->getBlock();
|
||||
nVif[idx].recEnd = &nVif[idx].recPtr[nVif[idx].vifCache->getSize()-(_1mb/4)]; // .25mb Safe Zone
|
||||
emitCustomCompare();
|
||||
}
|
||||
|
||||
_f void dVifRecLimit(int idx) {
|
||||
|
@ -75,7 +76,7 @@ void dVifRecompile(nVifStruct& v, nVifBlock* vB) {
|
|||
v.vifBlock = vB;
|
||||
xSetPtr(v.recPtr);
|
||||
xAlignPtr(16);
|
||||
vB->startPtr = xGetPtr();
|
||||
vB->startPtr = (uptr)xGetPtr();
|
||||
dVifSetMasks(v, doMask, doMode, cycleSize);
|
||||
|
||||
while (vifRegs->num) {
|
||||
|
@ -107,7 +108,7 @@ void dVifRecompile(nVifStruct& v, nVifBlock* vB) {
|
|||
vifRegs->num = backupNum;
|
||||
}
|
||||
|
||||
static nVifBlock _vBlock = {0};
|
||||
static __aligned16 nVifBlock _vBlock = {0};
|
||||
|
||||
_f u8* dVifsetVUptr(nVifStruct& v, int offset) {
|
||||
u8* ptr = (u8*)(v.VU->Mem + (offset & v.vuMemLimit));
|
||||
|
@ -148,10 +149,8 @@ void dVifUnpack(int idx, u8 *data, u32 size) {
|
|||
}
|
||||
static int recBlockNum = 0;
|
||||
DevCon.WriteLn("nVif: Recompiled Block! [%d]", recBlockNum++);
|
||||
nVifBlock* vB = new nVifBlock();
|
||||
memcpy(vB, &_vBlock, sizeof(nVifBlock));
|
||||
dVifRecompile(v, vB);
|
||||
v.vifBlocks->add(vB);
|
||||
dVifRecompile(v, &_vBlock);
|
||||
v.vifBlocks->add(&_vBlock);
|
||||
dVifRecLimit(idx);
|
||||
dVifUnpack(idx, data, size);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
extern __pagealigned u8 nVifMemCmp[__pagesize];
|
||||
|
||||
// HashBucket is a container which uses a built-in hash function
|
||||
// to perform quick searches.
|
||||
// T is a struct data type.
|
||||
// T is a struct data type (note: size must be in multiples of 16 bytes!)
|
||||
// hSize determines the number of buckets HashBucket will use for sorting.
|
||||
// cmpSize is the size of data to consider 2 structs equal (see find())
|
||||
// The hash function is determined by taking the first bytes of data and
|
||||
|
@ -46,7 +48,8 @@ public:
|
|||
int s = mSize[o];
|
||||
T* c = mChain[o];
|
||||
for (int i = 0; i < s; i++) {
|
||||
if (!memcmp(&c[i], dataPtr, cmpSize)) return &c[i];
|
||||
//if (!memcmp(&c[i], dataPtr, cmpSize)) return &c[i];
|
||||
if ((((nVifCall)((void*)nVifMemCmp))(&c[i], dataPtr))==0xf) return &c[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -55,17 +58,17 @@ public:
|
|||
int o = d % hSize;
|
||||
int s = mSize[o]++;
|
||||
T* c = mChain[o];
|
||||
T* n = new T[s+1];
|
||||
T* n = (T*)_aligned_malloc(sizeof(T)*(s+1), 16);
|
||||
if (s) {
|
||||
memcpy(n, c, sizeof(T) * s);
|
||||
delete[] c;
|
||||
safe_aligned_free(c);
|
||||
}
|
||||
memcpy(&n[s], dataPtr, sizeof(T));
|
||||
mChain[o] = n;
|
||||
}
|
||||
void clear() {
|
||||
for (int i = 0; i < hSize; i++) {
|
||||
safe_delete_array(mChain[i]);
|
||||
safe_aligned_free(mChain[i]);
|
||||
mSize[i] = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,3 +271,18 @@ void writeBackRow(nVifStruct& v) {
|
|||
DevCon.WriteLn("nVif: writing back row reg! [doMode = 2]");
|
||||
// ToDo: Do we need to write back to vifregs.rX too!? :/
|
||||
}
|
||||
|
||||
static __pagealigned u8 nVifMemCmp[__pagesize];
|
||||
|
||||
void emitCustomCompare() {
|
||||
HostSys::MemProtectStatic(nVifMemCmp, Protect_ReadWrite, false);
|
||||
memset_8<0xcc,__pagesize>(nVifMemCmp);
|
||||
xSetPtr(nVifMemCmp);
|
||||
|
||||
xMOVAPS (xmm0, ptr32[ecx]);
|
||||
xPCMP.EQD(xmm0, ptr32[edx]);
|
||||
xMOVMSKPS(eax, xmm0);
|
||||
|
||||
xRET();
|
||||
HostSys::MemProtectStatic(nVifMemCmp, Protect_ReadOnly, true);
|
||||
}
|
Loading…
Reference in New Issue