linux: Sh4 dynarec works

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-05-08 18:59:20 +02:00
parent d33ad6edfb
commit 5b609a6be4
14 changed files with 64 additions and 52 deletions

View File

@ -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;

View File

@ -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 : ");

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -4,8 +4,6 @@
//main system mem
extern VArray2 mem_b;
#define MEMCALL __fastcall
#include "hw/mem/_vmem.h"
#include "modules/mmu.h"

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;}

View File

@ -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);