diff options
| author | Fiora <fioraaeterna@gmail.com> | 2014-10-19 04:53:01 -0700 |
|---|---|---|
| committer | Fiora <fioraaeterna@gmail.com> | 2014-10-29 00:30:26 -0700 |
| commit | a666bb6bf679081cfe40a90f604e8517b5d806da (patch) | |
| tree | 85aa78b7581b15c7a55d6e627461613831acfc0c /Source/Core | |
| parent | 5b5e46220070130f49aacd52f59e4fa564883142 (diff) | |
JIT: optimize mulhwu
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index 5ec9ef15a2..d78e0a5bc3 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1017,20 +1017,30 @@ void Jit64::mulhwXx(UGeckoInstruction inst) else gpr.SetImmediate32(d, (u32)((gpr.R(a).offset * gpr.R(b).offset) >> 32)); } - else + else if (sign) { gpr.Lock(a, b, d); // no register choice gpr.FlushLockX(EDX, EAX); - gpr.BindToRegister(d, (d == a || d == b), true); + gpr.BindToRegister(d, d == a || d == b, true); MOV(32, R(EAX), gpr.R(a)); gpr.KillImmediate(b, true, false); - if (sign) - IMUL(32, gpr.R(b)); - else - MUL(32, gpr.R(b)); + IMUL(32, gpr.R(b)); MOV(32, gpr.R(d), R(EDX)); } + else + { + // Not faster for signed because we'd need two movsx. + gpr.Lock(a, b, d); + // We need to bind everything to registers since the top 32 bits need to be zero. + int src = d == b ? a : b; + gpr.BindToRegister(d, d == a || d == b, true); + gpr.BindToRegister(src, true, false); + if (d != a && d != b) + MOV(32, gpr.R(d), gpr.R(a)); + IMUL(64, gpr.RX(d), gpr.R(src)); + SHR(64, gpr.R(d), Imm8(32)); + } if (inst.Rc) ComputeRC(gpr.R(d)); gpr.UnlockAll(); |
