#include "types.h" #include "driver.h" #include "dc/sh4/sh4_interpreter.h" #include "dc/sh4/sh4_opcode_list.h" #include "dc/sh4/sh4_registers.h" #include "dc/sh4/sh4_if.h" #include "dc/pvr/pvr_if.h" #include "dc/aica/aica_if.h" #include "dc/gdrom/gdrom_if.h" #include "dc/sh4/intc.h" #include "dc/sh4/tmu.h" #include "dc/mem/sh4_mem.h" #include "dc/sh4/shil/shil_ce.h" #include "emitter/emitter.h" #include "recompiler.h" #include "blockmanager.h" #include "analyser.h" #include #include #include extern "C" { #include } #include //uh uh volatile bool rec_sh4_int_bCpuRun=false; u32 rec_exec_cycles=0; time_t rec_odtime=0; u32 avg_rat=0; u32 avg_rat_cnt=0; u32 avg_bc=0; u32 sb_count=0; u32 nb_count=0; u32 __attribute__((externally_visible)) rec_cycles=0; void* __attribute__((externally_visible)) Dynarec_Mainloop_no_update; void* __attribute__((externally_visible)) Dynarec_Mainloop_do_update; void* __attribute__((externally_visible)) Dynarec_Mainloop_end; void DynaPrintLinkStart(); void DynaPrintLinkEnd(); void DumpBlockMappings(); LARGE_INTEGER total_compile; u32 CompiledSRCsz=0; CompiledBlockInfo* __fastcall CompileCode(u32 pc) { LARGE_INTEGER comp_time_start,comp_time_end; CompiledBlockInfo* cblock=0; //bool reset_blocks; comp_time_start=mftb(); { nb_count++; //cblock=AnalyseCodeSuperBlock(pc); if (cblock==0) cblock=CompileBasicBlock(pc); RegisterBlock(cblock); } comp_time_end=mftb(); total_compile+=comp_time_end-comp_time_start; //compile code //return pointer if (!cblock) { _SuspendAllBlocks(); dlog("Compile failed -- retrying\n"); return CompileCode(pc);//retry } return cblock; } extern "C" { // called from asm BasicBlockEP* __attribute__((externally_visible)) __fastcall CompileCodePtr() { return CompileCode(sh4r.pc)->Code; } } INLINE BasicBlockEP * __fastcall GetRecompiledCodePointer(u32 pc) { return FindCode(pc); } CompiledBlockInfo* FindOrRecompileBlock(u32 pc) { CompiledBlockInfo* cblock=FindBlock(pc); if (cblock) return cblock; else return CompileCode(pc); } void __attribute__((naked)) CompileAndRunCode() { #ifdef XENON asm volatile ( "bl CompileCodePtr \n" "mtctr 3 \n" "bctr \n" ); #else __asm { call CompileCodePtr; jmp eax; } #endif } void __fastcall rec_sh4_int_RaiseExeption(u32 ExeptionCode,u32 VectorAddress) { } void rec_sh4_ResetCache() { SuspendAllBlocks(); } /////////////////////////////////////////////////////////////////////////////// #define DYNA_LOOKUP_SIZE (RAM_SIZE/2) // one sh4 op is 2 bytes #define DYNA_LOOKUP_BYTE_SIZE (DYNA_LOOKUP_SIZE*4) #define LOC_VM_USER_PAGE_SIZE 65536 u32 * __attribute__((aligned(LOC_VM_USER_PAGE_SIZE))) sh4_pc_to_ppc=NULL; u32 __attribute__((aligned(VM_USER_PAGE_SIZE))) sh4_pc_to_ppc_full_lookup[VM_USER_PAGE_SIZE/sizeof(void*)]; extern "C" { void __attribute__((naked)) DynaFullLookup() { asm volatile ( "mr 3," xstr(RPC) " \n" "stw 3,0(" xstr(RSH4R) ") \n" //sh4r+0 is pc "li 4,0 \n" "bl FindCode_full \n" "mtctr 3 \n" //"bctr\n" "rlwinm 5," xstr(RPC) ",16,0x1FFF \n" "cmplwi 5,0x0c00 \n" "bltctr \n" // make sure target is in recompiled code "lis 4,DynarecCache@ha \n" "lwz 4,DynarecCache@l(4) \n" "cmplw 3,4 \n" "bltctr \n" "addis 4,4," xstr(DYNA_MEM_POOL_SIZE>>16) "\n" "cmplw 3,4 \n" "bgectr \n" // update lookup table "lis 5,sh4_pc_to_ppc@ha \n" "lwz 5,sh4_pc_to_ppc@l(5) \n" "rlwinm 6," xstr(RPC) ",1,0x01fffffc \n" "stwx 3,5,6 \n" "bctr \n" ); } } void DynaLookupMap(u32 start_pc, u32 end_pc, void* ppc_code) { u32 i; if((start_pc&0x1FFFFFFF)<0x08000000 || (start_pc&0x1FFFFFFF)>=0x10000000) return; // printf("s %p e %p code %p\n",start_pc,end_pc,ppc_code); u32* addr=(u32*)(((start_pc<<1)&0x0FFFFFFC)|0x30000000); for(i=start_pc;i<=end_pc;i+=2) { sh4_pc_to_ppc[(i>>1)&(DYNA_LOOKUP_SIZE-1)]=(u32)ppc_code; verify(*addr==(u32)ppc_code); ++addr; } } void DynaLookupUnmap(u32 start_pc, u32 end_pc) { DynaLookupMap(start_pc,end_pc,(void*)DynaFullLookup); } void DynaLookupReset() { if(!sh4_pc_to_ppc) sh4_pc_to_ppc=(u32*)memalign(VM_USER_PAGE_SIZE,DYNA_LOOKUP_BYTE_SIZE); int i; for(i=0;i