mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-25 02:00:17 +00:00
* Implement a new JIT for Arm devices * Auto-format * Make a lot of Assembler members read-only * More read-only * Fix more warnings * ObjectDisposedException.ThrowIf * New JIT cache for platforms that enforce W^X, currently unused * Remove unused using * Fix assert * Pass memory manager type around * Safe memory manager mode support + other improvements * Actual safe memory manager mode masking support * PR feedback
67 lines
2.6 KiB
C#
67 lines
2.6 KiB
C#
using System.Numerics;
|
|
|
|
namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|
{
|
|
static class CodeGenCommon
|
|
{
|
|
public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR)
|
|
{
|
|
return TryEncodeBitMask(operand.Type, operand.Value, out immN, out immS, out immR);
|
|
}
|
|
|
|
public static bool TryEncodeBitMask(OperandType type, ulong value, out int immN, out int immS, out int immR)
|
|
{
|
|
if (type == OperandType.I32)
|
|
{
|
|
value &= uint.MaxValue;
|
|
value |= value << 32;
|
|
}
|
|
|
|
return TryEncodeBitMask(value, out immN, out immS, out immR);
|
|
}
|
|
|
|
public static bool TryEncodeBitMask(ulong value, out int immN, out int immS, out int immR)
|
|
{
|
|
// Some special values also can't be encoded:
|
|
// 0 can't be encoded because we need to subtract 1 from onesCount (which would became negative if 0).
|
|
// A value with all bits set can't be encoded because it is reserved according to the spec, because:
|
|
// Any value AND all ones will be equal itself, so it's effectively a no-op.
|
|
// Any value OR all ones will be equal all ones, so one can just use MOV.
|
|
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
|
|
if (value == 0 || value == ulong.MaxValue)
|
|
{
|
|
immN = 0;
|
|
immS = 0;
|
|
immR = 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
// Normalize value, rotating it such that the LSB is 1: Ensures we get a complete element that has not
|
|
// been cut-in-half across the word boundary.
|
|
int rotation = BitOperations.TrailingZeroCount(value & (value + 1));
|
|
ulong rotatedValue = ulong.RotateRight(value, rotation);
|
|
|
|
// Now that we have a complete element in the LSB with the LSB = 1, determine size and number of ones
|
|
// in element.
|
|
int elementSize = BitOperations.TrailingZeroCount(rotatedValue & (rotatedValue + 1));
|
|
int onesInElement = BitOperations.TrailingZeroCount(~rotatedValue);
|
|
|
|
// Check the value is repeating; also ensures element size is a power of two.
|
|
if (ulong.RotateRight(value, elementSize) != value)
|
|
{
|
|
immN = 0;
|
|
immS = 0;
|
|
immR = 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
immN = (elementSize >> 6) & 1;
|
|
immS = (((~elementSize + 1) << 1) | (onesInElement - 1)) & 0x3f;
|
|
immR = (elementSize - rotation) & (elementSize - 1);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|