Jit sparse continuation #250
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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";
|
||||||
|
@ -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,6 +339,9 @@ namespace ARMeilleure.Common
|
|||||||
{
|
{
|
||||||
if (_table == null)
|
if (_table == null)
|
||||||
{
|
{
|
||||||
|
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);
|
_table = (TEntry**)Allocate(1 << Levels[0].Length, GetFillValue(0), leaf: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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];
|
||||||
var level1 = funcTable.Levels[1];
|
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
||||||
asm.Ubfx(indexReg, guestAddress, level1.Index, level1.Length);
|
|
||||||
asm.Lsl(indexReg, indexReg, Const(3));
|
asm.Lsl(indexReg, indexReg, Const(3));
|
||||||
|
|
||||||
// Index into the page.
|
// Index into the page.
|
||||||
asm.Add(rn, rn, indexReg);
|
asm.Add(rn, rn, indexReg);
|
||||||
|
|
||||||
// Load the final branch address
|
// Load the page address.
|
||||||
asm.LdrRiUn(rn, rn, 0);
|
asm.LdrRiUn(rn, rn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (tempGuestAddress != -1)
|
if (tempGuestAddress != -1)
|
||||||
{
|
{
|
||||||
|
@ -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];
|
||||||
var level1 = funcTable.Levels[1];
|
asm.Ubfx(indexReg, guestAddress, level.Index, level.Length);
|
||||||
asm.Ubfx(indexReg, guestAddress, level1.Index, level1.Length);
|
|
||||||
asm.Lsl(indexReg, indexReg, Const(3));
|
asm.Lsl(indexReg, indexReg, Const(3));
|
||||||
|
|
||||||
// Index into the page.
|
// Index into the page.
|
||||||
asm.Add(rn, rn, indexReg);
|
asm.Add(rn, rn, indexReg);
|
||||||
|
|
||||||
// Load the final branch address
|
// Load the page address.
|
||||||
asm.LdrRiUn(rn, rn, 0);
|
asm.LdrRiUn(rn, rn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (tempGuestAddress != -1)
|
if (tempGuestAddress != -1)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user