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:
parent
ce3eb85d96
commit
99ffecd675
|
@ -502,6 +502,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||||
js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address);
|
js.downcountAmount = js.st.numCycles + PatchEngine::GetSpeedhackCycles(em_address);
|
||||||
|
|
||||||
|
js.skipnext = false;
|
||||||
js.blockSize = size;
|
js.blockSize = size;
|
||||||
// Translate instructions
|
// Translate instructions
|
||||||
for (int i = 0; i < (int)size; i++)
|
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
|
#endif
|
||||||
|
|
||||||
|
if (js.skipnext) {
|
||||||
|
js.skipnext = false;
|
||||||
|
i++; // Skip next instruction
|
||||||
|
}
|
||||||
|
|
||||||
if (js.cancel)
|
if (js.cancel)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ private:
|
||||||
u32 next_compilerPC;
|
u32 next_compilerPC;
|
||||||
u32 blockStart;
|
u32 blockStart;
|
||||||
bool cancel;
|
bool cancel;
|
||||||
|
bool skipnext;
|
||||||
UGeckoInstruction next_inst; // for easy peephole opt.
|
UGeckoInstruction next_inst; // for easy peephole opt.
|
||||||
int blockSize;
|
int blockSize;
|
||||||
int instructionNumber;
|
int instructionNumber;
|
||||||
|
|
|
@ -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
|
// a == 0, which for these instructions imply value = 0
|
||||||
gpr.SetImmediate32(d, value);
|
gpr.SetImmediate32(d, value);
|
||||||
|
#ifdef __APPLE__
|
||||||
// XXX soren
|
// XXX soren
|
||||||
|
// FIXME: Seems to be required on OS X (see r5799)
|
||||||
gpr.StoreFromX64(d);
|
gpr.StoreFromX64(d);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -126,7 +129,37 @@ void Jit64::reg_imm(UGeckoInstruction inst)
|
||||||
regimmop(d, a, false, (u32)(s32)inst.SIMM_16, Add, &XEmitter::ADD); //addi
|
regimmop(d, a, false, (u32)(s32)inst.SIMM_16, Add, &XEmitter::ADD); //addi
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case 24:
|
||||||
if (a == 0 && s == 0 && inst.UIMM == 0 && !inst.Rc) //check for nop
|
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.
|
{NOP(); return;} //make the nop visible in the generated code. not much use but interesting if we see one.
|
||||||
|
|
Loading…
Reference in New Issue