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), new( 1, 6),
}; };
private static readonly AddressTableLevel[] _levels64BitSparse = private static readonly AddressTableLevel[] _levels64BitSparseTiny =
new AddressTableLevel[] new AddressTableLevel[]
{ {
new(23, 16), new( 11, 28),
new( 2, 21), new( 2, 9),
}; };
private static readonly AddressTableLevel[] _levels32BitSparse = private static readonly AddressTableLevel[] _levels32BitSparseTiny =
new AddressTableLevel[] new AddressTableLevel[]
{ {
new(22, 10), new( 10, 22),
new( 1, 21), new( 1, 9),
}; };
public static AddressTableLevel[] GetArmPreset(bool for64Bits, bool sparse) public static AddressTableLevel[] GetArmPreset(bool for64Bits, bool sparse)
{ {
if (sparse) if (sparse)
{ {
return for64Bits ? _levels64BitSparse : _levels32BitSparse; return for64Bits ? _levels64BitSparseGiant : _levels32BitSparseGiant;
} }
else 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. // Inline table lookup. Only enabled when the sparse function table is enabled with 2 levels.
// Deliberately attempts to avoid branches. // 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 ? Operand tableBase = !context.HasPtc ?
Const(table.Base) : Const(table.Base) :
Const(table.Base, Ptc.FunctionTableSymbol); Const(table.Base, Ptc.FunctionTableSymbol);
Operand page = context.Load(OperandType.I64, context.Add(tableBase, index)); hostAddress = tableBase;
// Second level for (int i = 0; i < table.Levels.Length; i++)
var level1 = table.Levels[1]; {
int clearBits1 = 64 - (level1.Index + level1.Length); var level = table.Levels[i];
int clearBits = 64 - (level.Index + level.Length);
Operand index2 = context.ShiftLeft( Operand index = context.ShiftLeft(
context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits1)), Const(clearBits1 + level1.Index)), context.ShiftRightUI(context.ShiftLeft(guestAddress, Const(clearBits)), Const(clearBits + level.Index)),
Const(3) Const(3)
); );
hostAddress = context.Load(OperandType.I64, context.Add(page, index2)); hostAddress = context.Load(OperandType.I64, context.Add(hostAddress, index));
}
} }
else else
{ {

View File

@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\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 ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";

View File

@ -141,11 +141,6 @@ namespace ARMeilleure.Common
{ {
ArgumentNullException.ThrowIfNull(levels); 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); _pages = new List<AddressTablePage>(capacity: 16);
Levels = levels; Levels = levels;
@ -344,7 +339,10 @@ namespace ARMeilleure.Common
{ {
if (_table == null) 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; return _table;

View File

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

View File

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