From 5e806eb7b27db99510fd565505587b7d7c246cb6 Mon Sep 17 00:00:00 2001 From: nodchip Date: Thu, 23 Sep 2010 02:05:04 +0000 Subject: [PATCH] Jit64/JitIL: Implemented simple function inlining for speedup. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6223 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/Src/PowerPC/Jit64/Jit_Branch.cpp | 7 ++++++ .../Core/Src/PowerPC/Jit64IL/JitIL_Branch.cpp | 8 ++++++ Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 25 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp index aef25e9779..34f9839d6f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp @@ -221,6 +221,13 @@ void Jit64::bclrx(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Branch) + if (!js.isLastInstruction && + (inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) { + if (inst.LK) + MOV(32, M(&LR), Imm32(js.compilerPC + 4)); + return; + } + gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Branch.cpp index 608d362032..207ac60a5f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Branch.cpp @@ -185,6 +185,14 @@ void JitIL::bcctrx(UGeckoInstruction inst) void JitIL::bclrx(UGeckoInstruction inst) { NORMALBRANCH_START + + if (!js.isLastInstruction && + (inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) { + if (inst.LK) + ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4)); + return; + } + if (inst.hex == 0x4e800020) { ibuild.EmitBranchUncond(ibuild.EmitLoadLink()); return; diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index 5de88c305c..bb94789588 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -325,6 +325,8 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, CodeOp *code = buffer->codebuffer; bool foundExit = false; + u32 returnAddress = 0; + // Do analysis of the code, look for dependencies etc int numSystemInstructions = 0; for (int i = 0; i < maxsize; i++) @@ -454,6 +456,29 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, if (destination != blockstart) follow = true; } + else if (inst.OPCD == 19 && inst.SUBOP10 == 16 && + (inst.BO & (1 << 4)) && (inst.BO & (1 << 2)) && + returnAddress != 0) + { + // bclrx with unconditional branch = return + follow = true; + destination = returnAddress; + returnAddress = 0; + + if (inst.LK) + returnAddress = address + 4; + } + else if (inst.OPCD == 31 && inst.SUBOP10 == 467) + { + // mtspr + const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + if (index == SPR_LR) { + // We give up to follow the return address + // because we have to check the register usage. + returnAddress = 0; + } + } + if (follow) numFollows++; // TODO: Find the optimal value for FUNCTION_FOLLOWING_THRESHOLD.