Avoid a copy if possible
This commit is contained in:
parent
9ef61df9b8
commit
631b3e5116
2 changed files with 48 additions and 14 deletions
|
@ -140,7 +140,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
bool isTail = false)
|
bool isTail = false)
|
||||||
{
|
{
|
||||||
int tempRegister;
|
int tempRegister;
|
||||||
int tempGuestAddress = 0;
|
int tempGuestAddress = -1;
|
||||||
|
|
||||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
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);
|
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();
|
tempGuestAddress = regAlloc.AllocateTempGprRegister();
|
||||||
asm.Mov(Register(tempGuestAddress), guestAddress);
|
asm.Mov(Register(tempGuestAddress), guestAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
|
tempRegister = NextFreeRegister(1, tempGuestAddress);
|
||||||
|
|
||||||
if (!isTail)
|
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.
|
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||||
|
|
||||||
Operand indexReg = Register(3);
|
Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
|
||||||
guestAddress = Register(tempGuestAddress);
|
|
||||||
|
if (tempGuestAddress != -1)
|
||||||
|
{
|
||||||
|
guestAddress = Register(tempGuestAddress);
|
||||||
|
}
|
||||||
|
|
||||||
var level0 = funcTable.Levels[0];
|
var level0 = funcTable.Levels[0];
|
||||||
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
||||||
|
@ -225,7 +229,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
// Load the final branch address
|
// Load the final branch address
|
||||||
asm.LdrRiUn(rn, rn, 0);
|
asm.LdrRiUn(rn, rn, 0);
|
||||||
|
|
||||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
if (tempGuestAddress != -1)
|
||||||
|
{
|
||||||
|
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -308,5 +315,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
||||||
{
|
{
|
||||||
return new Operand(type, (ulong)value);
|
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)
|
bool isTail = false)
|
||||||
{
|
{
|
||||||
int tempRegister;
|
int tempRegister;
|
||||||
int tempGuestAddress = 0;
|
int tempGuestAddress = -1;
|
||||||
|
|
||||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant && funcTable != null && funcTable.Levels.Length == 2;
|
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);
|
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();
|
tempGuestAddress = regAlloc.AllocateTempGprRegister();
|
||||||
asm.Mov(Register(tempGuestAddress), guestAddress);
|
asm.Mov(Register(tempGuestAddress), guestAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
|
tempRegister = NextFreeRegister(1, tempGuestAddress);
|
||||||
|
|
||||||
if (!isTail)
|
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.
|
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
|
||||||
|
|
||||||
Operand indexReg = Register(3);
|
Operand indexReg = Register(NextFreeRegister(tempRegister + 1, tempGuestAddress));
|
||||||
guestAddress = Register(tempGuestAddress);
|
|
||||||
|
if (tempGuestAddress != -1)
|
||||||
|
{
|
||||||
|
guestAddress = Register(tempGuestAddress);
|
||||||
|
}
|
||||||
|
|
||||||
var level0 = funcTable.Levels[0];
|
var level0 = funcTable.Levels[0];
|
||||||
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
|
||||||
|
@ -390,7 +394,10 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
||||||
// Load the final branch address
|
// Load the final branch address
|
||||||
asm.LdrRiUn(rn, rn, 0);
|
asm.LdrRiUn(rn, rn, 0);
|
||||||
|
|
||||||
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
if (tempGuestAddress != -1)
|
||||||
|
{
|
||||||
|
regAlloc.FreeTempGprRegister(tempGuestAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -669,5 +676,15 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
||||||
{
|
{
|
||||||
return new Operand(type, (ulong)value);
|
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