linux: Sh4 dynarec works
This commit is contained in:
parent
d33ad6edfb
commit
5b609a6be4
|
@ -20,7 +20,7 @@ enum x86_op_params
|
|||
|
||||
encoded_type pg_none = {pg_NONE};
|
||||
|
||||
encoded_type __fastcall param_type(x86_Label* lbl)
|
||||
encoded_type param_type(x86_Label* lbl)
|
||||
{
|
||||
encoded_type rv;
|
||||
//Return pg_MEM_Rel32/pg_MEM_Rel16/pg_MEM_Rel8
|
||||
|
@ -33,7 +33,7 @@ encoded_type __fastcall param_type(x86_Label* lbl)
|
|||
rv.ptr_type=1;
|
||||
return rv;
|
||||
}
|
||||
encoded_type __fastcall param_type(x86_ptr_imm ptr)
|
||||
encoded_type param_type(x86_ptr_imm ptr)
|
||||
{
|
||||
encoded_type rv;
|
||||
//Return pg_MEM_Rel32.Due to relocation we cant optimise to 16/8 in one pass ...
|
||||
|
@ -43,7 +43,7 @@ encoded_type __fastcall param_type(x86_ptr_imm ptr)
|
|||
rv.ptr_type=0;
|
||||
return rv;
|
||||
}
|
||||
encoded_type __fastcall param_type(x86_mrm_t& modrm)
|
||||
encoded_type param_type(x86_mrm_t& modrm)
|
||||
{
|
||||
encoded_type rv;
|
||||
rv.modrm=modrm;
|
||||
|
@ -51,7 +51,7 @@ encoded_type __fastcall param_type(x86_mrm_t& modrm)
|
|||
rv.type=pg_ModRM;
|
||||
return rv;
|
||||
}
|
||||
encoded_type __fastcall param_type(x86_reg reg)
|
||||
encoded_type param_type(x86_reg reg)
|
||||
{
|
||||
encoded_type rv;
|
||||
rv.reg=REG_ID(reg);
|
||||
|
@ -65,7 +65,7 @@ encoded_type __fastcall param_type(x86_reg reg)
|
|||
return rv;
|
||||
}
|
||||
|
||||
encoded_type __fastcall param_type(u32 imm)
|
||||
encoded_type param_type(u32 imm)
|
||||
{
|
||||
encoded_type rv;
|
||||
rv.imm=imm;
|
||||
|
@ -82,7 +82,7 @@ encoded_type __fastcall param_type(u32 imm)
|
|||
|
||||
return rv;
|
||||
}
|
||||
void __fastcall Match_opcode(x86_block* block,const x86_opcode* ops,encoded_type pg1,encoded_type pg2,encoded_type pg3)
|
||||
void Match_opcode(x86_block* block,const x86_opcode* ops,encoded_type pg1,encoded_type pg2,encoded_type pg3)
|
||||
{
|
||||
block->opcode_count++;
|
||||
const x86_opcode* match=0;
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
#include "build.h"
|
||||
|
||||
#if BUILD_COMPILER == COMPILER_GCC
|
||||
#define __fastcall
|
||||
#define __fastcall BALLZZ!!
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -173,7 +173,7 @@ struct encoded_type
|
|||
|
||||
struct x86_opcode;
|
||||
|
||||
typedef void __fastcall x86_opcode_encoderFP(x86_block* block,const x86_opcode* op,encoded_type* p1,encoded_type* p2,u32 p3);
|
||||
typedef void x86_opcode_encoderFP(x86_block* block,const x86_opcode* op,encoded_type* p1,encoded_type* p2,u32 p3);
|
||||
|
||||
//enc_param_none is alower w/ params set to implicit registers (ie , mov eax,xxxx is enc_imm , pg1:pg_EAX , pg2:pg_imm
|
||||
|
||||
|
@ -190,7 +190,7 @@ struct x86_opcode
|
|||
};
|
||||
|
||||
//mod|reg|rm
|
||||
void __fastcall encode_modrm(x86_block* block,encoded_type* mrm, u32 extra)
|
||||
void encode_modrm(x86_block* block,encoded_type* mrm, u32 extra)
|
||||
{
|
||||
if (mrm->type != pg_ModRM)
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ void __fastcall encode_modrm(x86_block* block,encoded_type* mrm, u32 extra)
|
|||
}
|
||||
#ifdef X64
|
||||
//x64 stuff
|
||||
void __fastcall encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 ofe=0)
|
||||
void encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 ofe=0)
|
||||
{
|
||||
u32 flags = (ofe>>3) & 1; //opcode field extension
|
||||
|
||||
|
@ -237,7 +237,7 @@ void __fastcall encode_rex(x86_block* block,encoded_type* mrm,u32 mrm_reg,u32 of
|
|||
|
||||
//Encoding function (partially) specialised by templates to gain speed :)
|
||||
template < enc_param enc_1,enc_imm enc_2,u32 sz,x86_operand_size enc_op_size>
|
||||
void __fastcall x86_encode_opcode_tmpl(x86_block* block, const x86_opcode* op, encoded_type* p1,encoded_type* p2,u32 p3)
|
||||
void x86_encode_opcode_tmpl(x86_block* block, const x86_opcode* op, encoded_type* p1,encoded_type* p2,u32 p3)
|
||||
{
|
||||
//printf("Encoding : ");
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ void virt_arm_init()
|
|||
VARM::virt_arm_init();
|
||||
}
|
||||
|
||||
u32 __fastcall virt_arm_op(u32 opcode)
|
||||
u32 DYNACALL virt_arm_op(u32 opcode)
|
||||
{
|
||||
return VARM::virt_arm_op(opcode);
|
||||
}
|
||||
|
|
|
@ -87,24 +87,24 @@ blkmap_t blkmap;
|
|||
u32 bm_gc_luc,bm_gcf_luc;
|
||||
|
||||
|
||||
#define FPCA(x) ((DynarecCodeEntry*&)sh4rcb.fpcb[(x>>1)&(8*1024*1024-1)])
|
||||
#define FPCA(x) ((DynarecCodeEntryPtr&)sh4rcb.fpcb[(x>>1)&(8*1024*1024-1)])
|
||||
|
||||
DynarecCodeEntry* DYNACALL bm_GetCode(u32 addr)
|
||||
DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr)
|
||||
{
|
||||
//rdv_FailedToFindBlock_pc=addr;
|
||||
DynarecCodeEntry* rv=(DynarecCodeEntry*)FPCA(addr);
|
||||
DynarecCodeEntryPtr rv=(DynarecCodeEntryPtr)FPCA(addr);
|
||||
|
||||
return (DynarecCodeEntry*)rv;
|
||||
return (DynarecCodeEntryPtr)rv;
|
||||
}
|
||||
|
||||
DynarecCodeEntry* DYNACALL bm_GetCode2(u32 addr)
|
||||
DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr)
|
||||
{
|
||||
return (DynarecCodeEntry*)bm_GetCode(addr);
|
||||
return (DynarecCodeEntryPtr)bm_GetCode(addr);
|
||||
}
|
||||
|
||||
RuntimeBlockInfo* DYNACALL bm_GetBlock(u32 addr)
|
||||
{
|
||||
DynarecCodeEntry* cde=bm_GetCode(addr);
|
||||
DynarecCodeEntryPtr cde=bm_GetCode(addr);
|
||||
|
||||
if (cde==ngen_FailedToFindBlock)
|
||||
return 0;
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
#include "decoder.h"
|
||||
#pragma once
|
||||
|
||||
typedef void DynarecCodeEntry();
|
||||
typedef void (*DynarecCodeEntryPtr)();
|
||||
|
||||
struct RuntimeBlockInfo_Core
|
||||
{
|
||||
u32 addr;
|
||||
DynarecCodeEntry* code;
|
||||
DynarecCodeEntryPtr code;
|
||||
u32 lookups;
|
||||
};
|
||||
|
||||
|
@ -81,13 +81,13 @@ struct CachedBlockInfo: RuntimeBlockInfo_Core
|
|||
void bm_WriteBlockMap(const string& file);
|
||||
|
||||
|
||||
DynarecCodeEntry* DYNACALL bm_GetCode(u32 addr);
|
||||
DynarecCodeEntryPtr DYNACALL bm_GetCode(u32 addr);
|
||||
|
||||
|
||||
#if HOST_OS==OS_LINUX
|
||||
extern "C" {
|
||||
#endif
|
||||
DynarecCodeEntry* DYNACALL bm_GetCode2(u32 addr);
|
||||
DynarecCodeEntryPtr DYNACALL bm_GetCode2(u32 addr);
|
||||
#if HOST_OS==OS_LINUX
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -208,7 +208,7 @@ void RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg)
|
|||
AnalyseBlock(this);
|
||||
}
|
||||
|
||||
DynarecCodeEntry* rdv_CompilePC()
|
||||
DynarecCodeEntryPtr rdv_CompilePC()
|
||||
{
|
||||
u32 pc=next_pc;
|
||||
|
||||
|
@ -240,7 +240,7 @@ DynarecCodeEntry* rdv_CompilePC()
|
|||
return rv->code;
|
||||
}
|
||||
|
||||
DynarecCodeEntry* DYNACALL rdv_FailedToFindBlock(u32 pc)
|
||||
DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc)
|
||||
{
|
||||
//printf("rdv_FailedToFindBlock ~ %08X\n",pc);
|
||||
next_pc=pc;
|
||||
|
@ -269,25 +269,25 @@ u32 DYNACALL rdv_DoInterrupts(void* block_cpde)
|
|||
return next_pc;
|
||||
}
|
||||
|
||||
DynarecCodeEntry* DYNACALL rdv_BlockCheckFail(u32 pc)
|
||||
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc)
|
||||
{
|
||||
next_pc=pc;
|
||||
recSh4_ClearCache();
|
||||
return rdv_CompilePC();
|
||||
}
|
||||
|
||||
DynarecCodeEntry* rdv_FindCode()
|
||||
DynarecCodeEntryPtr rdv_FindCode()
|
||||
{
|
||||
DynarecCodeEntry* rv=bm_GetCode(next_pc);
|
||||
DynarecCodeEntryPtr rv=bm_GetCode(next_pc);
|
||||
if (rv==ngen_FailedToFindBlock)
|
||||
return 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
DynarecCodeEntry* rdv_FindOrCompile()
|
||||
DynarecCodeEntryPtr rdv_FindOrCompile()
|
||||
{
|
||||
DynarecCodeEntry* rv=bm_GetCode(next_pc);
|
||||
DynarecCodeEntryPtr rv=bm_GetCode(next_pc);
|
||||
if (rv==ngen_FailedToFindBlock)
|
||||
rv=rdv_CompilePC();
|
||||
|
||||
|
@ -324,7 +324,7 @@ void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc)
|
|||
next_pc=rbi->NextBlock;
|
||||
}
|
||||
|
||||
DynarecCodeEntry* rv=rdv_FindOrCompile();
|
||||
DynarecCodeEntryPtr rv=rdv_FindOrCompile();
|
||||
|
||||
bool do_link=bm_GetBlock(code)==rbi;
|
||||
|
||||
|
|
|
@ -63,15 +63,15 @@ void* emit_GetCCPtr();
|
|||
void emit_SetBaseAddr();
|
||||
|
||||
//Called from ngen_FailedToFindBlock
|
||||
DynarecCodeEntry* DYNACALL rdv_FailedToFindBlock(u32 pc);
|
||||
DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc);
|
||||
//Called when a block check failed, and the block needs to be invalidated
|
||||
DynarecCodeEntry* DYNACALL rdv_BlockCheckFail(u32 pc);
|
||||
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc);
|
||||
//Called to compile code @pc
|
||||
DynarecCodeEntry* rdv_CompilePC();
|
||||
DynarecCodeEntryPtr rdv_CompilePC();
|
||||
//Returns 0 if there is no code @pc, code ptr otherwise
|
||||
DynarecCodeEntry* rdv_FindCode();
|
||||
DynarecCodeEntryPtr rdv_FindCode();
|
||||
//Finds or compiles code @pc
|
||||
DynarecCodeEntry* rdv_FindOrCompile();
|
||||
DynarecCodeEntryPtr rdv_FindOrCompile();
|
||||
|
||||
//code -> pointer to code of block, dpc -> if dynamic block, pc. if cond, 0 for next, 1 for branch
|
||||
void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc);
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//main system mem
|
||||
extern VArray2 mem_b;
|
||||
|
||||
#define MEMCALL __fastcall
|
||||
|
||||
#include "hw/mem/_vmem.h"
|
||||
#include "modules/mmu.h"
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ void WriteMem_P4(u32 addr,u32 data,u32 sz);
|
|||
//Area7
|
||||
u32 ReadMem_area7(u32 addr,u32 sz);
|
||||
void WriteMem_area7(u32 addr,u32 data,u32 sz);
|
||||
void __fastcall WriteMem_sq_32(u32 address,u32 data);*/
|
||||
void DYNACALL WriteMem_sq_32(u32 address,u32 data);*/
|
||||
|
||||
//Init/Res/Term
|
||||
void sh4_mmr_init();
|
||||
|
|
|
@ -47,6 +47,9 @@ struct sigcontext uc_mcontext;
|
|||
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.eip)
|
||||
#else
|
||||
#define GET_PC_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EIP])
|
||||
#define GET_ESP_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ESP])
|
||||
#define GET_EAX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_EAX])
|
||||
#define GET_ECX_FROM_CONTEXT(c) (((ucontext_t *)(c))->uc_mcontext.gregs[REG_ECX])
|
||||
#endif
|
||||
#else
|
||||
#error fix ->pc support
|
||||
|
@ -54,6 +57,7 @@ struct sigcontext uc_mcontext;
|
|||
|
||||
#include "hw/sh4/dyna/ngen.h"
|
||||
|
||||
bool ngen_Rewrite(unat& addr,unat retadr,unat acc);
|
||||
u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr);
|
||||
bool VramLockedWrite(u8* address);
|
||||
bool BM_LockedWrite(u8* address);
|
||||
|
@ -68,12 +72,24 @@ void fault_handler (int sn, siginfo_t * si, void *ctxr)
|
|||
|
||||
if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr))
|
||||
return;
|
||||
#if !defined( HOST_NO_REC) && HOST_CPU==CPU_ARM
|
||||
else if (dyna_cde)
|
||||
{
|
||||
GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr);
|
||||
}
|
||||
#endif
|
||||
#if !defined(HOST_NO_REC)
|
||||
#if HOST_CPU==CPU_ARM
|
||||
else if (dyna_cde)
|
||||
{
|
||||
GET_PC_FROM_CONTEXT(ctxr)=(u32)ngen_readm_fail_v2((u32*)GET_PC_FROM_CONTEXT(ctxr),(u32*)&(ctx->uc_mcontext.arm_r0),(unat)si->si_addr);
|
||||
}
|
||||
#elif HOST_CPU==CPU_X86
|
||||
else if ( ngen_Rewrite((unat&)GET_PC_FROM_CONTEXT(ctxr),*(unat*)GET_ESP_FROM_CONTEXT(ctxr),GET_EAX_FROM_CONTEXT(ctxr)) )
|
||||
{
|
||||
//remove the call from call stack
|
||||
GET_ESP_FROM_CONTEXT(ctxr)+=4;
|
||||
//restore the addr from eax to ecx so its valid again
|
||||
GET_ECX_FROM_CONTEXT(ctxr)=GET_EAX_FROM_CONTEXT(ctxr);
|
||||
}
|
||||
#else
|
||||
#error JIT: Not supported arch
|
||||
#endif
|
||||
#endif
|
||||
else
|
||||
{
|
||||
printf("SIGSEGV @ fault_handler+0x%08X ... %08X -> was not in vram\n",GET_PC_FROM_CONTEXT(ctxr)-(u32)fault_handler,si->si_addr);
|
||||
|
|
|
@ -1979,7 +1979,7 @@ __default:
|
|||
void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise)
|
||||
{
|
||||
//printf("Compile: %08X, %d, %d\n",block->addr,staging,optimise);
|
||||
block->code=(DynarecCodeEntry*)EMIT_GET_PTR();
|
||||
block->code=(DynarecCodeEntryPtr)EMIT_GET_PTR();
|
||||
|
||||
//StoreImms(r0,r1,(u32)&last_run_block,(u32)code); //useful when code jumps to random locations ...
|
||||
++blockno;
|
||||
|
|
|
@ -301,7 +301,7 @@ void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool st
|
|||
x86e->x86_size=emit_FreeSpace();
|
||||
x86e->do_realloc=false;
|
||||
|
||||
block->code=(DynarecCodeEntry*)emit_GetCCPtr();
|
||||
block->code=(DynarecCodeEntryPtr)emit_GetCCPtr();
|
||||
|
||||
x86e->Emit(op_add32,&memops_t,block->memops);
|
||||
x86e->Emit(op_add32,&memops_l,block->linkedmemops);
|
||||
|
|
|
@ -13,10 +13,8 @@
|
|||
|
||||
#if BUILD_COMPILER==COMPILER_VC
|
||||
#define DYNACALL __fastcall
|
||||
#define DYNACALL_T
|
||||
#else
|
||||
#define DYNACALL
|
||||
#define DYNACALL_T __attribute__((fastcall))
|
||||
#define DYNACALL __attribute__((fastcall))
|
||||
#endif
|
||||
|
||||
#if BUILD_COMPILER==COMPILER_VC
|
||||
|
@ -511,7 +509,7 @@ void os_DebugBreak();
|
|||
#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
//#define __fastcall <nothing useful is here "" must not happen ever>
|
||||
#define __fastcall <nothing useful is here "" must not happen ever>
|
||||
#ifndef STRIP_TEXT
|
||||
#define verify(x) if((x)==false){ msgboxf("Verify Failed : " #x "\n in %s -> %s : %d \n",MBX_ICONERROR,(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;}
|
||||
#define die(reason) { msgboxf("Fatal error : %s\n in %s -> %s : %d \n",MBX_ICONERROR,(reason),(__FUNCTION__),(__FILE__),__LINE__); dbgbreak;}
|
||||
|
|
|
@ -299,7 +299,7 @@ void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool st
|
|||
x86e->x86_size=emit_FreeSpace();
|
||||
x86e->do_realloc=false;
|
||||
|
||||
block->code=(DynarecCodeEntry*)emit_GetCCPtr();
|
||||
block->code=(DynarecCodeEntryPtr)emit_GetCCPtr();
|
||||
|
||||
x86e->Emit(op_add32,&memops_t,block->memops);
|
||||
x86e->Emit(op_add32,&memops_l,block->linkedmemops);
|
||||
|
|
Loading…
Reference in New Issue