Jit64: slwx - Optimize shift by constant
More efficient code can be generated if the shift amount is known at compile time. Similar optimizations were present in JitArm64 already, but were missing in Jit64. - By using an 8-bit immediate we can eliminate the need for ECX as a scratch register, thereby reducing register pressure and occasionally eliminating a spill. Before: B9 18 00 00 00 mov ecx,18h 41 8B F7 mov esi,r15d 48 D3 E6 shl rsi,cl 8B F6 mov esi,esi After: 41 8B CF mov ecx,r15d C1 E1 18 shl ecx,18h - PowerPC has strange shift amount masking behavior which is emulated using 64-bit shifts, even though we only care about a 32-bit result. If the shift amount is known, we can handle this special case separately, and use 32-bit shift instructions otherwise. We also no longer need to clear the upper 32 bits of the register. Before: BE F8 FF FF FF mov esi,0FFFFFFF8h 8B CE mov ecx,esi 41 8B F4 mov esi,r12d 48 D3 E6 shl rsi,cl 8B F6 mov esi,esi After: Nothing, register is set to constant zero. - A shift by zero becomes a simple MOV. Before: BE 00 00 00 00 mov esi,0 8B CE mov ecx,esi 41 8B F3 mov esi,r11d 48 D3 E6 shl rsi,cl 8B F6 mov esi,esi After: 41 8B FB mov edi,r11d
This commit is contained in:
parent
17db359979
commit
17dc870847
|
@ -1849,6 +1849,30 @@ void Jit64::slwx(UGeckoInstruction inst)
|
|||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
else if (gpr.IsImm(b))
|
||||
{
|
||||
u32 amount = gpr.Imm32(b);
|
||||
if (amount & 0x20)
|
||||
{
|
||||
gpr.SetImmediate32(a, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
|
||||
RCOpArg Rs = gpr.Use(s, RCMode::Read);
|
||||
RegCache::Realize(Ra, Rs);
|
||||
|
||||
if (a != s)
|
||||
MOV(32, Ra, Rs);
|
||||
|
||||
amount &= 0x1f;
|
||||
if (amount != 0)
|
||||
SHL(32, Ra, Imm8(amount));
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
RCX64Reg ecx = gpr.Scratch(ECX); // no register choice
|
||||
|
|
Loading…
Reference in New Issue