mirror of
https://github.com/libretro/parallel-dc.git
synced 2026-11-13 04:41:41 -10:00
274 lines
7.0 KiB
C++
274 lines
7.0 KiB
C++
#include "types.h"
|
|
|
|
#include <map>
|
|
#include <algorithm>
|
|
|
|
#include "hw/sh4/sh4_opcode_list.h"
|
|
#include "hw/sh4/modules/ccn.h"
|
|
#include "hw/sh4/sh4_interrupts.h"
|
|
|
|
#include "hw/sh4/sh4_core.h"
|
|
#include "hw/sh4/dyna/ngen.h"
|
|
#include "hw/sh4/sh4_mem.h"
|
|
#include "hw/sh4/dyna/regalloc.h"
|
|
|
|
int cycle_counter;
|
|
|
|
struct DynaRBI : RuntimeBlockInfo
|
|
{
|
|
/* NOTE/TODO - this was virtual u32 Relink();
|
|
* for rec_arm.cpp - check this in case of
|
|
* errors */
|
|
virtual u32 Relink()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
virtual void Relocate(void* dst) {
|
|
}
|
|
};
|
|
|
|
#if !(HOST_CPU == CPU_ARM) || (FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86)
|
|
static void ngen_mainloop_exec(Sh4RCB* ctx)
|
|
{
|
|
cycle_counter = SH4_TIMESLICE;
|
|
|
|
do {
|
|
DynarecCodeEntryPtr rcb = bm_GetCode(ctx->cntx.pc);
|
|
rcb();
|
|
} while (cycle_counter > 0);
|
|
|
|
if (UpdateSystem())
|
|
rdv_DoInterrupts_pc(ctx->cntx.pc);
|
|
}
|
|
|
|
void ngen_mainloop(void* v_cntx)
|
|
{
|
|
Sh4RCB* ctx = (Sh4RCB*)((u8*)v_cntx - sizeof(Sh4RCB));
|
|
|
|
for (
|
|
#if defined(TARGET_BOUNDED_EXECUTION)
|
|
int i=0; i<10000; i++
|
|
#else
|
|
;;
|
|
#endif
|
|
)
|
|
ngen_mainloop_exec(ctx);
|
|
}
|
|
#endif
|
|
|
|
|
|
void ngen_init(void)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0: /* native dynarec */
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_init_x86_32bit(void);
|
|
ngen_init_x86_32bit();
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_init_arm(void);
|
|
ngen_init_arm();
|
|
#endif
|
|
break;
|
|
case 1: /* rec_cpp */
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if !(FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86)
|
|
extern "C" {
|
|
|
|
void ngen_FailedToFindBlock_internal(void)
|
|
{
|
|
rdv_FailedToFindBlock(Sh4cntx.pc);
|
|
}
|
|
|
|
};
|
|
|
|
void(*ngen_FailedToFindBlock)() = &ngen_FailedToFindBlock_internal;
|
|
#endif
|
|
|
|
void ngen_GetFeatures(ngen_features* dst)
|
|
{
|
|
dst->InterpreterFallback = false;
|
|
dst->OnlyDynamicEnds = false;
|
|
}
|
|
|
|
int idxnxx = 0;
|
|
|
|
void ngen_ResetBlocks(void)
|
|
{
|
|
printf("@@\tngen_ResetBlocks()\n");
|
|
idxnxx = 0;
|
|
}
|
|
|
|
void *compiler_data;
|
|
|
|
void ngen_CC_Param(shil_opcode* op, shil_param* par, CanonicalParamType tp)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0:
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_CC_Param_x86(shil_opcode* op,shil_param* par,CanonicalParamType tp);
|
|
ngen_CC_Param_x86(op, par, tp);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_CC_Param_arm(shil_opcode* op,shil_param* par,CanonicalParamType tp);
|
|
ngen_CC_Param_arm(op, par, tp);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64
|
|
extern void ngen_CC_Param_x64(shil_opcode* op,shil_param* par,CanonicalParamType tp);
|
|
ngen_CC_Param_x64(op, par, tp);
|
|
break;
|
|
#elif defined(TARGET_NO_JIT)
|
|
/* we want this to fall through */
|
|
#else
|
|
break;
|
|
#endif
|
|
case 1: /* rec_cpp */
|
|
#ifdef TARGET_NO_JIT
|
|
extern void ngen_CC_Param_cpp(shil_opcode* op,shil_param* par,CanonicalParamType tp);
|
|
ngen_CC_Param_cpp(op, par, tp);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void ngen_CC_Call(shil_opcode*op, void* function)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0:
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_CC_Call_x86(shil_opcode*op,void* function);
|
|
ngen_CC_Call_x86(op, function);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_CC_Call_arm(shil_opcode* op,void* function);
|
|
ngen_CC_Call_arm(op, function);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64
|
|
extern void ngen_CC_Call_x64(shil_opcode*op, void* function);
|
|
ngen_CC_Call_x64(op, function);
|
|
break;
|
|
#elif defined(TARGET_NO_JIT)
|
|
/* we want to fall-through here */
|
|
#else
|
|
break;
|
|
#endif
|
|
case 1:
|
|
#ifdef TARGET_NO_JIT
|
|
extern void ngen_CC_Call_cpp(shil_opcode*op, void* function);
|
|
ngen_CC_Call_cpp(op, function);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ngen_CC_Finish(shil_opcode* op)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0:
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_CC_Finish_x86(shil_opcode* op);
|
|
ngen_CC_Finish_x86(op);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_CC_Finish_arm(shil_opcode* op);
|
|
ngen_CC_Finish_arm(op);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64
|
|
extern void ngen_CC_Finish_x64(shil_opcode* op);
|
|
ngen_CC_Finish_x64(op);
|
|
break;
|
|
#elif defined(TARGET_NO_JIT)
|
|
/* we want to fall-through here */
|
|
#else
|
|
break;
|
|
#endif
|
|
case 1:
|
|
#ifdef TARGET_NO_JIT
|
|
extern void ngen_CC_Finish_cpp(shil_opcode* op);
|
|
ngen_CC_Finish_cpp(op);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ngen_CC_Start(shil_opcode* op)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0:
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_CC_Start_x86(shil_opcode* op);
|
|
ngen_CC_Start_x86(op);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_CC_Start_arm(shil_opcode* op);
|
|
ngen_CC_Start_arm(op);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64
|
|
extern void ngen_CC_Start_x64(shil_opcode* op);
|
|
ngen_CC_Start_x64(op);
|
|
break;
|
|
#elif defined(TARGET_NO_JIT)
|
|
/* we want this to fall through */
|
|
#else
|
|
break;
|
|
#endif
|
|
case 1: /* rec_cpp */
|
|
#ifdef TARGET_NO_JIT
|
|
extern void ngen_CC_Start_cpp(shil_opcode* op);
|
|
ngen_CC_Start_cpp(op);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise)
|
|
{
|
|
switch (settings.dynarec.Type)
|
|
{
|
|
case 0:
|
|
#if FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X86
|
|
extern void ngen_Compile_x86(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise)
|
|
ngen_Compile_x86(block, force_checks, reset, staging, optimise);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_ARM
|
|
extern void ngen_Compile_arm(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise);
|
|
ngen_Compile_arm(block, force_checks, reset, staging, optimise);
|
|
break;
|
|
#elif FEAT_SHREC == DYNAREC_JIT && HOST_CPU == CPU_X64
|
|
extern void ngen_Compile_x64(RuntimeBlockInfo* block, bool force_checks, bool reset, bool staging, bool optimise);
|
|
ngen_Compile_x64(block, force_checks, reset, staging, optimise);
|
|
break;
|
|
#elif defined(TARGET_NO_JIT)
|
|
/* we want this to fall through */
|
|
#else
|
|
break;
|
|
#endif
|
|
case 1: /* rec_cpp */
|
|
#ifdef TARGET_NO_JIT
|
|
extern void ngen_Compile_cpp(RuntimeBlockInfo* block, bool force_checks, bool reset, bool staging, bool optimise);
|
|
ngen_Compile_cpp(block, force_checks, reset, staging, optimise);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
RuntimeBlockInfo* ngen_AllocateBlock(void)
|
|
{
|
|
return new DynaRBI();
|
|
}
|
|
|
|
u32* GetRegPtr(u32 reg)
|
|
{
|
|
return Sh4_int_GetRegisterPtr((Sh4RegType)reg);
|
|
}
|