From 757f849ad021ffcbfb2e4e88c243bcd8dde02f16 Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Sun, 14 May 2006 07:21:10 +0000 Subject: [PATCH] Optimize generated code to NQD & CheckLoad functions. They don't call into 68k or MacOS code, so they don't need to be a termination point. i.e. don't split into two basic blocks and thus avoid a full hash search. Also add missing NQD_unknown_hook NativeOp from previous commit. --- SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp | 29 ++++++++++++++++++- .../kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp | 10 +++++++ .../src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp | 11 +++++++ .../src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp | 1 + SheepShaver/src/thunks.cpp | 17 ++++++----- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp index d17d3d0f..67863768 100644 --- a/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp +++ b/SheepShaver/src/kpx_cpu/sheepshaver_glue.cpp @@ -336,6 +336,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context) status = COMPILE_CODE_OK; break; } +#endif case NATIVE_CHECK_LOAD_INVOC: dg.gen_load_T0_GPR(3); dg.gen_load_T1_GPR(4); @@ -351,7 +352,30 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context) dg.gen_invoke_T0_T1_T2((void (*)(uint32, uint32, uint32))named_check_load_invoc); status = COMPILE_CODE_OK; break; -#endif + case NATIVE_NQD_SYNC_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_sync_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_BITBLT_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_bitblt_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_FILLRECT_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_fillrect_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; + case NATIVE_NQD_UNKNOWN_HOOK: + dg.gen_load_T0_GPR(3); + dg.gen_invoke_T0_ret_T0((uint32 (*)(uint32))NQD_unknown_hook); + dg.gen_store_T0_GPR(3); + status = COMPILE_CODE_OK; + break; case NATIVE_NQD_BITBLT: dg.gen_load_T0_GPR(3); dg.gen_invoke_T0((void (*)(uint32))NQD_bitblt); @@ -1036,6 +1060,9 @@ void sheepshaver_cpu::execute_native_op(uint32 selector) case NATIVE_NQD_SYNC_HOOK: gpr(3) = NQD_sync_hook(gpr(3)); break; + case NATIVE_NQD_UNKNOWN_HOOK: + gpr(3) = NQD_unknown_hook(gpr(3)); + break; case NATIVE_NQD_BITBLT_HOOK: gpr(3) = NQD_bitblt_hook(gpr(3)); break; diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp index 0a3dacaf..18a180fa 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen-ops.cpp @@ -414,6 +414,11 @@ DEFINE_OP(op_invoke_T0_T1_T2, { CALL(reg_A0,(T0, T1, T2)); }); +DEFINE_OP(op_invoke_T0_ret_T0, { + typedef uint32 (*func_t)(uint32); + T0 = CALL(reg_A0,(T0)); +}); + DEFINE_OP(op_invoke_im, { typedef void (*func_t)(uint32); CALL(reg_A0,(PARAM1)); @@ -459,6 +464,11 @@ DEFINE_OP(op_invoke_direct_T0_T1_T2, { CALL(PARAM1,(T0, T1, T2)); }); +DEFINE_OP(op_invoke_direct_T0_ret_T0, { + typedef uint32 (*func_t)(uint32); + T0 = CALL(PARAM1,(T0)); +}); + DEFINE_OP(op_invoke_direct_im, { typedef void (*func_t)(uint32); CALL(PARAM1,(PARAM2)); diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp index 0ac0883b..99696e8b 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.cpp @@ -89,6 +89,17 @@ basic_dyngen::gen_invoke_T0_T1_T2(void (*func)(uint32, uint32, uint32)) } } +void +basic_dyngen::gen_invoke_T0_ret_T0(uint32 (*func)(uint32)) +{ + if (direct_call_possible((uintptr)func)) + gen_op_invoke_direct_T0_ret_T0((uintptr)func); + else { + gen_op_mov_ad_A0_im((uintptr)func); + gen_op_invoke_T0_ret_T0(); + } +} + void basic_dyngen::gen_invoke_im(void (*func)(uint32), uint32 value) { diff --git a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp index 29684f33..24321551 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/jit/basic-dyngen.hpp @@ -105,6 +105,7 @@ public: void gen_invoke_T0(void (*func)(uint32)); void gen_invoke_T0_T1(void (*func)(uint32, uint32)); void gen_invoke_T0_T1_T2(void (*func)(uint32, uint32, uint32)); + void gen_invoke_T0_ret_T0(uint32 (*func)(uint32)); void gen_invoke_im(void (*func)(uint32), uint32 value); void gen_invoke_CPU(void (*func)(dyngen_cpu_base)); void gen_invoke_CPU_T0(void (*func)(dyngen_cpu_base, uint32)); diff --git a/SheepShaver/src/thunks.cpp b/SheepShaver/src/thunks.cpp index dc2db28b..954f1155 100644 --- a/SheepShaver/src/thunks.cpp +++ b/SheepShaver/src/thunks.cpp @@ -57,6 +57,13 @@ uint32 NativeOpcode(int selector) switch (selector) { case NATIVE_CHECK_LOAD_INVOC: case NATIVE_NAMED_CHECK_LOAD_INVOC: + case NATIVE_NQD_SYNC_HOOK: + case NATIVE_NQD_BITBLT_HOOK: + case NATIVE_NQD_FILLRECT_HOOK: + case NATIVE_NQD_UNKNOWN_HOOK: + case NATIVE_NQD_BITBLT: + case NATIVE_NQD_INVRECT: + case NATIVE_NQD_FILLRECT: opcode = POWERPC_NATIVE_OP(0, selector); break; case NATIVE_PATCH_NAME_REGISTRY: @@ -89,13 +96,6 @@ uint32 NativeOpcode(int selector) case NATIVE_GET_NAMED_RESOURCE: case NATIVE_GET_1_NAMED_RESOURCE: case NATIVE_MAKE_EXECUTABLE: - case NATIVE_NQD_SYNC_HOOK: - case NATIVE_NQD_BITBLT_HOOK: - case NATIVE_NQD_FILLRECT_HOOK: - case NATIVE_NQD_UNKNOWN_HOOK: - case NATIVE_NQD_BITBLT: - case NATIVE_NQD_INVRECT: - case NATIVE_NQD_FILLRECT: opcode = POWERPC_NATIVE_OP(1, selector); break; default: @@ -262,10 +262,11 @@ bool ThunksInit(void) { #if EMULATED_PPC for (int i = 0; i < NATIVE_OP_MAX; i++) { - uintptr base = SheepMem::Reserve(12); + uintptr base = SheepMem::Reserve(16); WriteMacInt32(base + 0, base + 8); WriteMacInt32(base + 4, 0); // Fake TVECT WriteMacInt32(base + 8, NativeOpcode(i)); + WriteMacInt32(base + 12, POWERPC_BLR); native_op[i].tvect = base; native_op[i].func = base + 8; }