Jit sparse continuation #250

Merged
LotP1 merged 13 commits from jit-sparse-continuation into master 2024-11-22 21:33:44 +00:00
6 changed files with 45 additions and 65 deletions
Showing only changes of commit aefaa9eeb8 - Show all commits

View File

@ -22,25 +22,25 @@ namespace ARMeilleure.Common
new( 1, 6),
};
private static readonly AddressTableLevel[] _levels64BitSparse =
private static readonly AddressTableLevel[] _levels64BitSparseTiny =
new AddressTableLevel[]
{
new(23, 16),
new( 2, 21),
new( 11, 28),
new( 2, 9),
};
private static readonly AddressTableLevel[] _levels32BitSparse =
private static readonly AddressTableLevel[] _levels32BitSparseTiny =
new AddressTableLevel[]
{
new(22, 10),
new( 1, 21),
new( 10, 22),
new( 1, 9),
};
public static AddressTableLevel[] GetArmPreset(bool for64Bits, bool sparse)
{
if (sparse)
{
return for64Bits ? _levels64BitSparse : _levels32BitSparse;
return for64Bits ? _levels64BitSparseGiant : _levels32BitSparseGiant;
}
else
{

View File

@ -210,30 +210,24 @@ namespace ARMeilleure.Instructions
// Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
// Deliberately attempts to avoid branches.
var level0 = table.Levels[0];
int clearBits0 = 64 - (level0.Index + level0.Length);
Operand index = context.ShiftLeft(
context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits0)), Const(clearBits0 + level0.Index)),
Const(3)
);
Operand tableBase = !context.HasPtc ?
Const(table.Base) :
Const(table.Base, Ptc.FunctionTableSymbol);
Operand page = context.Load(OperandType.I64, context.Add(tableBase, index));
hostAddress = tableBase;
// Second level
var level1 = table.Levels[1];
int clearBits1 = 64 - (level1.Index + level1.Length);
for (int i = 0; i < table.Levels.Length; i++)
{
var level = table.Levels[i];
int clearBits = 64 - (level.Index + level.Length);
Operand index2 = context.ShiftLeft(
context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits1)), Const(clearBits1 + level1.Index)),
Const(3)
);
Operand index = context.ShiftLeft(
context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits)), Const(clearBits + level.Index)),
Const(3)
);
hostAddress = context.Load(OperandType.I64, context.Add(page, index2));
hostAddress = context.Load(OperandType.I64, context.Add(hostAddress, index));
}
}
else
{

View File

@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 6978; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 6986; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";

View File

@ -141,11 +141,6 @@ namespace ARMeilleure.Common
{
ArgumentNullException.ThrowIfNull(levels);
if (levels.Length < 2)
{
throw new ArgumentException("Table must be at least 2 levels deep.", nameof(levels));
}
_pages = new List<AddressTablePage>(capacity: 16);
Levels = levels;
@ -344,7 +339,10 @@ namespace ARMeilleure.Common
{
if (_table == null)
{
_table = (TEntry**)Allocate(1 << Levels[0].Length, GetFillValue(0), leaf: false);
if (Levels.Length == 1)
_table = (TEntry**)Allocate(1 << Levels[0].Length, Fill, leaf: true);
else
_table = (TEntry**)Allocate(1 << Levels[0].Length, GetFillValue(0), leaf: false);
}
return _table;

View File

@ -143,8 +143,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
int tempGuestAddress = -1;
bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
funcTable is { Sparse: true } &&
funcTable.Levels.Length == 2;
funcTable is { Sparse: true };
if (guestAddress.Kind == OperandKind.Constant)
{
@ -199,28 +198,23 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
guestAddress = Register(tempGuestAddress);
}
var level0 = funcTable.Levels[0];
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
asm.Lsl(indexReg, indexReg, Const(3));
ulong tableBase = (ulong)funcTable.Base;
// Index into the table.
asm.Mov(rn, tableBase);
asm.Add(rn, rn, indexReg);
// Load the page address.
asm.LdrRiUn(rn, rn, 0);
for (int i = 0; i < funcTable.Levels.Length; i++)
{
var level = funcTable.Levels[i];
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
asm.Lsl(indexReg, indexReg, Const(3));
var level1 = funcTable.Levels[1];
asm.Ubfx(indexReg, guestAddress, level1.Index, level1.Length);
asm.Lsl(indexReg, indexReg, Const(3));
// Index into the page.
asm.Add(rn, rn, indexReg);
// Index into the page.
asm.Add(rn, rn, indexReg);
// Load the final branch address
asm.LdrRiUn(rn, rn, 0);
// Load the page address.
asm.LdrRiUn(rn, rn, 0);
}
if (tempGuestAddress != -1)
{

View File

@ -308,8 +308,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
int tempGuestAddress = -1;
bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
funcTable is { Sparse: true } &&
funcTable.Levels.Length == 2;
funcTable is { Sparse: true };
if (guestAddress.Kind == OperandKind.Constant)
{
@ -364,28 +363,23 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
guestAddress = Register(tempGuestAddress);
}
var level0 = funcTable.Levels[0];
asm.Ubfx(indexReg, guestAddress, level0.Index, level0.Length);
asm.Lsl(indexReg, indexReg, Const(3));
ulong tableBase = (ulong)funcTable.Base;
// Index into the table.
asm.Mov(rn, tableBase);
asm.Add(rn, rn, indexReg);
// Load the page address.
asm.LdrRiUn(rn, rn, 0);
for (int i = 0; i < funcTable.Levels.Length; i++)
{
var level = funcTable.Levels[i];
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
asm.Lsl(indexReg, indexReg, Const(3));
var level1 = funcTable.Levels[1];
asm.Ubfx(indexReg, guestAddress, level1.Index, level1.Length);
asm.Lsl(indexReg, indexReg, Const(3));
// Index into the page.
asm.Add(rn, rn, indexReg);
// Index into the page.
asm.Add(rn, rn, indexReg);
// Load the final branch address
asm.LdrRiUn(rn, rn, 0);
// Load the page address.
asm.LdrRiUn(rn, rn, 0);
}
if (tempGuestAddress != -1)
{