mirror of https://github.com/PCSX2/pcsx2.git
--No longer uses 2 hacks/buffers, it just stores the info needed to generate the memops directly on the code
git-svn-id: http://pcsx2.googlecode.com/svn/branches/vtlb-exp@936 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6c88e99cf2
commit
f5e99af1ab
|
@ -62,7 +62,7 @@ int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
|
|||
|
||||
if (addr&0x80000000)
|
||||
{
|
||||
uptr _vtlb_HandleRewrite(uptr code);
|
||||
uptr _vtlb_HandleRewrite(u32 info,u8* ra);
|
||||
u8* pcode=(u8*)ExceptionRecord.ExceptionAddress;
|
||||
|
||||
u32 patch_point=1;
|
||||
|
@ -79,7 +79,7 @@ int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
|
|||
|
||||
eps->ContextRecord->Eax-=*(u32*)&pcode[-patch_point+2];
|
||||
|
||||
uptr codeloc=_vtlb_HandleRewrite(*(u32*)&pcode[-patch_point+2]);
|
||||
uptr codeloc=_vtlb_HandleRewrite(*(u32*)&pcode[-patch_point+2],&pcode[-patch_point+2+4]);
|
||||
|
||||
eps->ContextRecord->Eip=codeloc;
|
||||
*(u32*)&pcode[-patch_point+2]=codeloc-(u32)&pcode[-patch_point+6];
|
||||
|
|
|
@ -24,14 +24,28 @@
|
|||
#include "iCore.h"
|
||||
#include "iR5900.h"
|
||||
|
||||
u8* execohax_pos=0;
|
||||
u8* execohax_start=0;
|
||||
u32 execohx_sz;
|
||||
|
||||
u8* code_pos=0;
|
||||
u8* code_start=0;
|
||||
u32 code_sz;
|
||||
|
||||
union _vtlb_MemOpInfo
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 sz:8;//0 -> 8, 1 -> 16, 2 -> 32, 3 -> 64, 4 -> 128
|
||||
u32 skip:8;//bytes to skip
|
||||
u32 sx:1;
|
||||
u32 read:1;
|
||||
};
|
||||
u32 full;
|
||||
bool isRead() { return read; }
|
||||
bool isWrite(){ return !isRead(); }
|
||||
bool isSX() { return sx; }
|
||||
u32 getSize() { return sz; }
|
||||
u32 getSkip() { return skip; }
|
||||
};
|
||||
|
||||
|
||||
using namespace vtlb_private;
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -49,8 +63,8 @@ void execuCode(bool set)
|
|||
while(i<code_sz)
|
||||
{
|
||||
//UD2 is 0xF 0xB.Fill the stream with it so that the cpu don't try to execute past branches ..
|
||||
code_start[i]=0xF;i++;
|
||||
code_start[i]=0xB;i++;
|
||||
code_start[i]=0xF;i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,67 +77,33 @@ void execuCode(bool set)
|
|||
else
|
||||
{
|
||||
code_pos=x86SetPtr(old);
|
||||
u32 tt=execohx_sz-2*1024*1024+(execohax_pos-execohax_start);
|
||||
u32 tc=code_sz-free;
|
||||
SysPrintf("%d code, %d pot, %.2f%%\n",tc,tt,tc/(float)tt*100);
|
||||
}
|
||||
}
|
||||
|
||||
u32* execohaxme(bool set)
|
||||
u8* IndirectPlaceholderA()
|
||||
{
|
||||
u32 used=execohax_pos-execohax_start;
|
||||
u32 free=2*1024*1024-used;
|
||||
write8<_EmitterId_>( 0x81 );
|
||||
ModRM<_EmitterId_>( 3, 0, EAX );
|
||||
|
||||
if (execohax_pos == 0 || free<128)
|
||||
{
|
||||
SysPrintf("Leaking 2 megabytes of ram\n");
|
||||
execohax_start=execohax_pos=(u8*)VirtualAlloc(0,2*1024*1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
|
||||
execohx_sz+=2*1024*1024;
|
||||
}
|
||||
static u8* saved;
|
||||
static u8* mod;
|
||||
if (set)
|
||||
{
|
||||
write8<_EmitterId_>( 0x81 );
|
||||
ModRM<_EmitterId_>( 3, 0, EAX );
|
||||
write32<_EmitterId_>( (uptr)execohax_pos );
|
||||
u8* rv=x86SetPtr(0);
|
||||
write32<_EmitterId_>(0);
|
||||
|
||||
saved=x86SetPtr(execohax_pos);
|
||||
mod=execohax_pos;
|
||||
write8<_EmitterId_>(0); //size, in bytes
|
||||
write32<_EmitterId_>(0); //return address
|
||||
}
|
||||
else
|
||||
{
|
||||
//x86AlignExecutable(4);
|
||||
//x86Align(64);
|
||||
execohax_pos=x86SetPtr(mod);
|
||||
write8<_EmitterId_>(execohax_pos-mod-5);
|
||||
return (u32*)x86SetPtr(saved);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr _vtlb_HandleRewrite(uptr block)
|
||||
{
|
||||
u8 size=*(u8*)block;
|
||||
u32 ra=*(u32*)(block+1);
|
||||
u8* pcode=(u8*)(block+5);
|
||||
execuCode(true);
|
||||
uptr rv=(uptr)code_pos;
|
||||
|
||||
while(size--)
|
||||
{
|
||||
write8<_EmitterId_>(*pcode++);
|
||||
}
|
||||
JMP32(ra-(uptr)x86Ptr[_EmitterId_]-5);
|
||||
|
||||
execuCode(false);
|
||||
//do magic
|
||||
return rv;
|
||||
}
|
||||
|
||||
void IndirectPlaceholderB(u8* pl,bool read,u32 sz,bool sx)
|
||||
{
|
||||
_vtlb_MemOpInfo inf;
|
||||
inf.full=0;
|
||||
inf.read=read;
|
||||
inf.sz=sz;
|
||||
inf.sx=sx;
|
||||
|
||||
u8* old=x86SetPtr(pl);
|
||||
inf.skip=old-pl-4;
|
||||
//Add32 <eax>,imm, 6 bytes form.
|
||||
write32<_EmitterId_>( inf.full );
|
||||
x86SetPtr(old);
|
||||
}
|
||||
PCSX2_ALIGNED16( static u64 g_globalXMMData[2*XMMREGS] );
|
||||
void MOVx_SSE( x86IntRegType destRm, x86IntRegType srcRm,u32 srcAddr=0,u32 dstAddr=0,bool half=false )
|
||||
{
|
||||
|
@ -196,6 +176,8 @@ void MOV64_MMX( x86IntRegType destRm, x86IntRegType srcRm,u32 srcAddr=0,u32 dstA
|
|||
MOVx_SSE(destRm,srcRm,srcAddr,dstAddr,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Pseudo-Code For the following Dynarec Implementations -->
|
||||
|
||||
|
@ -317,16 +299,12 @@ void vtlb_DynGenRead64(u32 bits)
|
|||
SHR32ItoR(EAX,VTLB_PAGE_BITS);
|
||||
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
|
||||
ADD32RtoR(ECX,EAX);
|
||||
//u8* _direct = JMP8(0);
|
||||
execohaxme(true);
|
||||
|
||||
_vtlb_DynGen_IndirectRead( bits );
|
||||
|
||||
u32* patch=execohaxme(false);
|
||||
u8* patch=IndirectPlaceholderA();
|
||||
|
||||
_vtlb_DynGen_DirectRead( bits, false );
|
||||
|
||||
*patch=(uptr)x86Ptr[_EmitterId_];
|
||||
|
||||
IndirectPlaceholderB(patch,true,bits,false);
|
||||
}
|
||||
|
||||
// Recompiled input registers:
|
||||
|
@ -340,33 +318,12 @@ void vtlb_DynGenRead32(u32 bits, bool sign)
|
|||
SHR32ItoR(EAX,VTLB_PAGE_BITS);
|
||||
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
|
||||
ADD32RtoR(ECX,EAX);
|
||||
//u8* _direct = JMP8(0);
|
||||
execohaxme(true);
|
||||
|
||||
_vtlb_DynGen_IndirectRead( bits );
|
||||
|
||||
// perform sign extension on the result:
|
||||
|
||||
if( bits==8 )
|
||||
{
|
||||
if( sign )
|
||||
MOVSX32R8toR(EAX,EAX);
|
||||
else
|
||||
MOVZX32R8toR(EAX,EAX);
|
||||
}
|
||||
else if( bits==16 )
|
||||
{
|
||||
if( sign )
|
||||
MOVSX32R16toR(EAX,EAX);
|
||||
else
|
||||
MOVZX32R16toR(EAX,EAX);
|
||||
}
|
||||
|
||||
u32* patch=execohaxme(false);
|
||||
|
||||
u8* patch=IndirectPlaceholderA();
|
||||
|
||||
_vtlb_DynGen_DirectRead( bits, sign );
|
||||
|
||||
*patch=(uptr)x86Ptr[_EmitterId_];
|
||||
|
||||
IndirectPlaceholderB(patch,true,bits,sign);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -543,16 +500,11 @@ void vtlb_DynGenWrite(u32 sz)
|
|||
MOV32RmSOffsettoR(EAX,EAX,(int)vtlbdata.vmap,2);
|
||||
ADD32RtoR(ECX,EAX);
|
||||
|
||||
//u8* _direct=JMP8(0);
|
||||
u8* patch=IndirectPlaceholderA();
|
||||
|
||||
execohaxme(true);
|
||||
|
||||
_vtlb_DynGen_IndirectWrite( sz );
|
||||
|
||||
u32* patch=execohaxme(false);
|
||||
_vtlb_DynGen_DirectWrite( sz );
|
||||
|
||||
*patch=(uptr)x86Ptr[_EmitterId_];
|
||||
|
||||
IndirectPlaceholderB(patch,false,sz,false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,3 +560,52 @@ void vtlb_DynGenWrite_Const( u32 bits, u32 addr_const )
|
|||
CALLFunc( (int)vtlbdata.RWFT[szidx][1][handler] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u32 GenIndirectMemOp(u32 info)
|
||||
{
|
||||
_vtlb_MemOpInfo inf;
|
||||
inf.full=info;
|
||||
|
||||
u32 bits=inf.getSize();
|
||||
bool sign=inf.isSX();
|
||||
|
||||
if (inf.isWrite())
|
||||
{
|
||||
_vtlb_DynGen_IndirectWrite(bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vtlb_DynGen_IndirectRead(bits);
|
||||
|
||||
if( bits==8 )
|
||||
{
|
||||
if( sign )
|
||||
MOVSX32R8toR(EAX,EAX);
|
||||
else
|
||||
MOVZX32R8toR(EAX,EAX);
|
||||
}
|
||||
else if( bits==16 )
|
||||
{
|
||||
if( sign )
|
||||
MOVSX32R16toR(EAX,EAX);
|
||||
else
|
||||
MOVZX32R16toR(EAX,EAX);
|
||||
}
|
||||
}
|
||||
|
||||
return inf.getSkip();
|
||||
}
|
||||
uptr _vtlb_HandleRewrite(u32 info,u8* ra)
|
||||
{
|
||||
execuCode(true);
|
||||
uptr rv=(uptr)x86SetPtr(0);
|
||||
|
||||
u32 skip=GenIndirectMemOp(info);
|
||||
|
||||
JMP32(ra-x86Ptr[_EmitterId_]-5+skip);
|
||||
|
||||
execuCode(false);
|
||||
|
||||
return rv;
|
||||
}
|
Loading…
Reference in New Issue