JIT: more mftb fixes

A very subtle difference in how I calculated the timebase value seems
to have broken Karaoke Revolution; this seems to fix it. Also be a bit more
paranoid in conditions for mftb merging.
This commit is contained in:
Fiora 2014-11-01 03:13:08 -07:00
parent 86c100c442
commit 7deaf00c44
1 changed files with 21 additions and 25 deletions

View File

@ -204,21 +204,19 @@ void Jit64::mfspr(UGeckoInstruction inst)
// no register choice // no register choice
gpr.FlushLockX(RDX, RAX); gpr.FlushLockX(RDX, RAX);
u32 offset = js.downcountAmount / SystemTimers::TIMER_RATIO;
// An inline implementation of CoreTiming::GetFakeTimeBase, since in timer-heavy games the // An inline implementation of CoreTiming::GetFakeTimeBase, since in timer-heavy games the
// cost of calling out to C for this is actually significant. // cost of calling out to C for this is actually significant.
MOV(64, R(RAX), M(&CoreTiming::globalTimer)); MOV(64, R(RAX), M(&CoreTiming::globalTimer));
SUB(64, R(RAX), M(&CoreTiming::fakeTBStartTicks)); SUB(64, R(RAX), M(&CoreTiming::fakeTBStartTicks));
// The timer can change within a long block, so add in any difference
if (js.downcountAmount)
ADD(64, R(RAX), Imm32(js.downcountAmount));
// a / 12 = (a * 0xAAAAAAAAAAAAAAAB) >> 67 // a / 12 = (a * 0xAAAAAAAAAAAAAAAB) >> 67
MOV(64, R(RDX), Imm64(0xAAAAAAAAAAAAAAABULL)); MOV(64, R(RDX), Imm64(0xAAAAAAAAAAAAAAABULL));
MUL(64, R(RDX)); MUL(64, R(RDX));
MOV(64, R(RAX), M(&CoreTiming::fakeTBStartValue)); MOV(64, R(RAX), M(&CoreTiming::fakeTBStartValue));
SHR(64, R(RDX), Imm8(3)); SHR(64, R(RDX), Imm8(3));
// The timer can change within a long block, so add in any difference
if (offset > 0)
LEA(64, RAX, MComplex(RAX, RDX, SCALE_1, offset));
else
ADD(64, R(RAX), R(RDX)); ADD(64, R(RAX), R(RDX));
MOV(64, PPCSTATE(spr[SPR_TL]), R(RAX)); MOV(64, PPCSTATE(spr[SPR_TL]), R(RAX));
@ -226,11 +224,10 @@ void Jit64::mfspr(UGeckoInstruction inst)
// if we can. // if we can.
u32 nextIndex = (js.next_inst.SPRU << 5) | (js.next_inst.SPRL & 0x1F); u32 nextIndex = (js.next_inst.SPRU << 5) | (js.next_inst.SPRL & 0x1F);
// Be careful; the actual opcode is for mftb (371), not mfspr (339) // Be careful; the actual opcode is for mftb (371), not mfspr (339)
if (js.next_inst.OPCD == 31 && js.next_inst.SUBOP10 == 371 && (nextIndex == SPR_TU || nextIndex == SPR_TL))
{
if (PowerPC::GetState() != PowerPC::CPU_STEPPING)
{
int n = js.next_inst.RD; int n = js.next_inst.RD;
if (js.next_inst.OPCD == 31 && js.next_inst.SUBOP10 == 371 && (nextIndex == SPR_TU || nextIndex == SPR_TL) &&
PowerPC::GetState() != PowerPC::CPU_STEPPING && n != d)
{
js.downcountAmount++; js.downcountAmount++;
js.skipnext = true; js.skipnext = true;
gpr.Lock(d, n); gpr.Lock(d, n);
@ -246,7 +243,6 @@ void Jit64::mfspr(UGeckoInstruction inst)
if (nextIndex == SPR_TU) if (nextIndex == SPR_TU)
MOV(32, gpr.R(n), R(RAX)); MOV(32, gpr.R(n), R(RAX));
} }
}
else else
{ {
gpr.Lock(d); gpr.Lock(d);