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
This commit is contained in:
dok.slade 2010-07-26 23:06:34 +00:00
parent ce3eb85d96
commit 99ffecd675
3 changed files with 41 additions and 1 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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.