mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-27 02:06:01 +00:00
Avoid a copy if possible
This commit is contained in:
parent
9ef61df9b8
commit
631b3e5116
2 changed files with 48 additions and 14 deletions
src/Ryujinx.Cpu/LightningJit
|
@ -140,7 +140,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
bool isTail = false)
|
||||
{
|
||||
int tempRegister;
|
||||
int tempGuestAddress = 0;
|
||||
int tempGuestAddress = -1;
|
||||
|
||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
||||
|
||||
|
@ -157,15 +157,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
{
|
||||
asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
|
||||
|
||||
if (inlineLookup)
|
||||
if (inlineLookup && guestAddress.Value == 0)
|
||||
{
|
||||
// Might be overwritten. Move the address to a temp register.
|
||||
// X0 will be overwritten. Move the address to a temp register.
|
||||
tempGuestAddress = regAlloc.AllocateTempGprRegister();
|
||||
asm.Mov(Register(tempGuestAddress), guestAddress);
|
||||
}
|
||||
}
|
||||
|
||||
tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
|
||||
tempRegister = NextFreeRegister(1, tempGuestAddress);
|
||||
|
||||
if (!isTail)
|
||||
{
|
||||
|
@ -190,8 +190,12 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
{
|
||||
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||
|
||||
Operand indexReg = Register(3);
|
||||
guestAddress = Register(tempGuestAddress);
|
||||
Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
|
||||
|
||||
if (tempGuestAddress != -1)
|
||||
{
|
||||
guestAddress = Register(tempGuestAddress);
|
||||
}
|
||||
|
||||
var level0 = funcTable.Levels[0];
|
||||
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
||||
|
@ -225,7 +229,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
// Load the final branch address
|
||||
asm.LdrRiUn(rn, rn, 0);
|
||||
|
||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||
if (tempGuestAddress != -1)
|
||||
{
|
||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -308,5 +315,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||
{
|
||||
return new Operand(type, (ulong)value);
|
||||
}
|
||||
|
||||
private static int NextFreeRegister(int start, int avoid)
|
||||
{
|
||||
if (start == avoid)
|
||||
{
|
||||
start++;
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -305,7 +305,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||
bool isTail = false)
|
||||
{
|
||||
int tempRegister;
|
||||
int tempGuestAddress = 0;
|
||||
int tempGuestAddress = -1;
|
||||
|
||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
||||
|
||||
|
@ -322,15 +322,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||
{
|
||||
asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
|
||||
|
||||
if (inlineLookup)
|
||||
if (inlineLookup && guestAddress.Value == 0)
|
||||
{
|
||||
// Might be overwritten. Move the address to a temp register.
|
||||
// X0 will be overwritten. Move the address to a temp register.
|
||||
tempGuestAddress = regAlloc.AllocateTempGprRegister();
|
||||
asm.Mov(Register(tempGuestAddress), guestAddress);
|
||||
}
|
||||
}
|
||||
|
||||
tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
|
||||
tempRegister = NextFreeRegister(1, tempGuestAddress);
|
||||
|
||||
if (!isTail)
|
||||
{
|
||||
|
@ -355,8 +355,12 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||
{
|
||||
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||
|
||||
Operand indexReg = Register(3);
|
||||
guestAddress = Register(tempGuestAddress);
|
||||
Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
|
||||
|
||||
if (tempGuestAddress != -1)
|
||||
{
|
||||
guestAddress = Register(tempGuestAddress);
|
||||
}
|
||||
|
||||
var level0 = funcTable.Levels[0];
|
||||
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
||||
|
@ -390,7 +394,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||
// Load the final branch address
|
||||
asm.LdrRiUn(rn, rn, 0);
|
||||
|
||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||
if (tempGuestAddress != -1)
|
||||
{
|
||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -669,5 +676,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||
{
|
||||
return new Operand(type, (ulong)value);
|
||||
}
|
||||
|
||||
private static int NextFreeRegister(int start, int avoid)
|
||||
{
|
||||
if (start == avoid)
|
||||
{
|
||||
start++;
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue