diff options
| author | Fiora <fioraaeterna@gmail.com> | 2014-08-20 00:42:04 -0700 |
|---|---|---|
| committer | Fiora <fioraaeterna@gmail.com> | 2014-09-02 21:49:24 -0700 |
| commit | 6875d911f11ae8a3fee8f8fdc34844d9bc5c2018 (patch) | |
| tree | ac7a2be59eb985816357ec749383970cc95c6e10 /Source/Core | |
| parent | 816d056657885e869a1bd550a88fe92e52533d92 (diff) | |
JIT: merge paired timebase reads where possible
Combined with the previous patch, ~1% faster overall on F-Zero GX.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp index 3005970453..af2fe33bb8 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -182,11 +182,33 @@ void Jit64::mfspr(UGeckoInstruction inst) if (offset > 0) ADD(64, R(RAX), Imm32(offset)); MOV(64, M(&TL), R(RAX)); - gpr.Lock(d); - gpr.BindToRegister(d, false); - if (iIndex == SPR_TU) + // Two calls of TU/TL next to each other are extremely common in typical usage, so merge them + // if we can. + u32 nextIndex = (js.next_inst.SPRU << 5) | (js.next_inst.SPRL & 0x1F); + // 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)) + { + int n = js.next_inst.RD; + js.downcountAmount++; + js.skipnext = true; + gpr.Lock(d, n); + if (iIndex == SPR_TL) + MOV(32, gpr.R(d), R(EAX)); + if (nextIndex == SPR_TL) + MOV(32, gpr.R(n), R(EAX)); SHR(64, R(RAX), Imm8(32)); - MOV(32, gpr.R(d), R(EAX)); + if (iIndex == SPR_TU) + MOV(32, gpr.R(d), R(EAX)); + if (nextIndex == SPR_TU) + MOV(32, gpr.R(n), R(EAX)); + } + else + { + gpr.Lock(d); + if (iIndex == SPR_TU) + SHR(64, R(RAX), Imm8(32)); + MOV(32, gpr.R(d), R(EAX)); + } break; } case SPR_WPAR: |
