From 99ffecd6754c1217c71efa084291a4da1057a1d2 Mon Sep 17 00:00:00 2001 From: "dok.slade" Date: Mon, 26 Jul 2010 23:06:34 +0000 Subject: [PATCH] Merge JIT instructions when loading 32-bits immediate values : PowerPC needs 2 instructions to load a 32-bits immediate value in a register (lis + addi; lis + ori). We can merge both instructions into a single SetImmediate(). This commit shares code with r5799, so to prevent another flame war on OSX vs Windows, I added #ifdef around the "bad" lines... git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5982 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 6 ++++ Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 1 + .../Core/Src/PowerPC/Jit64/Jit_Integer.cpp | 35 ++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index c911b5f1c3..9023ce3c18 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -502,6 +502,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address); + js.skipnext = false; js.blockSize = size; // Translate instructions for (int i = 0; i < (int)size; i++) @@ -549,6 +550,11 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } #endif + if (js.skipnext) { + js.skipnext = false; + i++; // Skip next instruction + } + if (js.cancel) break; } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 5e3161cb76..ec5c9e1ac0 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -61,6 +61,7 @@ private: u32 next_compilerPC; u32 blockStart; bool cancel; + bool skipnext; UGeckoInstruction next_inst; // for easy peephole opt. int blockSize; int instructionNumber; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 8b7e03a440..a543e9a520 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -91,8 +91,11 @@ void Jit64::regimmop(int d, int a, bool binary, u32 value, Operation doop, void { // a == 0, which for these instructions imply value = 0 gpr.SetImmediate32(d, value); +#ifdef __APPLE__ // XXX soren + // FIXME: Seems to be required on OS X (see r5799) gpr.StoreFromX64(d); +#endif } else { @@ -126,7 +129,37 @@ void Jit64::reg_imm(UGeckoInstruction inst) regimmop(d, a, false, (u32)(s32)inst.SIMM_16, Add, &XEmitter::ADD); //addi } break; - case 15: regimmop(d, a, false, (u32)inst.SIMM_16 << 16, Add, &XEmitter::ADD); break; //addis + case 15: + if (a == 0) { // lis + // Merge with next instruction if loading a 32-bits immediate value (lis + addi, lis + ori) + if (!js.isLastInstruction) { + if ((js.next_inst.OPCD == 14) && (js.next_inst.RD == d) && (js.next_inst.RA == d)) { // addi + gpr.SetImmediate32(d, ((u32)inst.SIMM_16 << 16) + (u32)(s32)js.next_inst.SIMM_16); +#ifdef __APPLE__ + // FIXME: Seems to be required on OS X (see r5799) + gpr.StoreFromX64(d); +#endif + js.skipnext = true; + break; + } + else if ((js.next_inst.OPCD == 24) && (js.next_inst.RA == d) && (js.next_inst.RS == d)) { // ori + gpr.SetImmediate32(d, ((u32)inst.SIMM_16 << 16) | (u32)js.next_inst.UIMM); +#ifdef __APPLE__ + // FIXME: Seems to be required on OS X (see r5799) + gpr.StoreFromX64(d); +#endif + js.skipnext = true; + break; + } + } + + // Not merged + regimmop(d, a, false, (u32)inst.SIMM_16 << 16, Add, &XEmitter::ADD); + } + else { // addis + regimmop(d, a, false, (u32)inst.SIMM_16 << 16, Add, &XEmitter::ADD); + } + break; case 24: if (a == 0 && s == 0 && inst.UIMM == 0 && !inst.Rc) //check for nop {NOP(); return;} //make the nop visible in the generated code. not much use but interesting if we see one.