summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authordok.slade <dok.slade@gmail.com>2010-07-26 23:06:34 +0000
committerdok.slade <dok.slade@gmail.com>2010-07-26 23:06:34 +0000
commit99ffecd6754c1217c71efa084291a4da1057a1d2 (patch)
treec59200b1a096a041127072df0a5fbfa77a836d38 /Source
parentce3eb85d96b63dda6e0ecf58c53e280888075bdf (diff)
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
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp6
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h1
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp35
3 files changed, 41 insertions, 1 deletions
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.