diff --git a/src/ARMeilleure/Common/AddressTable.cs b/src/ARMeilleure/Common/AddressTable.cs
index c9b0062b..fcab3a20 100644
--- a/src/ARMeilleure/Common/AddressTable.cs
+++ b/src/ARMeilleure/Common/AddressTable.cs
@@ -9,7 +9,7 @@ namespace ARMeilleure.Common
/// Represents a table of guest address to a value.
///
/// Type of the value
- unsafe class AddressTable : IDisposable where TEntry : unmanaged
+ public unsafe class AddressTable : IDisposable where TEntry : unmanaged
{
///
/// Represents a level in an .
diff --git a/src/ARMeilleure/Memory/IJitMemoryBlock.cs b/src/ARMeilleure/Memory/IJitMemoryBlock.cs
index cd49f314..c103fe8d 100644
--- a/src/ARMeilleure/Memory/IJitMemoryBlock.cs
+++ b/src/ARMeilleure/Memory/IJitMemoryBlock.cs
@@ -8,6 +8,7 @@ namespace ARMeilleure.Memory
void Commit(ulong offset, ulong size);
+ void MapAsRw(ulong offset, ulong size);
void MapAsRx(ulong offset, ulong size);
void MapAsRwx(ulong offset, ulong size);
}
diff --git a/src/ARMeilleure/Memory/ReservedRegion.cs b/src/ARMeilleure/Memory/ReservedRegion.cs
index d0ffa8f1..3870d4c8 100644
--- a/src/ARMeilleure/Memory/ReservedRegion.cs
+++ b/src/ARMeilleure/Memory/ReservedRegion.cs
@@ -2,7 +2,7 @@ using System;
namespace ARMeilleure.Memory
{
- class ReservedRegion
+ public class ReservedRegion
{
public const int DefaultGranularity = 65536; // Mapping granularity in Windows.
diff --git a/src/ARMeilleure/Native/JitSupportDarwin.cs b/src/ARMeilleure/Native/JitSupportDarwin.cs
index ed347b9c..33946039 100644
--- a/src/ARMeilleure/Native/JitSupportDarwin.cs
+++ b/src/ARMeilleure/Native/JitSupportDarwin.cs
@@ -5,7 +5,7 @@ using System.Runtime.Versioning;
namespace ARMeilleure.Native
{
[SupportedOSPlatform("macos")]
- internal static partial class JitSupportDarwin
+ static partial class JitSupportDarwin
{
[LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")]
public static partial void Copy(IntPtr dst, IntPtr src, ulong n);
diff --git a/src/ARMeilleure/Translation/IntervalTree.cs b/src/ARMeilleure/Translation/IntervalTree.cs
index da29d6a6..a5f9b5d5 100644
--- a/src/ARMeilleure/Translation/IntervalTree.cs
+++ b/src/ARMeilleure/Translation/IntervalTree.cs
@@ -8,7 +8,7 @@ namespace ARMeilleure.Translation
///
/// Key
/// Value
- class IntervalTree where TK : IComparable
+ public class IntervalTree where TK : IComparable
{
private const int ArrayGrowthSize = 32;
diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs
index 48c1a575..014b1203 100644
--- a/src/ARMeilleure/Translation/Translator.cs
+++ b/src/ARMeilleure/Translation/Translator.cs
@@ -73,7 +73,7 @@ namespace ARMeilleure.Translation
CountTable = new EntryTable();
Functions = new TranslatorCache();
FunctionTable = new AddressTable(for64Bits ? _levels64Bit : _levels32Bit);
- Stubs = new TranslatorStubs(this);
+ Stubs = new TranslatorStubs(FunctionTable);
FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
}
diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs
index bbe48c16..d80823a8 100644
--- a/src/ARMeilleure/Translation/TranslatorStubs.cs
+++ b/src/ARMeilleure/Translation/TranslatorStubs.cs
@@ -1,3 +1,4 @@
+using ARMeilleure.Common;
using ARMeilleure.Instructions;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.State;
@@ -14,11 +15,11 @@ namespace ARMeilleure.Translation
///
class TranslatorStubs : IDisposable
{
- private static readonly Lazy _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
+ private readonly Lazy _slowDispatchStub;
private bool _disposed;
- private readonly Translator _translator;
+ private readonly AddressTable _functionTable;
private readonly Lazy _dispatchStub;
private readonly Lazy _dispatchLoop;
private readonly Lazy _contextWrapper;
@@ -83,13 +84,14 @@ namespace ARMeilleure.Translation
/// Initializes a new instance of the class with the specified
/// instance.
///
- /// instance to use
+ /// Function table used to store pointers to the functions that the guest code will call
/// is null
- public TranslatorStubs(Translator translator)
+ public TranslatorStubs(AddressTable functionTable)
{
- ArgumentNullException.ThrowIfNull(translator);
+ ArgumentNullException.ThrowIfNull(functionTable);
- _translator = translator;
+ _functionTable = functionTable;
+ _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
_dispatchStub = new(GenerateDispatchStub, isThreadSafe: true);
_dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true);
_contextWrapper = new(GenerateContextWrapper, isThreadSafe: true);
@@ -151,15 +153,15 @@ namespace ARMeilleure.Translation
context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())));
// Check if guest address is within range of the AddressTable.
- Operand masked = context.BitwiseAnd(guestAddress, Const(~_translator.FunctionTable.Mask));
+ Operand masked = context.BitwiseAnd(guestAddress, Const(~_functionTable.Mask));
context.BranchIfTrue(lblFallback, masked);
Operand index = default;
- Operand page = Const((long)_translator.FunctionTable.Base);
+ Operand page = Const((long)_functionTable.Base);
- for (int i = 0; i < _translator.FunctionTable.Levels.Length; i++)
+ for (int i = 0; i < _functionTable.Levels.Length; i++)
{
- ref var level = ref _translator.FunctionTable.Levels[i];
+ ref var level = ref _functionTable.Levels[i];
// level.Mask is not used directly because it is more often bigger than 32-bits, so it will not
// be encoded as an immediate on x86's bitwise and operation.
@@ -167,7 +169,7 @@ namespace ARMeilleure.Translation
index = context.BitwiseAnd(context.ShiftRightUI(guestAddress, Const(level.Index)), mask);
- if (i < _translator.FunctionTable.Levels.Length - 1)
+ if (i < _functionTable.Levels.Length - 1)
{
page = context.Load(OperandType.I64, context.Add(page, context.ShiftLeft(index, Const(3))));
context.BranchIfFalse(lblFallback, page);
@@ -196,7 +198,7 @@ namespace ARMeilleure.Translation
/// Generates a .
///
/// Generated
- private static IntPtr GenerateSlowDispatchStub()
+ private IntPtr GenerateSlowDispatchStub()
{
var context = new EmitterContext();
@@ -205,8 +207,7 @@ namespace ARMeilleure.Translation
Operand guestAddress = context.Load(OperandType.I64,
context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())));
- MethodInfo getFuncAddress = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress));
- Operand hostAddress = context.Call(getFuncAddress, guestAddress);
+ Operand hostAddress = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress)), guestAddress);
context.Tailcall(hostAddress, nativeContext);
var cfg = context.GetControlFlowGraph();
diff --git a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
index 2c4ff2b6..99e4c047 100644
--- a/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
+++ b/src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs
@@ -40,5 +40,9 @@ namespace Ryujinx.Cpu.AppleHv
public void PrepareCodeRange(ulong address, ulong size)
{
}
+
+ public void Dispose()
+ {
+ }
}
}
diff --git a/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs b/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs
new file mode 100644
index 00000000..d050bdde
--- /dev/null
+++ b/src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Ryujinx.Cpu
+{
+ public class DummyDiskCacheLoadState : IDiskCacheLoadState
+ {
+#pragma warning disable CS0067 // The event is never used
+ ///
+ public event Action StateChanged;
+#pragma warning restore CS0067
+
+ ///
+ public void Cancel()
+ {
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/ICpuContext.cs b/src/Ryujinx.Cpu/ICpuContext.cs
index 80916d1c..edcebdfc 100644
--- a/src/Ryujinx.Cpu/ICpuContext.cs
+++ b/src/Ryujinx.Cpu/ICpuContext.cs
@@ -1,9 +1,11 @@
+using System;
+
namespace Ryujinx.Cpu
{
///
/// CPU context interface.
///
- public interface ICpuContext
+ public interface ICpuContext : IDisposable
{
///
/// Creates a new execution context that will store thread CPU register state when executing guest code.
diff --git a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
index 5876346a..dce0490a 100644
--- a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
+++ b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs
@@ -13,7 +13,7 @@ namespace Ryujinx.Cpu.Jit
public JitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
{
_tickSource = tickSource;
- _translator = new Translator(new JitMemoryAllocator(), memory, for64Bit);
+ _translator = new Translator(new JitMemoryAllocator(forJit: true), memory, for64Bit);
if (memory.Type.IsHostMapped())
{
@@ -57,5 +57,9 @@ namespace Ryujinx.Cpu.Jit
{
_translator.PrepareCodeRange(address, size);
}
+
+ public void Dispose()
+ {
+ }
}
}
diff --git a/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs b/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs
index eb665c2d..06c11b7b 100644
--- a/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs
+++ b/src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs
@@ -5,7 +5,14 @@ namespace Ryujinx.Cpu.Jit
{
public class JitMemoryAllocator : IJitMemoryAllocator
{
+ private readonly MemoryAllocationFlags _jitFlag;
+
+ public JitMemoryAllocator(bool forJit = false)
+ {
+ _jitFlag = forJit ? MemoryAllocationFlags.Jit : MemoryAllocationFlags.None;
+ }
+
public IJitMemoryBlock Allocate(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.None);
- public IJitMemoryBlock Reserve(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.Jit);
+ public IJitMemoryBlock Reserve(ulong size) => new JitMemoryBlock(size, MemoryAllocationFlags.Reserve | _jitFlag);
}
}
diff --git a/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs b/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs
index bcacd116..bd07d349 100644
--- a/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs
+++ b/src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs
@@ -16,6 +16,7 @@ namespace Ryujinx.Cpu.Jit
}
public void Commit(ulong offset, ulong size) => _impl.Commit(offset, size);
+ public void MapAsRw(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndWrite);
public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute);
public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute);
diff --git a/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs
new file mode 100644
index 00000000..ee4fc439
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs
@@ -0,0 +1,32 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.Arm32;
+using Ryujinx.Cpu.LightningJit.Arm64;
+using Ryujinx.Cpu.LightningJit.State;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+ class AarchCompiler
+ {
+ public static CompiledFunction Compile(
+ CpuPreset cpuPreset,
+ IMemoryManager memoryManager,
+ ulong address,
+ AddressTable funcTable,
+ IntPtr dispatchStubPtr,
+ ExecutionMode executionMode,
+ Architecture targetArch)
+ {
+ if (executionMode == ExecutionMode.Aarch64)
+ {
+ return A64Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, targetArch);
+ }
+ else
+ {
+ return A32Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, executionMode == ExecutionMode.Aarch32Thumb, targetArch);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/AddressForm.cs b/src/Ryujinx.Cpu/LightningJit/AddressForm.cs
new file mode 100644
index 00000000..a9ad7e8a
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/AddressForm.cs
@@ -0,0 +1,18 @@
+
+namespace Ryujinx.Cpu.LightningJit
+{
+ enum AddressForm : byte
+ {
+ None,
+ OffsetReg,
+ PostIndexed,
+ PreIndexed,
+ SignedScaled,
+ UnsignedScaled,
+ BaseRegister,
+ BasePlusOffset,
+ Literal,
+ StructNoOffset,
+ StructPostIndexedReg,
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs
new file mode 100644
index 00000000..7f6024d4
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs
@@ -0,0 +1,30 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class A32Compiler
+ {
+ public static CompiledFunction Compile(
+ CpuPreset cpuPreset,
+ IMemoryManager memoryManager,
+ ulong address,
+ AddressTable funcTable,
+ IntPtr dispatchStubPtr,
+ bool isThumb,
+ Architecture targetArch)
+ {
+ if (targetArch == Architecture.Arm64)
+ {
+ return Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr, isThumb);
+ }
+ else
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs
new file mode 100644
index 00000000..4729f694
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs
@@ -0,0 +1,101 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ class Block
+ {
+ public readonly ulong Address;
+ public readonly ulong EndAddress;
+ public readonly List Instructions;
+ public readonly bool EndsWithBranch;
+ public readonly bool HasHostCall;
+ public readonly bool IsTruncated;
+ public readonly bool IsLoopEnd;
+ public readonly bool IsThumb;
+
+ public Block(
+ ulong address,
+ ulong endAddress,
+ List instructions,
+ bool endsWithBranch,
+ bool hasHostCall,
+ bool isTruncated,
+ bool isLoopEnd,
+ bool isThumb)
+ {
+ Debug.Assert(isThumb || (int)((endAddress - address) / 4) == instructions.Count);
+
+ Address = address;
+ EndAddress = endAddress;
+ Instructions = instructions;
+ EndsWithBranch = endsWithBranch;
+ HasHostCall = hasHostCall;
+ IsTruncated = isTruncated;
+ IsLoopEnd = isLoopEnd;
+ IsThumb = isThumb;
+ }
+
+ public (Block, Block) SplitAtAddress(ulong address)
+ {
+ int splitIndex = FindSplitIndex(address);
+
+ if (splitIndex < 0)
+ {
+ return (null, null);
+ }
+
+ int splitCount = Instructions.Count - splitIndex;
+
+ // Technically those are valid, but we don't want to create empty blocks.
+ Debug.Assert(splitIndex != 0);
+ Debug.Assert(splitCount != 0);
+
+ Block leftBlock = new(
+ Address,
+ address,
+ Instructions.GetRange(0, splitIndex),
+ false,
+ HasHostCall,
+ false,
+ false,
+ IsThumb);
+
+ Block rightBlock = new(
+ address,
+ EndAddress,
+ Instructions.GetRange(splitIndex, splitCount),
+ EndsWithBranch,
+ HasHostCall,
+ IsTruncated,
+ IsLoopEnd,
+ IsThumb);
+
+ return (leftBlock, rightBlock);
+ }
+
+ private int FindSplitIndex(ulong address)
+ {
+ if (IsThumb)
+ {
+ ulong pc = Address;
+
+ for (int index = 0; index < Instructions.Count; index++)
+ {
+ if (pc == address)
+ {
+ return index;
+ }
+
+ pc += Instructions[index].Flags.HasFlag(InstFlags.Thumb16) ? 2UL : 4UL;
+ }
+
+ return -1;
+ }
+ else
+ {
+ return (int)((address - Address) / 4);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs
new file mode 100644
index 00000000..6d9fdf2c
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ enum BranchType
+ {
+ Branch,
+ Call,
+ IndirectBranch,
+ TableBranchByte,
+ TableBranchHalfword,
+ IndirectCall,
+ SyncPoint,
+ SoftwareInterrupt,
+ ReadCntpct,
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs
new file mode 100644
index 00000000..f55e2bb9
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs
@@ -0,0 +1,198 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ class CodeGenContext
+ {
+ public CodeWriter CodeWriter { get; }
+ public Assembler Arm64Assembler { get; }
+ public RegisterAllocator RegisterAllocator { get; }
+
+ public MemoryManagerType MemoryManagerType { get; }
+
+ private uint _instructionAddress;
+
+ public bool IsThumb { get; }
+ public uint Pc { get; private set; }
+ public bool InITBlock { get; private set; }
+
+ private InstInfo _nextInstruction;
+ private bool _skipNextInstruction;
+
+ private readonly ArmCondition[] _itConditions;
+ private int _itCount;
+
+ private readonly List _pendingBranches;
+
+ private bool _nzcvModified;
+
+ public CodeGenContext(CodeWriter codeWriter, Assembler arm64Assembler, RegisterAllocator registerAllocator, MemoryManagerType mmType, bool isThumb)
+ {
+ CodeWriter = codeWriter;
+ Arm64Assembler = arm64Assembler;
+ RegisterAllocator = registerAllocator;
+ MemoryManagerType = mmType;
+ _itConditions = new ArmCondition[4];
+ _pendingBranches = new();
+ IsThumb = isThumb;
+ }
+
+ public void SetPc(uint address)
+ {
+ // Due to historical reasons, the PC value is always 2 instructions ahead on 32-bit Arm CPUs.
+ Pc = address + (IsThumb ? 4u : 8u);
+ _instructionAddress = address;
+ }
+
+ public void SetNextInstruction(InstInfo info)
+ {
+ _nextInstruction = info;
+ }
+
+ public InstInfo PeekNextInstruction()
+ {
+ return _nextInstruction;
+ }
+
+ public void SetSkipNextInstruction()
+ {
+ _skipNextInstruction = true;
+ }
+
+ public bool ConsumeSkipNextInstruction()
+ {
+ bool skip = _skipNextInstruction;
+ _skipNextInstruction = false;
+
+ return skip;
+ }
+
+ public void AddPendingBranch(InstName name, int offset)
+ {
+ _pendingBranches.Add(new(BranchType.Branch, Pc + (uint)offset, 0u, name, CodeWriter.InstructionPointer));
+ }
+
+ public void AddPendingCall(uint targetAddress, uint nextAddress)
+ {
+ _pendingBranches.Add(new(BranchType.Call, targetAddress, nextAddress, InstName.BlI, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ RegisterAllocator.MarkGprAsUsed(RegisterUtils.LrRegister);
+ }
+
+ public void AddPendingIndirectBranch(InstName name, uint targetRegister)
+ {
+ _pendingBranches.Add(new(BranchType.IndirectBranch, targetRegister, 0u, name, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.MarkGprAsUsed((int)targetRegister);
+ }
+
+ public void AddPendingTableBranch(uint rn, uint rm, bool halfword)
+ {
+ _pendingBranches.Add(new(halfword ? BranchType.TableBranchHalfword : BranchType.TableBranchByte, rn, rm, InstName.Tbb, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(2);
+ RegisterAllocator.MarkGprAsUsed((int)rn);
+ RegisterAllocator.MarkGprAsUsed((int)rm);
+ }
+
+ public void AddPendingIndirectCall(uint targetRegister, uint nextAddress)
+ {
+ _pendingBranches.Add(new(BranchType.IndirectCall, targetRegister, nextAddress, InstName.BlxR, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(targetRegister == RegisterUtils.LrRegister ? 1 : 0);
+ RegisterAllocator.MarkGprAsUsed((int)targetRegister);
+ RegisterAllocator.MarkGprAsUsed(RegisterUtils.LrRegister);
+ }
+
+ public void AddPendingSyncPoint()
+ {
+ _pendingBranches.Add(new(BranchType.SyncPoint, 0, 0, default, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ }
+
+ public void AddPendingBkpt(uint imm)
+ {
+ _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Bkpt, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ }
+
+ public void AddPendingSvc(uint imm)
+ {
+ _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Svc, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ }
+
+ public void AddPendingUdf(uint imm)
+ {
+ _pendingBranches.Add(new(BranchType.SoftwareInterrupt, imm, _instructionAddress, InstName.Udf, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ }
+
+ public void AddPendingReadCntpct(uint rt, uint rt2)
+ {
+ _pendingBranches.Add(new(BranchType.ReadCntpct, rt, rt2, InstName.Mrrc, CodeWriter.InstructionPointer));
+
+ RegisterAllocator.EnsureTempGprRegisters(1);
+ }
+
+ public IEnumerable GetPendingBranches()
+ {
+ return _pendingBranches;
+ }
+
+ public void SetItBlockStart(ReadOnlySpan conditions)
+ {
+ _itCount = conditions.Length;
+
+ for (int index = 0; index < conditions.Length; index++)
+ {
+ _itConditions[index] = conditions[index];
+ }
+
+ InITBlock = true;
+ }
+
+ public bool ConsumeItCondition(out ArmCondition condition)
+ {
+ if (_itCount != 0)
+ {
+ condition = _itConditions[--_itCount];
+
+ return true;
+ }
+
+ condition = ArmCondition.Al;
+
+ return false;
+ }
+
+ public void UpdateItState()
+ {
+ if (_itCount == 0)
+ {
+ InITBlock = false;
+ }
+ }
+
+ public void SetNzcvModified()
+ {
+ _nzcvModified = true;
+ }
+
+ public bool ConsumeNzcvModified()
+ {
+ bool modified = _nzcvModified;
+ _nzcvModified = false;
+
+ return modified;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs
new file mode 100644
index 00000000..e0a18e66
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs
@@ -0,0 +1,546 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class Decoder where T : IInstEmit
+ {
+ public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb)
+ {
+ List blocks = new();
+ List branchTargets = new();
+
+ while (true)
+ {
+ Block block = Decode(cpuPreset, memoryManager, address, isThumb);
+
+ if (!block.IsTruncated && TryGetBranchTarget(block, out ulong targetAddress))
+ {
+ branchTargets.Add(targetAddress);
+ }
+
+ blocks.Add(block);
+
+ if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets))
+ {
+ break;
+ }
+
+ address = block.EndAddress;
+ }
+
+ branchTargets.Sort();
+ SplitBlocks(blocks, branchTargets);
+
+ return new(blocks);
+ }
+
+ private static bool TryGetBranchTarget(Block block, out ulong targetAddress)
+ {
+ // PC is 2 instructions ahead, since the end address is already one instruction after the last one, we just need to add
+ // another instruction.
+
+ ulong pc = block.EndAddress + (block.IsThumb ? 2UL : 4UL);
+
+ return TryGetBranchTarget(block.Instructions[^1].Name, block.Instructions[^1].Flags, pc, block.Instructions[^1].Encoding, block.IsThumb, out targetAddress);
+ }
+
+ private static bool TryGetBranchTarget(InstName name, InstFlags flags, ulong pc, uint encoding, bool isThumb, out ulong targetAddress)
+ {
+ int originalOffset;
+
+ switch (name)
+ {
+ case InstName.B:
+ if (isThumb)
+ {
+ if (flags.HasFlag(InstFlags.Thumb16))
+ {
+ if ((encoding & (1u << 29)) != 0)
+ {
+ InstImm11b16w11 inst = new(encoding);
+
+ originalOffset = ImmUtils.ExtractT16SImm11Times2(inst.Imm11);
+ }
+ else
+ {
+ InstCondb24w4Imm8b16w8 inst = new(encoding);
+
+ originalOffset = ImmUtils.ExtractT16SImm8Times2(inst.Imm8);
+ }
+ }
+ else
+ {
+ if ((encoding & (1u << 12)) != 0)
+ {
+ InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding);
+
+ originalOffset = ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S);
+ }
+ else
+ {
+ InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11 inst = new(encoding);
+
+ originalOffset = ImmUtils.CombineSImm20Times2(inst.Imm11, inst.Imm6, inst.J1, inst.J2, inst.S);
+ }
+ }
+ }
+ else
+ {
+ originalOffset = ImmUtils.ExtractSImm24Times4(encoding);
+ }
+
+ targetAddress = pc + (ulong)originalOffset;
+ Debug.Assert((targetAddress & 1) == 0);
+
+ return true;
+
+ case InstName.Cbnz:
+ originalOffset = ImmUtils.ExtractT16UImm5Times2(encoding);
+ targetAddress = pc + (ulong)originalOffset;
+ Debug.Assert((targetAddress & 1) == 0);
+
+ return true;
+ }
+
+ targetAddress = 0;
+
+ return false;
+ }
+
+ private static void SplitBlocks(List blocks, List branchTargets)
+ {
+ int btIndex = 0;
+
+ while (btIndex < branchTargets.Count)
+ {
+ for (int blockIndex = 0; blockIndex < blocks.Count && btIndex < branchTargets.Count; blockIndex++)
+ {
+ Block block = blocks[blockIndex];
+ ulong currentBranchTarget = branchTargets[btIndex];
+
+ while (currentBranchTarget >= block.Address && currentBranchTarget < block.EndAddress)
+ {
+ if (block.Address != currentBranchTarget)
+ {
+ (Block leftBlock, Block rightBlock) = block.SplitAtAddress(currentBranchTarget);
+
+ if (leftBlock != null && rightBlock != null)
+ {
+ blocks.Insert(blockIndex, leftBlock);
+ blocks[blockIndex + 1] = rightBlock;
+
+ block = leftBlock;
+ }
+ else
+ {
+ // Split can only fail in thumb mode, where the instruction size is not fixed.
+
+ Debug.Assert(block.IsThumb);
+ }
+ }
+
+ btIndex++;
+
+ while (btIndex < branchTargets.Count && branchTargets[btIndex] == currentBranchTarget)
+ {
+ btIndex++;
+ }
+
+ if (btIndex >= branchTargets.Count)
+ {
+ break;
+ }
+
+ currentBranchTarget = branchTargets[btIndex];
+ }
+ }
+
+ Debug.Assert(btIndex < int.MaxValue);
+ btIndex++;
+ }
+ }
+
+ private static bool HasNextBlock(in Block block, ulong pc, List branchTargets)
+ {
+ InstFlags lastInstFlags = block.Instructions[^1].Flags;
+
+ // Thumb has separate encodings for conditional and unconditional branch instructions.
+ if (lastInstFlags.HasFlag(InstFlags.Cond) && (block.IsThumb || (ArmCondition)(block.Instructions[^1].Encoding >> 28) < ArmCondition.Al))
+ {
+ return true;
+ }
+
+ switch (block.Instructions[^1].Name)
+ {
+ case InstName.B:
+ return branchTargets.Contains(pc + 4UL) ||
+ (TryGetBranchTarget(block, out ulong targetAddress) && targetAddress >= pc && targetAddress < pc + 0x1000);
+
+ case InstName.Bx:
+ case InstName.Bxj:
+ return branchTargets.Contains(pc + 4UL);
+
+ case InstName.Cbnz:
+ case InstName.BlI:
+ case InstName.BlxR:
+ return true;
+ }
+
+ if (WritesToPC(block.Instructions[^1].Encoding, block.Instructions[^1].Name, lastInstFlags, block.IsThumb))
+ {
+ return branchTargets.Contains(pc + 4UL);
+ }
+
+ return !block.EndsWithBranch;
+ }
+
+ private static Block Decode(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb)
+ {
+ ulong startAddress = address;
+
+ List insts = new();
+
+ uint encoding;
+ InstMeta meta;
+ InstFlags extraFlags = InstFlags.None;
+ bool hasHostCall = false;
+ bool isTruncated = false;
+
+ do
+ {
+ if (!memoryManager.IsMapped(address))
+ {
+ encoding = 0;
+ meta = default;
+ isTruncated = true;
+ break;
+ }
+
+ if (isThumb)
+ {
+ encoding = (uint)memoryManager.Read(address) << 16;
+ address += 2UL;
+
+ extraFlags = InstFlags.Thumb16;
+
+ if (!InstTableT16.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta))
+ {
+ encoding |= memoryManager.Read(address);
+
+ if (InstTableT32.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta))
+ {
+ address += 2UL;
+ extraFlags = InstFlags.None;
+ }
+ }
+ }
+ else
+ {
+ encoding = memoryManager.Read(address);
+ address += 4UL;
+
+ meta = InstTableA32.GetMeta(encoding, cpuPreset.Version, cpuPreset.Features);
+ }
+
+ if (meta.Name.IsSystemOrCall() && !hasHostCall)
+ {
+ hasHostCall = meta.Name.IsCall() || InstEmitSystem.NeedsCall(meta.Name);
+ }
+
+ insts.Add(new(encoding, meta.Name, meta.EmitFunc, meta.Flags | extraFlags));
+ }
+ while (!IsControlFlow(encoding, meta.Name, meta.Flags | extraFlags, isThumb));
+
+ bool isLoopEnd = false;
+
+ if (!isTruncated && IsBackwardsBranch(meta.Name, encoding))
+ {
+ hasHostCall = true;
+ isLoopEnd = true;
+ }
+
+ return new(
+ startAddress,
+ address,
+ insts,
+ !isTruncated,
+ hasHostCall,
+ isTruncated,
+ isLoopEnd,
+ isThumb);
+ }
+
+ private static bool IsControlFlow(uint encoding, InstName name, InstFlags flags, bool isThumb)
+ {
+ switch (name)
+ {
+ case InstName.B:
+ case InstName.BlI:
+ case InstName.BlxR:
+ case InstName.Bx:
+ case InstName.Bxj:
+ case InstName.Cbnz:
+ case InstName.Tbb:
+ return true;
+ }
+
+ return WritesToPC(encoding, name, flags, isThumb);
+ }
+
+ public static bool WritesToPC(uint encoding, InstName name, InstFlags flags, bool isThumb)
+ {
+ return (GetRegisterWriteMask(encoding, name, flags, isThumb) & (1u << RegisterUtils.PcRegister)) != 0;
+ }
+
+ private static uint GetRegisterWriteMask(uint encoding, InstName name, InstFlags flags, bool isThumb)
+ {
+ uint mask = 0;
+
+ if (isThumb)
+ {
+ if (flags.HasFlag(InstFlags.Thumb16))
+ {
+ if (flags.HasFlag(InstFlags.Rdn))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdn(flags, encoding);
+ }
+
+ if (flags.HasFlag(InstFlags.Rd))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdT16(flags, encoding);
+ }
+
+ Debug.Assert(!flags.HasFlag(InstFlags.RdHi));
+
+ if (IsRegisterWrite(flags, InstFlags.Rt))
+ {
+ mask |= 1u << RegisterUtils.ExtractRtT16(flags, encoding);
+ }
+
+ Debug.Assert(!flags.HasFlag(InstFlags.Rt2));
+
+ if (IsRegisterWrite(flags, InstFlags.Rlist))
+ {
+ mask |= (byte)(encoding >> 16);
+
+ if (name == InstName.Push)
+ {
+ mask |= (encoding >> 10) & 0x4000; // LR
+ }
+ else if (name == InstName.Pop)
+ {
+ mask |= (encoding >> 9) & 0x8000; // PC
+ }
+ }
+
+ Debug.Assert(!flags.HasFlag(InstFlags.WBack));
+ }
+ else
+ {
+ if (flags.HasFlag(InstFlags.Rd))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdT32(flags, encoding);
+ }
+
+ if (flags.HasFlag(InstFlags.RdLo))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdLoT32(encoding);
+ }
+
+ if (flags.HasFlag(InstFlags.RdHi))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdHiT32(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rt) && IsRtWrite(name, encoding) && !IsR15RtEncodingSpecial(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRtT32(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rt2) && IsRtWrite(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRt2T32(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rlist))
+ {
+ mask |= (ushort)encoding;
+ }
+
+ if (flags.HasFlag(InstFlags.WBack) && HasWriteBackT32(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRn(encoding); // This is at the same bit position as A32.
+ }
+ }
+ }
+ else
+ {
+ if (flags.HasFlag(InstFlags.Rd))
+ {
+ mask |= 1u << RegisterUtils.ExtractRd(flags, encoding);
+ }
+
+ if (flags.HasFlag(InstFlags.RdHi))
+ {
+ mask |= 1u << RegisterUtils.ExtractRdHi(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rt) && IsRtWrite(name, encoding) && !IsR15RtEncodingSpecial(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRt(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rt2) && IsRtWrite(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRt2(encoding);
+ }
+
+ if (IsRegisterWrite(flags, InstFlags.Rlist))
+ {
+ mask |= (ushort)encoding;
+ }
+
+ if (flags.HasFlag(InstFlags.WBack) && HasWriteBack(name, encoding))
+ {
+ mask |= 1u << RegisterUtils.ExtractRn(encoding);
+ }
+ }
+
+ return mask;
+ }
+
+ private static bool IsRtWrite(InstName name, uint encoding)
+ {
+ // Some instructions can move GPR to FP/SIMD or FP/SIMD to GPR depending on the encoding.
+ // Detect those cases so that we can tell if we're actually doing a register write.
+
+ switch (name)
+ {
+ case InstName.VmovD:
+ case InstName.VmovH:
+ case InstName.VmovS:
+ case InstName.VmovSs:
+ return (encoding & (1u << 20)) != 0;
+ }
+
+ return true;
+ }
+
+ private static bool HasWriteBack(InstName name, uint encoding)
+ {
+ if (IsLoadStoreMultiple(name))
+ {
+ return (encoding & (1u << 21)) != 0;
+ }
+
+ if (IsVLDnVSTn(name))
+ {
+ return (encoding & 0xf) != RegisterUtils.PcRegister;
+ }
+
+ bool w = (encoding & (1u << 21)) != 0;
+ bool p = (encoding & (1u << 24)) != 0;
+
+ return !p || w;
+ }
+
+ private static bool HasWriteBackT32(InstName name, uint encoding)
+ {
+ if (IsLoadStoreMultiple(name))
+ {
+ return (encoding & (1u << 21)) != 0;
+ }
+
+ if (IsVLDnVSTn(name))
+ {
+ return (encoding & 0xf) != RegisterUtils.PcRegister;
+ }
+
+ return (encoding & (1u << 8)) != 0;
+ }
+
+ private static bool IsLoadStoreMultiple(InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Ldm:
+ case InstName.Ldmda:
+ case InstName.Ldmdb:
+ case InstName.LdmE:
+ case InstName.Ldmib:
+ case InstName.LdmU:
+ case InstName.Stm:
+ case InstName.Stmda:
+ case InstName.Stmdb:
+ case InstName.Stmib:
+ case InstName.StmU:
+ case InstName.Fldmx:
+ case InstName.Fstmx:
+ case InstName.Vldm:
+ case InstName.Vstm:
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool IsVLDnVSTn(InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Vld11:
+ case InstName.Vld1A:
+ case InstName.Vld1M:
+ case InstName.Vld21:
+ case InstName.Vld2A:
+ case InstName.Vld2M:
+ case InstName.Vld31:
+ case InstName.Vld3A:
+ case InstName.Vld3M:
+ case InstName.Vld41:
+ case InstName.Vld4A:
+ case InstName.Vld4M:
+ case InstName.Vst11:
+ case InstName.Vst1M:
+ case InstName.Vst21:
+ case InstName.Vst2M:
+ case InstName.Vst31:
+ case InstName.Vst3M:
+ case InstName.Vst41:
+ case InstName.Vst4M:
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool IsR15RtEncodingSpecial(InstName name, uint encoding)
+ {
+ if (name == InstName.Vmrs)
+ {
+ return ((encoding >> 16) & 0xf) == 1;
+ }
+
+ return false;
+ }
+
+ private static bool IsRegisterWrite(InstFlags flags, InstFlags testFlag)
+ {
+ return flags.HasFlag(testFlag) && !flags.HasFlag(InstFlags.ReadRd);
+ }
+
+ private static bool IsBackwardsBranch(InstName name, uint encoding)
+ {
+ if (name == InstName.B)
+ {
+ return ImmUtils.ExtractSImm24Times4(encoding) < 0;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs
new file mode 100644
index 00000000..32dc5aeb
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs
@@ -0,0 +1,1231 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ interface IInstEmit
+ {
+ static abstract void AdcIA1(CodeGenContext context, uint encoding);
+ static abstract void AdcIT1(CodeGenContext context, uint encoding);
+ static abstract void AdcRA1(CodeGenContext context, uint encoding);
+ static abstract void AdcRT1(CodeGenContext context, uint encoding);
+ static abstract void AdcRT2(CodeGenContext context, uint encoding);
+ static abstract void AdcRrA1(CodeGenContext context, uint encoding);
+ static abstract void AddIA1(CodeGenContext context, uint encoding);
+ static abstract void AddIT1(CodeGenContext context, uint encoding);
+ static abstract void AddIT2(CodeGenContext context, uint encoding);
+ static abstract void AddIT3(CodeGenContext context, uint encoding);
+ static abstract void AddIT4(CodeGenContext context, uint encoding);
+ static abstract void AddRA1(CodeGenContext context, uint encoding);
+ static abstract void AddRT1(CodeGenContext context, uint encoding);
+ static abstract void AddRT2(CodeGenContext context, uint encoding);
+ static abstract void AddRT3(CodeGenContext context, uint encoding);
+ static abstract void AddRrA1(CodeGenContext context, uint encoding);
+ static abstract void AddSpIA1(CodeGenContext context, uint encoding);
+ static abstract void AddSpIT1(CodeGenContext context, uint encoding);
+ static abstract void AddSpIT2(CodeGenContext context, uint encoding);
+ static abstract void AddSpIT3(CodeGenContext context, uint encoding);
+ static abstract void AddSpIT4(CodeGenContext context, uint encoding);
+ static abstract void AddSpRA1(CodeGenContext context, uint encoding);
+ static abstract void AddSpRT1(CodeGenContext context, uint encoding);
+ static abstract void AddSpRT2(CodeGenContext context, uint encoding);
+ static abstract void AddSpRT3(CodeGenContext context, uint encoding);
+ static abstract void AdrA1(CodeGenContext context, uint encoding);
+ static abstract void AdrA2(CodeGenContext context, uint encoding);
+ static abstract void AdrT1(CodeGenContext context, uint encoding);
+ static abstract void AdrT2(CodeGenContext context, uint encoding);
+ static abstract void AdrT3(CodeGenContext context, uint encoding);
+ static abstract void AesdA1(CodeGenContext context, uint encoding);
+ static abstract void AesdT1(CodeGenContext context, uint encoding);
+ static abstract void AeseA1(CodeGenContext context, uint encoding);
+ static abstract void AeseT1(CodeGenContext context, uint encoding);
+ static abstract void AesimcA1(CodeGenContext context, uint encoding);
+ static abstract void AesimcT1(CodeGenContext context, uint encoding);
+ static abstract void AesmcA1(CodeGenContext context, uint encoding);
+ static abstract void AesmcT1(CodeGenContext context, uint encoding);
+ static abstract void AndIA1(CodeGenContext context, uint encoding);
+ static abstract void AndIT1(CodeGenContext context, uint encoding);
+ static abstract void AndRA1(CodeGenContext context, uint encoding);
+ static abstract void AndRT1(CodeGenContext context, uint encoding);
+ static abstract void AndRT2(CodeGenContext context, uint encoding);
+ static abstract void AndRrA1(CodeGenContext context, uint encoding);
+ static abstract void BA1(CodeGenContext context, uint encoding);
+ static abstract void BT1(CodeGenContext context, uint encoding);
+ static abstract void BT2(CodeGenContext context, uint encoding);
+ static abstract void BT3(CodeGenContext context, uint encoding);
+ static abstract void BT4(CodeGenContext context, uint encoding);
+ static abstract void BfcA1(CodeGenContext context, uint encoding);
+ static abstract void BfcT1(CodeGenContext context, uint encoding);
+ static abstract void BfiA1(CodeGenContext context, uint encoding);
+ static abstract void BfiT1(CodeGenContext context, uint encoding);
+ static abstract void BicIA1(CodeGenContext context, uint encoding);
+ static abstract void BicIT1(CodeGenContext context, uint encoding);
+ static abstract void BicRA1(CodeGenContext context, uint encoding);
+ static abstract void BicRT1(CodeGenContext context, uint encoding);
+ static abstract void BicRT2(CodeGenContext context, uint encoding);
+ static abstract void BicRrA1(CodeGenContext context, uint encoding);
+ static abstract void BkptA1(CodeGenContext context, uint encoding);
+ static abstract void BkptT1(CodeGenContext context, uint encoding);
+ static abstract void BlxRA1(CodeGenContext context, uint encoding);
+ static abstract void BlxRT1(CodeGenContext context, uint encoding);
+ static abstract void BlIA1(CodeGenContext context, uint encoding);
+ static abstract void BlIA2(CodeGenContext context, uint encoding);
+ static abstract void BlIT1(CodeGenContext context, uint encoding);
+ static abstract void BlIT2(CodeGenContext context, uint encoding);
+ static abstract void BxA1(CodeGenContext context, uint encoding);
+ static abstract void BxT1(CodeGenContext context, uint encoding);
+ static abstract void BxjA1(CodeGenContext context, uint encoding);
+ static abstract void BxjT1(CodeGenContext context, uint encoding);
+ static abstract void CbnzT1(CodeGenContext context, uint encoding);
+ static abstract void ClrbhbA1(CodeGenContext context, uint encoding);
+ static abstract void ClrbhbT1(CodeGenContext context, uint encoding);
+ static abstract void ClrexA1(CodeGenContext context, uint encoding);
+ static abstract void ClrexT1(CodeGenContext context, uint encoding);
+ static abstract void ClzA1(CodeGenContext context, uint encoding);
+ static abstract void ClzT1(CodeGenContext context, uint encoding);
+ static abstract void CmnIA1(CodeGenContext context, uint encoding);
+ static abstract void CmnIT1(CodeGenContext context, uint encoding);
+ static abstract void CmnRA1(CodeGenContext context, uint encoding);
+ static abstract void CmnRT1(CodeGenContext context, uint encoding);
+ static abstract void CmnRT2(CodeGenContext context, uint encoding);
+ static abstract void CmnRrA1(CodeGenContext context, uint encoding);
+ static abstract void CmpIA1(CodeGenContext context, uint encoding);
+ static abstract void CmpIT1(CodeGenContext context, uint encoding);
+ static abstract void CmpIT2(CodeGenContext context, uint encoding);
+ static abstract void CmpRA1(CodeGenContext context, uint encoding);
+ static abstract void CmpRT1(CodeGenContext context, uint encoding);
+ static abstract void CmpRT2(CodeGenContext context, uint encoding);
+ static abstract void CmpRT3(CodeGenContext context, uint encoding);
+ static abstract void CmpRrA1(CodeGenContext context, uint encoding);
+ static abstract void CpsA1(CodeGenContext context, uint encoding);
+ static abstract void CpsT1(CodeGenContext context, uint encoding);
+ static abstract void CpsT2(CodeGenContext context, uint encoding);
+ static abstract void Crc32A1(CodeGenContext context, uint encoding);
+ static abstract void Crc32T1(CodeGenContext context, uint encoding);
+ static abstract void Crc32cA1(CodeGenContext context, uint encoding);
+ static abstract void Crc32cT1(CodeGenContext context, uint encoding);
+ static abstract void CsdbA1(CodeGenContext context, uint encoding);
+ static abstract void CsdbT1(CodeGenContext context, uint encoding);
+ static abstract void DbgA1(CodeGenContext context, uint encoding);
+ static abstract void DbgT1(CodeGenContext context, uint encoding);
+ static abstract void Dcps1T1(CodeGenContext context, uint encoding);
+ static abstract void Dcps2T1(CodeGenContext context, uint encoding);
+ static abstract void Dcps3T1(CodeGenContext context, uint encoding);
+ static abstract void DmbA1(CodeGenContext context, uint encoding);
+ static abstract void DmbT1(CodeGenContext context, uint encoding);
+ static abstract void DsbA1(CodeGenContext context, uint encoding);
+ static abstract void DsbT1(CodeGenContext context, uint encoding);
+ static abstract void EorIA1(CodeGenContext context, uint encoding);
+ static abstract void EorIT1(CodeGenContext context, uint encoding);
+ static abstract void EorRA1(CodeGenContext context, uint encoding);
+ static abstract void EorRT1(CodeGenContext context, uint encoding);
+ static abstract void EorRT2(CodeGenContext context, uint encoding);
+ static abstract void EorRrA1(CodeGenContext context, uint encoding);
+ static abstract void EretA1(CodeGenContext context, uint encoding);
+ static abstract void EretT1(CodeGenContext context, uint encoding);
+ static abstract void EsbA1(CodeGenContext context, uint encoding);
+ static abstract void EsbT1(CodeGenContext context, uint encoding);
+ static abstract void FldmxA1(CodeGenContext context, uint encoding);
+ static abstract void FldmxT1(CodeGenContext context, uint encoding);
+ static abstract void FstmxA1(CodeGenContext context, uint encoding);
+ static abstract void FstmxT1(CodeGenContext context, uint encoding);
+ static abstract void HltA1(CodeGenContext context, uint encoding);
+ static abstract void HltT1(CodeGenContext context, uint encoding);
+ static abstract void HvcA1(CodeGenContext context, uint encoding);
+ static abstract void HvcT1(CodeGenContext context, uint encoding);
+ static abstract void IsbA1(CodeGenContext context, uint encoding);
+ static abstract void IsbT1(CodeGenContext context, uint encoding);
+ static abstract void ItT1(CodeGenContext context, uint encoding);
+ static abstract void LdaA1(CodeGenContext context, uint encoding);
+ static abstract void LdaT1(CodeGenContext context, uint encoding);
+ static abstract void LdabA1(CodeGenContext context, uint encoding);
+ static abstract void LdabT1(CodeGenContext context, uint encoding);
+ static abstract void LdaexA1(CodeGenContext context, uint encoding);
+ static abstract void LdaexT1(CodeGenContext context, uint encoding);
+ static abstract void LdaexbA1(CodeGenContext context, uint encoding);
+ static abstract void LdaexbT1(CodeGenContext context, uint encoding);
+ static abstract void LdaexdA1(CodeGenContext context, uint encoding);
+ static abstract void LdaexdT1(CodeGenContext context, uint encoding);
+ static abstract void LdaexhA1(CodeGenContext context, uint encoding);
+ static abstract void LdaexhT1(CodeGenContext context, uint encoding);
+ static abstract void LdahA1(CodeGenContext context, uint encoding);
+ static abstract void LdahT1(CodeGenContext context, uint encoding);
+ static abstract void LdcIA1(CodeGenContext context, uint encoding);
+ static abstract void LdcIT1(CodeGenContext context, uint encoding);
+ static abstract void LdcLA1(CodeGenContext context, uint encoding);
+ static abstract void LdcLT1(CodeGenContext context, uint encoding);
+ static abstract void LdmA1(CodeGenContext context, uint encoding);
+ static abstract void LdmT1(CodeGenContext context, uint encoding);
+ static abstract void LdmT2(CodeGenContext context, uint encoding);
+ static abstract void LdmdaA1(CodeGenContext context, uint encoding);
+ static abstract void LdmdbA1(CodeGenContext context, uint encoding);
+ static abstract void LdmdbT1(CodeGenContext context, uint encoding);
+ static abstract void LdmibA1(CodeGenContext context, uint encoding);
+ static abstract void LdmEA1(CodeGenContext context, uint encoding);
+ static abstract void LdmUA1(CodeGenContext context, uint encoding);
+ static abstract void LdrbtA1(CodeGenContext context, uint encoding);
+ static abstract void LdrbtA2(CodeGenContext context, uint encoding);
+ static abstract void LdrbtT1(CodeGenContext context, uint encoding);
+ static abstract void LdrbIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrbIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrbIT2(CodeGenContext context, uint encoding);
+ static abstract void LdrbIT3(CodeGenContext context, uint encoding);
+ static abstract void LdrbLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrbLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrbRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrbRT1(CodeGenContext context, uint encoding);
+ static abstract void LdrbRT2(CodeGenContext context, uint encoding);
+ static abstract void LdrdIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrdIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrdLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrdLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrdRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrexA1(CodeGenContext context, uint encoding);
+ static abstract void LdrexT1(CodeGenContext context, uint encoding);
+ static abstract void LdrexbA1(CodeGenContext context, uint encoding);
+ static abstract void LdrexbT1(CodeGenContext context, uint encoding);
+ static abstract void LdrexdA1(CodeGenContext context, uint encoding);
+ static abstract void LdrexdT1(CodeGenContext context, uint encoding);
+ static abstract void LdrexhA1(CodeGenContext context, uint encoding);
+ static abstract void LdrexhT1(CodeGenContext context, uint encoding);
+ static abstract void LdrhtA1(CodeGenContext context, uint encoding);
+ static abstract void LdrhtA2(CodeGenContext context, uint encoding);
+ static abstract void LdrhtT1(CodeGenContext context, uint encoding);
+ static abstract void LdrhIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrhIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrhIT2(CodeGenContext context, uint encoding);
+ static abstract void LdrhIT3(CodeGenContext context, uint encoding);
+ static abstract void LdrhLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrhLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrhRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrhRT1(CodeGenContext context, uint encoding);
+ static abstract void LdrhRT2(CodeGenContext context, uint encoding);
+ static abstract void LdrsbtA1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbtA2(CodeGenContext context, uint encoding);
+ static abstract void LdrsbtT1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbIT2(CodeGenContext context, uint encoding);
+ static abstract void LdrsbLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbRT1(CodeGenContext context, uint encoding);
+ static abstract void LdrsbRT2(CodeGenContext context, uint encoding);
+ static abstract void LdrshtA1(CodeGenContext context, uint encoding);
+ static abstract void LdrshtA2(CodeGenContext context, uint encoding);
+ static abstract void LdrshtT1(CodeGenContext context, uint encoding);
+ static abstract void LdrshIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrshIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrshIT2(CodeGenContext context, uint encoding);
+ static abstract void LdrshLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrshLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrshRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrshRT1(CodeGenContext context, uint encoding);
+ static abstract void LdrshRT2(CodeGenContext context, uint encoding);
+ static abstract void LdrtA1(CodeGenContext context, uint encoding);
+ static abstract void LdrtA2(CodeGenContext context, uint encoding);
+ static abstract void LdrtT1(CodeGenContext context, uint encoding);
+ static abstract void LdrIA1(CodeGenContext context, uint encoding);
+ static abstract void LdrIT1(CodeGenContext context, uint encoding);
+ static abstract void LdrIT2(CodeGenContext context, uint encoding);
+ static abstract void LdrIT3(CodeGenContext context, uint encoding);
+ static abstract void LdrIT4(CodeGenContext context, uint encoding);
+ static abstract void LdrLA1(CodeGenContext context, uint encoding);
+ static abstract void LdrLT1(CodeGenContext context, uint encoding);
+ static abstract void LdrLT2(CodeGenContext context, uint encoding);
+ static abstract void LdrRA1(CodeGenContext context, uint encoding);
+ static abstract void LdrRT1(CodeGenContext context, uint encoding);
+ static abstract void LdrRT2(CodeGenContext context, uint encoding);
+ static abstract void McrA1(CodeGenContext context, uint encoding);
+ static abstract void McrT1(CodeGenContext context, uint encoding);
+ static abstract void McrrA1(CodeGenContext context, uint encoding);
+ static abstract void McrrT1(CodeGenContext context, uint encoding);
+ static abstract void MlaA1(CodeGenContext context, uint encoding);
+ static abstract void MlaT1(CodeGenContext context, uint encoding);
+ static abstract void MlsA1(CodeGenContext context, uint encoding);
+ static abstract void MlsT1(CodeGenContext context, uint encoding);
+ static abstract void MovtA1(CodeGenContext context, uint encoding);
+ static abstract void MovtT1(CodeGenContext context, uint encoding);
+ static abstract void MovIA1(CodeGenContext context, uint encoding);
+ static abstract void MovIA2(CodeGenContext context, uint encoding);
+ static abstract void MovIT1(CodeGenContext context, uint encoding);
+ static abstract void MovIT2(CodeGenContext context, uint encoding);
+ static abstract void MovIT3(CodeGenContext context, uint encoding);
+ static abstract void MovRA1(CodeGenContext context, uint encoding);
+ static abstract void MovRT1(CodeGenContext context, uint encoding);
+ static abstract void MovRT2(CodeGenContext context, uint encoding);
+ static abstract void MovRT3(CodeGenContext context, uint encoding);
+ static abstract void MovRrA1(CodeGenContext context, uint encoding);
+ static abstract void MovRrT1(CodeGenContext context, uint encoding);
+ static abstract void MovRrT2(CodeGenContext context, uint encoding);
+ static abstract void MrcA1(CodeGenContext context, uint encoding);
+ static abstract void MrcT1(CodeGenContext context, uint encoding);
+ static abstract void MrrcA1(CodeGenContext context, uint encoding);
+ static abstract void MrrcT1(CodeGenContext context, uint encoding);
+ static abstract void MrsA1(CodeGenContext context, uint encoding);
+ static abstract void MrsT1(CodeGenContext context, uint encoding);
+ static abstract void MrsBrA1(CodeGenContext context, uint encoding);
+ static abstract void MrsBrT1(CodeGenContext context, uint encoding);
+ static abstract void MsrBrA1(CodeGenContext context, uint encoding);
+ static abstract void MsrBrT1(CodeGenContext context, uint encoding);
+ static abstract void MsrIA1(CodeGenContext context, uint encoding);
+ static abstract void MsrRA1(CodeGenContext context, uint encoding);
+ static abstract void MsrRT1(CodeGenContext context, uint encoding);
+ static abstract void MulA1(CodeGenContext context, uint encoding);
+ static abstract void MulT1(CodeGenContext context, uint encoding);
+ static abstract void MulT2(CodeGenContext context, uint encoding);
+ static abstract void MvnIA1(CodeGenContext context, uint encoding);
+ static abstract void MvnIT1(CodeGenContext context, uint encoding);
+ static abstract void MvnRA1(CodeGenContext context, uint encoding);
+ static abstract void MvnRT1(CodeGenContext context, uint encoding);
+ static abstract void MvnRT2(CodeGenContext context, uint encoding);
+ static abstract void MvnRrA1(CodeGenContext context, uint encoding);
+ static abstract void NopA1(CodeGenContext context, uint encoding);
+ static abstract void NopT1(CodeGenContext context, uint encoding);
+ static abstract void NopT2(CodeGenContext context, uint encoding);
+ static abstract void OrnIT1(CodeGenContext context, uint encoding);
+ static abstract void OrnRT1(CodeGenContext context, uint encoding);
+ static abstract void OrrIA1(CodeGenContext context, uint encoding);
+ static abstract void OrrIT1(CodeGenContext context, uint encoding);
+ static abstract void OrrRA1(CodeGenContext context, uint encoding);
+ static abstract void OrrRT1(CodeGenContext context, uint encoding);
+ static abstract void OrrRT2(CodeGenContext context, uint encoding);
+ static abstract void OrrRrA1(CodeGenContext context, uint encoding);
+ static abstract void PkhA1(CodeGenContext context, uint encoding);
+ static abstract void PkhT1(CodeGenContext context, uint encoding);
+ static abstract void PldIA1(CodeGenContext context, uint encoding);
+ static abstract void PldIT1(CodeGenContext context, uint encoding);
+ static abstract void PldIT2(CodeGenContext context, uint encoding);
+ static abstract void PldLA1(CodeGenContext context, uint encoding);
+ static abstract void PldLT1(CodeGenContext context, uint encoding);
+ static abstract void PldRA1(CodeGenContext context, uint encoding);
+ static abstract void PldRT1(CodeGenContext context, uint encoding);
+ static abstract void PliIA1(CodeGenContext context, uint encoding);
+ static abstract void PliIT1(CodeGenContext context, uint encoding);
+ static abstract void PliIT2(CodeGenContext context, uint encoding);
+ static abstract void PliIT3(CodeGenContext context, uint encoding);
+ static abstract void PliRA1(CodeGenContext context, uint encoding);
+ static abstract void PliRT1(CodeGenContext context, uint encoding);
+ static abstract void PopT1(CodeGenContext context, uint encoding);
+ static abstract void PssbbA1(CodeGenContext context, uint encoding);
+ static abstract void PssbbT1(CodeGenContext context, uint encoding);
+ static abstract void PushT1(CodeGenContext context, uint encoding);
+ static abstract void QaddA1(CodeGenContext context, uint encoding);
+ static abstract void QaddT1(CodeGenContext context, uint encoding);
+ static abstract void Qadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Qadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Qadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Qadd8T1(CodeGenContext context, uint encoding);
+ static abstract void QasxA1(CodeGenContext context, uint encoding);
+ static abstract void QasxT1(CodeGenContext context, uint encoding);
+ static abstract void QdaddA1(CodeGenContext context, uint encoding);
+ static abstract void QdaddT1(CodeGenContext context, uint encoding);
+ static abstract void QdsubA1(CodeGenContext context, uint encoding);
+ static abstract void QdsubT1(CodeGenContext context, uint encoding);
+ static abstract void QsaxA1(CodeGenContext context, uint encoding);
+ static abstract void QsaxT1(CodeGenContext context, uint encoding);
+ static abstract void QsubA1(CodeGenContext context, uint encoding);
+ static abstract void QsubT1(CodeGenContext context, uint encoding);
+ static abstract void Qsub16A1(CodeGenContext context, uint encoding);
+ static abstract void Qsub16T1(CodeGenContext context, uint encoding);
+ static abstract void Qsub8A1(CodeGenContext context, uint encoding);
+ static abstract void Qsub8T1(CodeGenContext context, uint encoding);
+ static abstract void RbitA1(CodeGenContext context, uint encoding);
+ static abstract void RbitT1(CodeGenContext context, uint encoding);
+ static abstract void RevA1(CodeGenContext context, uint encoding);
+ static abstract void RevT1(CodeGenContext context, uint encoding);
+ static abstract void RevT2(CodeGenContext context, uint encoding);
+ static abstract void Rev16A1(CodeGenContext context, uint encoding);
+ static abstract void Rev16T1(CodeGenContext context, uint encoding);
+ static abstract void Rev16T2(CodeGenContext context, uint encoding);
+ static abstract void RevshA1(CodeGenContext context, uint encoding);
+ static abstract void RevshT1(CodeGenContext context, uint encoding);
+ static abstract void RevshT2(CodeGenContext context, uint encoding);
+ static abstract void RfeA1(CodeGenContext context, uint encoding);
+ static abstract void RfeT1(CodeGenContext context, uint encoding);
+ static abstract void RfeT2(CodeGenContext context, uint encoding);
+ static abstract void RsbIA1(CodeGenContext context, uint encoding);
+ static abstract void RsbIT1(CodeGenContext context, uint encoding);
+ static abstract void RsbIT2(CodeGenContext context, uint encoding);
+ static abstract void RsbRA1(CodeGenContext context, uint encoding);
+ static abstract void RsbRT1(CodeGenContext context, uint encoding);
+ static abstract void RsbRrA1(CodeGenContext context, uint encoding);
+ static abstract void RscIA1(CodeGenContext context, uint encoding);
+ static abstract void RscRA1(CodeGenContext context, uint encoding);
+ static abstract void RscRrA1(CodeGenContext context, uint encoding);
+ static abstract void Sadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Sadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Sadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Sadd8T1(CodeGenContext context, uint encoding);
+ static abstract void SasxA1(CodeGenContext context, uint encoding);
+ static abstract void SasxT1(CodeGenContext context, uint encoding);
+ static abstract void SbA1(CodeGenContext context, uint encoding);
+ static abstract void SbT1(CodeGenContext context, uint encoding);
+ static abstract void SbcIA1(CodeGenContext context, uint encoding);
+ static abstract void SbcIT1(CodeGenContext context, uint encoding);
+ static abstract void SbcRA1(CodeGenContext context, uint encoding);
+ static abstract void SbcRT1(CodeGenContext context, uint encoding);
+ static abstract void SbcRT2(CodeGenContext context, uint encoding);
+ static abstract void SbcRrA1(CodeGenContext context, uint encoding);
+ static abstract void SbfxA1(CodeGenContext context, uint encoding);
+ static abstract void SbfxT1(CodeGenContext context, uint encoding);
+ static abstract void SdivA1(CodeGenContext context, uint encoding);
+ static abstract void SdivT1(CodeGenContext context, uint encoding);
+ static abstract void SelA1(CodeGenContext context, uint encoding);
+ static abstract void SelT1(CodeGenContext context, uint encoding);
+ static abstract void SetendA1(CodeGenContext context, uint encoding);
+ static abstract void SetendT1(CodeGenContext context, uint encoding);
+ static abstract void SetpanA1(CodeGenContext context, uint encoding);
+ static abstract void SetpanT1(CodeGenContext context, uint encoding);
+ static abstract void SevA1(CodeGenContext context, uint encoding);
+ static abstract void SevT1(CodeGenContext context, uint encoding);
+ static abstract void SevT2(CodeGenContext context, uint encoding);
+ static abstract void SevlA1(CodeGenContext context, uint encoding);
+ static abstract void SevlT1(CodeGenContext context, uint encoding);
+ static abstract void SevlT2(CodeGenContext context, uint encoding);
+ static abstract void Sha1cA1(CodeGenContext context, uint encoding);
+ static abstract void Sha1cT1(CodeGenContext context, uint encoding);
+ static abstract void Sha1hA1(CodeGenContext context, uint encoding);
+ static abstract void Sha1hT1(CodeGenContext context, uint encoding);
+ static abstract void Sha1mA1(CodeGenContext context, uint encoding);
+ static abstract void Sha1mT1(CodeGenContext context, uint encoding);
+ static abstract void Sha1pA1(CodeGenContext context, uint encoding);
+ static abstract void Sha1pT1(CodeGenContext context, uint encoding);
+ static abstract void Sha1su0A1(CodeGenContext context, uint encoding);
+ static abstract void Sha1su0T1(CodeGenContext context, uint encoding);
+ static abstract void Sha1su1A1(CodeGenContext context, uint encoding);
+ static abstract void Sha1su1T1(CodeGenContext context, uint encoding);
+ static abstract void Sha256hA1(CodeGenContext context, uint encoding);
+ static abstract void Sha256hT1(CodeGenContext context, uint encoding);
+ static abstract void Sha256h2A1(CodeGenContext context, uint encoding);
+ static abstract void Sha256h2T1(CodeGenContext context, uint encoding);
+ static abstract void Sha256su0A1(CodeGenContext context, uint encoding);
+ static abstract void Sha256su0T1(CodeGenContext context, uint encoding);
+ static abstract void Sha256su1A1(CodeGenContext context, uint encoding);
+ static abstract void Sha256su1T1(CodeGenContext context, uint encoding);
+ static abstract void Shadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Shadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Shadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Shadd8T1(CodeGenContext context, uint encoding);
+ static abstract void ShasxA1(CodeGenContext context, uint encoding);
+ static abstract void ShasxT1(CodeGenContext context, uint encoding);
+ static abstract void ShsaxA1(CodeGenContext context, uint encoding);
+ static abstract void ShsaxT1(CodeGenContext context, uint encoding);
+ static abstract void Shsub16A1(CodeGenContext context, uint encoding);
+ static abstract void Shsub16T1(CodeGenContext context, uint encoding);
+ static abstract void Shsub8A1(CodeGenContext context, uint encoding);
+ static abstract void Shsub8T1(CodeGenContext context, uint encoding);
+ static abstract void SmcA1(CodeGenContext context, uint encoding);
+ static abstract void SmcT1(CodeGenContext context, uint encoding);
+ static abstract void SmlabbA1(CodeGenContext context, uint encoding);
+ static abstract void SmlabbT1(CodeGenContext context, uint encoding);
+ static abstract void SmladA1(CodeGenContext context, uint encoding);
+ static abstract void SmladT1(CodeGenContext context, uint encoding);
+ static abstract void SmlalA1(CodeGenContext context, uint encoding);
+ static abstract void SmlalT1(CodeGenContext context, uint encoding);
+ static abstract void SmlalbbA1(CodeGenContext context, uint encoding);
+ static abstract void SmlalbbT1(CodeGenContext context, uint encoding);
+ static abstract void SmlaldA1(CodeGenContext context, uint encoding);
+ static abstract void SmlaldT1(CodeGenContext context, uint encoding);
+ static abstract void SmlawbA1(CodeGenContext context, uint encoding);
+ static abstract void SmlawbT1(CodeGenContext context, uint encoding);
+ static abstract void SmlsdA1(CodeGenContext context, uint encoding);
+ static abstract void SmlsdT1(CodeGenContext context, uint encoding);
+ static abstract void SmlsldA1(CodeGenContext context, uint encoding);
+ static abstract void SmlsldT1(CodeGenContext context, uint encoding);
+ static abstract void SmmlaA1(CodeGenContext context, uint encoding);
+ static abstract void SmmlaT1(CodeGenContext context, uint encoding);
+ static abstract void SmmlsA1(CodeGenContext context, uint encoding);
+ static abstract void SmmlsT1(CodeGenContext context, uint encoding);
+ static abstract void SmmulA1(CodeGenContext context, uint encoding);
+ static abstract void SmmulT1(CodeGenContext context, uint encoding);
+ static abstract void SmuadA1(CodeGenContext context, uint encoding);
+ static abstract void SmuadT1(CodeGenContext context, uint encoding);
+ static abstract void SmulbbA1(CodeGenContext context, uint encoding);
+ static abstract void SmulbbT1(CodeGenContext context, uint encoding);
+ static abstract void SmullA1(CodeGenContext context, uint encoding);
+ static abstract void SmullT1(CodeGenContext context, uint encoding);
+ static abstract void SmulwbA1(CodeGenContext context, uint encoding);
+ static abstract void SmulwbT1(CodeGenContext context, uint encoding);
+ static abstract void SmusdA1(CodeGenContext context, uint encoding);
+ static abstract void SmusdT1(CodeGenContext context, uint encoding);
+ static abstract void SrsA1(CodeGenContext context, uint encoding);
+ static abstract void SrsT1(CodeGenContext context, uint encoding);
+ static abstract void SrsT2(CodeGenContext context, uint encoding);
+ static abstract void SsatA1(CodeGenContext context, uint encoding);
+ static abstract void SsatT1(CodeGenContext context, uint encoding);
+ static abstract void Ssat16A1(CodeGenContext context, uint encoding);
+ static abstract void Ssat16T1(CodeGenContext context, uint encoding);
+ static abstract void SsaxA1(CodeGenContext context, uint encoding);
+ static abstract void SsaxT1(CodeGenContext context, uint encoding);
+ static abstract void SsbbA1(CodeGenContext context, uint encoding);
+ static abstract void SsbbT1(CodeGenContext context, uint encoding);
+ static abstract void Ssub16A1(CodeGenContext context, uint encoding);
+ static abstract void Ssub16T1(CodeGenContext context, uint encoding);
+ static abstract void Ssub8A1(CodeGenContext context, uint encoding);
+ static abstract void Ssub8T1(CodeGenContext context, uint encoding);
+ static abstract void StcA1(CodeGenContext context, uint encoding);
+ static abstract void StcT1(CodeGenContext context, uint encoding);
+ static abstract void StlA1(CodeGenContext context, uint encoding);
+ static abstract void StlT1(CodeGenContext context, uint encoding);
+ static abstract void StlbA1(CodeGenContext context, uint encoding);
+ static abstract void StlbT1(CodeGenContext context, uint encoding);
+ static abstract void StlexA1(CodeGenContext context, uint encoding);
+ static abstract void StlexT1(CodeGenContext context, uint encoding);
+ static abstract void StlexbA1(CodeGenContext context, uint encoding);
+ static abstract void StlexbT1(CodeGenContext context, uint encoding);
+ static abstract void StlexdA1(CodeGenContext context, uint encoding);
+ static abstract void StlexdT1(CodeGenContext context, uint encoding);
+ static abstract void StlexhA1(CodeGenContext context, uint encoding);
+ static abstract void StlexhT1(CodeGenContext context, uint encoding);
+ static abstract void StlhA1(CodeGenContext context, uint encoding);
+ static abstract void StlhT1(CodeGenContext context, uint encoding);
+ static abstract void StmA1(CodeGenContext context, uint encoding);
+ static abstract void StmT1(CodeGenContext context, uint encoding);
+ static abstract void StmT2(CodeGenContext context, uint encoding);
+ static abstract void StmdaA1(CodeGenContext context, uint encoding);
+ static abstract void StmdbA1(CodeGenContext context, uint encoding);
+ static abstract void StmdbT1(CodeGenContext context, uint encoding);
+ static abstract void StmibA1(CodeGenContext context, uint encoding);
+ static abstract void StmUA1(CodeGenContext context, uint encoding);
+ static abstract void StrbtA1(CodeGenContext context, uint encoding);
+ static abstract void StrbtA2(CodeGenContext context, uint encoding);
+ static abstract void StrbtT1(CodeGenContext context, uint encoding);
+ static abstract void StrbIA1(CodeGenContext context, uint encoding);
+ static abstract void StrbIT1(CodeGenContext context, uint encoding);
+ static abstract void StrbIT2(CodeGenContext context, uint encoding);
+ static abstract void StrbIT3(CodeGenContext context, uint encoding);
+ static abstract void StrbRA1(CodeGenContext context, uint encoding);
+ static abstract void StrbRT1(CodeGenContext context, uint encoding);
+ static abstract void StrbRT2(CodeGenContext context, uint encoding);
+ static abstract void StrdIA1(CodeGenContext context, uint encoding);
+ static abstract void StrdIT1(CodeGenContext context, uint encoding);
+ static abstract void StrdRA1(CodeGenContext context, uint encoding);
+ static abstract void StrexA1(CodeGenContext context, uint encoding);
+ static abstract void StrexT1(CodeGenContext context, uint encoding);
+ static abstract void StrexbA1(CodeGenContext context, uint encoding);
+ static abstract void StrexbT1(CodeGenContext context, uint encoding);
+ static abstract void StrexdA1(CodeGenContext context, uint encoding);
+ static abstract void StrexdT1(CodeGenContext context, uint encoding);
+ static abstract void StrexhA1(CodeGenContext context, uint encoding);
+ static abstract void StrexhT1(CodeGenContext context, uint encoding);
+ static abstract void StrhtA1(CodeGenContext context, uint encoding);
+ static abstract void StrhtA2(CodeGenContext context, uint encoding);
+ static abstract void StrhtT1(CodeGenContext context, uint encoding);
+ static abstract void StrhIA1(CodeGenContext context, uint encoding);
+ static abstract void StrhIT1(CodeGenContext context, uint encoding);
+ static abstract void StrhIT2(CodeGenContext context, uint encoding);
+ static abstract void StrhIT3(CodeGenContext context, uint encoding);
+ static abstract void StrhRA1(CodeGenContext context, uint encoding);
+ static abstract void StrhRT1(CodeGenContext context, uint encoding);
+ static abstract void StrhRT2(CodeGenContext context, uint encoding);
+ static abstract void StrtA1(CodeGenContext context, uint encoding);
+ static abstract void StrtA2(CodeGenContext context, uint encoding);
+ static abstract void StrtT1(CodeGenContext context, uint encoding);
+ static abstract void StrIA1(CodeGenContext context, uint encoding);
+ static abstract void StrIT1(CodeGenContext context, uint encoding);
+ static abstract void StrIT2(CodeGenContext context, uint encoding);
+ static abstract void StrIT3(CodeGenContext context, uint encoding);
+ static abstract void StrIT4(CodeGenContext context, uint encoding);
+ static abstract void StrRA1(CodeGenContext context, uint encoding);
+ static abstract void StrRT1(CodeGenContext context, uint encoding);
+ static abstract void StrRT2(CodeGenContext context, uint encoding);
+ static abstract void SubIA1(CodeGenContext context, uint encoding);
+ static abstract void SubIT1(CodeGenContext context, uint encoding);
+ static abstract void SubIT2(CodeGenContext context, uint encoding);
+ static abstract void SubIT3(CodeGenContext context, uint encoding);
+ static abstract void SubIT4(CodeGenContext context, uint encoding);
+ static abstract void SubIT5(CodeGenContext context, uint encoding);
+ static abstract void SubRA1(CodeGenContext context, uint encoding);
+ static abstract void SubRT1(CodeGenContext context, uint encoding);
+ static abstract void SubRT2(CodeGenContext context, uint encoding);
+ static abstract void SubRrA1(CodeGenContext context, uint encoding);
+ static abstract void SubSpIA1(CodeGenContext context, uint encoding);
+ static abstract void SubSpIT1(CodeGenContext context, uint encoding);
+ static abstract void SubSpIT2(CodeGenContext context, uint encoding);
+ static abstract void SubSpIT3(CodeGenContext context, uint encoding);
+ static abstract void SubSpRA1(CodeGenContext context, uint encoding);
+ static abstract void SubSpRT1(CodeGenContext context, uint encoding);
+ static abstract void SvcA1(CodeGenContext context, uint encoding);
+ static abstract void SvcT1(CodeGenContext context, uint encoding);
+ static abstract void SxtabA1(CodeGenContext context, uint encoding);
+ static abstract void SxtabT1(CodeGenContext context, uint encoding);
+ static abstract void Sxtab16A1(CodeGenContext context, uint encoding);
+ static abstract void Sxtab16T1(CodeGenContext context, uint encoding);
+ static abstract void SxtahA1(CodeGenContext context, uint encoding);
+ static abstract void SxtahT1(CodeGenContext context, uint encoding);
+ static abstract void SxtbA1(CodeGenContext context, uint encoding);
+ static abstract void SxtbT1(CodeGenContext context, uint encoding);
+ static abstract void SxtbT2(CodeGenContext context, uint encoding);
+ static abstract void Sxtb16A1(CodeGenContext context, uint encoding);
+ static abstract void Sxtb16T1(CodeGenContext context, uint encoding);
+ static abstract void SxthA1(CodeGenContext context, uint encoding);
+ static abstract void SxthT1(CodeGenContext context, uint encoding);
+ static abstract void SxthT2(CodeGenContext context, uint encoding);
+ static abstract void TbbT1(CodeGenContext context, uint encoding);
+ static abstract void TeqIA1(CodeGenContext context, uint encoding);
+ static abstract void TeqIT1(CodeGenContext context, uint encoding);
+ static abstract void TeqRA1(CodeGenContext context, uint encoding);
+ static abstract void TeqRT1(CodeGenContext context, uint encoding);
+ static abstract void TeqRrA1(CodeGenContext context, uint encoding);
+ static abstract void TsbA1(CodeGenContext context, uint encoding);
+ static abstract void TsbT1(CodeGenContext context, uint encoding);
+ static abstract void TstIA1(CodeGenContext context, uint encoding);
+ static abstract void TstIT1(CodeGenContext context, uint encoding);
+ static abstract void TstRA1(CodeGenContext context, uint encoding);
+ static abstract void TstRT1(CodeGenContext context, uint encoding);
+ static abstract void TstRT2(CodeGenContext context, uint encoding);
+ static abstract void TstRrA1(CodeGenContext context, uint encoding);
+ static abstract void Uadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Uadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Uadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Uadd8T1(CodeGenContext context, uint encoding);
+ static abstract void UasxA1(CodeGenContext context, uint encoding);
+ static abstract void UasxT1(CodeGenContext context, uint encoding);
+ static abstract void UbfxA1(CodeGenContext context, uint encoding);
+ static abstract void UbfxT1(CodeGenContext context, uint encoding);
+ static abstract void UdfA1(CodeGenContext context, uint encoding);
+ static abstract void UdfT1(CodeGenContext context, uint encoding);
+ static abstract void UdfT2(CodeGenContext context, uint encoding);
+ static abstract void UdivA1(CodeGenContext context, uint encoding);
+ static abstract void UdivT1(CodeGenContext context, uint encoding);
+ static abstract void Uhadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Uhadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Uhadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Uhadd8T1(CodeGenContext context, uint encoding);
+ static abstract void UhasxA1(CodeGenContext context, uint encoding);
+ static abstract void UhasxT1(CodeGenContext context, uint encoding);
+ static abstract void UhsaxA1(CodeGenContext context, uint encoding);
+ static abstract void UhsaxT1(CodeGenContext context, uint encoding);
+ static abstract void Uhsub16A1(CodeGenContext context, uint encoding);
+ static abstract void Uhsub16T1(CodeGenContext context, uint encoding);
+ static abstract void Uhsub8A1(CodeGenContext context, uint encoding);
+ static abstract void Uhsub8T1(CodeGenContext context, uint encoding);
+ static abstract void UmaalA1(CodeGenContext context, uint encoding);
+ static abstract void UmaalT1(CodeGenContext context, uint encoding);
+ static abstract void UmlalA1(CodeGenContext context, uint encoding);
+ static abstract void UmlalT1(CodeGenContext context, uint encoding);
+ static abstract void UmullA1(CodeGenContext context, uint encoding);
+ static abstract void UmullT1(CodeGenContext context, uint encoding);
+ static abstract void Uqadd16A1(CodeGenContext context, uint encoding);
+ static abstract void Uqadd16T1(CodeGenContext context, uint encoding);
+ static abstract void Uqadd8A1(CodeGenContext context, uint encoding);
+ static abstract void Uqadd8T1(CodeGenContext context, uint encoding);
+ static abstract void UqasxA1(CodeGenContext context, uint encoding);
+ static abstract void UqasxT1(CodeGenContext context, uint encoding);
+ static abstract void UqsaxA1(CodeGenContext context, uint encoding);
+ static abstract void UqsaxT1(CodeGenContext context, uint encoding);
+ static abstract void Uqsub16A1(CodeGenContext context, uint encoding);
+ static abstract void Uqsub16T1(CodeGenContext context, uint encoding);
+ static abstract void Uqsub8A1(CodeGenContext context, uint encoding);
+ static abstract void Uqsub8T1(CodeGenContext context, uint encoding);
+ static abstract void Usad8A1(CodeGenContext context, uint encoding);
+ static abstract void Usad8T1(CodeGenContext context, uint encoding);
+ static abstract void Usada8A1(CodeGenContext context, uint encoding);
+ static abstract void Usada8T1(CodeGenContext context, uint encoding);
+ static abstract void UsatA1(CodeGenContext context, uint encoding);
+ static abstract void UsatT1(CodeGenContext context, uint encoding);
+ static abstract void Usat16A1(CodeGenContext context, uint encoding);
+ static abstract void Usat16T1(CodeGenContext context, uint encoding);
+ static abstract void UsaxA1(CodeGenContext context, uint encoding);
+ static abstract void UsaxT1(CodeGenContext context, uint encoding);
+ static abstract void Usub16A1(CodeGenContext context, uint encoding);
+ static abstract void Usub16T1(CodeGenContext context, uint encoding);
+ static abstract void Usub8A1(CodeGenContext context, uint encoding);
+ static abstract void Usub8T1(CodeGenContext context, uint encoding);
+ static abstract void UxtabA1(CodeGenContext context, uint encoding);
+ static abstract void UxtabT1(CodeGenContext context, uint encoding);
+ static abstract void Uxtab16A1(CodeGenContext context, uint encoding);
+ static abstract void Uxtab16T1(CodeGenContext context, uint encoding);
+ static abstract void UxtahA1(CodeGenContext context, uint encoding);
+ static abstract void UxtahT1(CodeGenContext context, uint encoding);
+ static abstract void UxtbA1(CodeGenContext context, uint encoding);
+ static abstract void UxtbT1(CodeGenContext context, uint encoding);
+ static abstract void UxtbT2(CodeGenContext context, uint encoding);
+ static abstract void Uxtb16A1(CodeGenContext context, uint encoding);
+ static abstract void Uxtb16T1(CodeGenContext context, uint encoding);
+ static abstract void UxthA1(CodeGenContext context, uint encoding);
+ static abstract void UxthT1(CodeGenContext context, uint encoding);
+ static abstract void UxthT2(CodeGenContext context, uint encoding);
+ static abstract void VabaA1(CodeGenContext context, uint encoding);
+ static abstract void VabaT1(CodeGenContext context, uint encoding);
+ static abstract void VabalA1(CodeGenContext context, uint encoding);
+ static abstract void VabalT1(CodeGenContext context, uint encoding);
+ static abstract void VabdlIA1(CodeGenContext context, uint encoding);
+ static abstract void VabdlIT1(CodeGenContext context, uint encoding);
+ static abstract void VabdFA1(CodeGenContext context, uint encoding);
+ static abstract void VabdFT1(CodeGenContext context, uint encoding);
+ static abstract void VabdIA1(CodeGenContext context, uint encoding);
+ static abstract void VabdIT1(CodeGenContext context, uint encoding);
+ static abstract void VabsA1(CodeGenContext context, uint encoding);
+ static abstract void VabsA2(CodeGenContext context, uint encoding);
+ static abstract void VabsT1(CodeGenContext context, uint encoding);
+ static abstract void VabsT2(CodeGenContext context, uint encoding);
+ static abstract void VacgeA1(CodeGenContext context, uint encoding);
+ static abstract void VacgeT1(CodeGenContext context, uint encoding);
+ static abstract void VacgtA1(CodeGenContext context, uint encoding);
+ static abstract void VacgtT1(CodeGenContext context, uint encoding);
+ static abstract void VaddhnA1(CodeGenContext context, uint encoding);
+ static abstract void VaddhnT1(CodeGenContext context, uint encoding);
+ static abstract void VaddlA1(CodeGenContext context, uint encoding);
+ static abstract void VaddlT1(CodeGenContext context, uint encoding);
+ static abstract void VaddwA1(CodeGenContext context, uint encoding);
+ static abstract void VaddwT1(CodeGenContext context, uint encoding);
+ static abstract void VaddFA1(CodeGenContext context, uint encoding);
+ static abstract void VaddFA2(CodeGenContext context, uint encoding);
+ static abstract void VaddFT1(CodeGenContext context, uint encoding);
+ static abstract void VaddFT2(CodeGenContext context, uint encoding);
+ static abstract void VaddIA1(CodeGenContext context, uint encoding);
+ static abstract void VaddIT1(CodeGenContext context, uint encoding);
+ static abstract void VandRA1(CodeGenContext context, uint encoding);
+ static abstract void VandRT1(CodeGenContext context, uint encoding);
+ static abstract void VbicIA1(CodeGenContext context, uint encoding);
+ static abstract void VbicIA2(CodeGenContext context, uint encoding);
+ static abstract void VbicIT1(CodeGenContext context, uint encoding);
+ static abstract void VbicIT2(CodeGenContext context, uint encoding);
+ static abstract void VbicRA1(CodeGenContext context, uint encoding);
+ static abstract void VbicRT1(CodeGenContext context, uint encoding);
+ static abstract void VbifA1(CodeGenContext context, uint encoding);
+ static abstract void VbifT1(CodeGenContext context, uint encoding);
+ static abstract void VbitA1(CodeGenContext context, uint encoding);
+ static abstract void VbitT1(CodeGenContext context, uint encoding);
+ static abstract void VbslA1(CodeGenContext context, uint encoding);
+ static abstract void VbslT1(CodeGenContext context, uint encoding);
+ static abstract void VcaddA1(CodeGenContext context, uint encoding);
+ static abstract void VcaddT1(CodeGenContext context, uint encoding);
+ static abstract void VceqIA1(CodeGenContext context, uint encoding);
+ static abstract void VceqIT1(CodeGenContext context, uint encoding);
+ static abstract void VceqRA1(CodeGenContext context, uint encoding);
+ static abstract void VceqRA2(CodeGenContext context, uint encoding);
+ static abstract void VceqRT1(CodeGenContext context, uint encoding);
+ static abstract void VceqRT2(CodeGenContext context, uint encoding);
+ static abstract void VcgeIA1(CodeGenContext context, uint encoding);
+ static abstract void VcgeIT1(CodeGenContext context, uint encoding);
+ static abstract void VcgeRA1(CodeGenContext context, uint encoding);
+ static abstract void VcgeRA2(CodeGenContext context, uint encoding);
+ static abstract void VcgeRT1(CodeGenContext context, uint encoding);
+ static abstract void VcgeRT2(CodeGenContext context, uint encoding);
+ static abstract void VcgtIA1(CodeGenContext context, uint encoding);
+ static abstract void VcgtIT1(CodeGenContext context, uint encoding);
+ static abstract void VcgtRA1(CodeGenContext context, uint encoding);
+ static abstract void VcgtRA2(CodeGenContext context, uint encoding);
+ static abstract void VcgtRT1(CodeGenContext context, uint encoding);
+ static abstract void VcgtRT2(CodeGenContext context, uint encoding);
+ static abstract void VcleIA1(CodeGenContext context, uint encoding);
+ static abstract void VcleIT1(CodeGenContext context, uint encoding);
+ static abstract void VclsA1(CodeGenContext context, uint encoding);
+ static abstract void VclsT1(CodeGenContext context, uint encoding);
+ static abstract void VcltIA1(CodeGenContext context, uint encoding);
+ static abstract void VcltIT1(CodeGenContext context, uint encoding);
+ static abstract void VclzA1(CodeGenContext context, uint encoding);
+ static abstract void VclzT1(CodeGenContext context, uint encoding);
+ static abstract void VcmlaA1(CodeGenContext context, uint encoding);
+ static abstract void VcmlaT1(CodeGenContext context, uint encoding);
+ static abstract void VcmlaSA1(CodeGenContext context, uint encoding);
+ static abstract void VcmlaST1(CodeGenContext context, uint encoding);
+ static abstract void VcmpA1(CodeGenContext context, uint encoding);
+ static abstract void VcmpA2(CodeGenContext context, uint encoding);
+ static abstract void VcmpT1(CodeGenContext context, uint encoding);
+ static abstract void VcmpT2(CodeGenContext context, uint encoding);
+ static abstract void VcmpeA1(CodeGenContext context, uint encoding);
+ static abstract void VcmpeA2(CodeGenContext context, uint encoding);
+ static abstract void VcmpeT1(CodeGenContext context, uint encoding);
+ static abstract void VcmpeT2(CodeGenContext context, uint encoding);
+ static abstract void VcntA1(CodeGenContext context, uint encoding);
+ static abstract void VcntT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtaAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtaAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtaVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtaVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtbA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtbT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtbBfsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtbBfsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtmAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtmAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtmVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtmVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtnAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtnAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtnVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtnVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtpAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtpAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtpVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtpVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtrIvA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtrIvT1(CodeGenContext context, uint encoding);
+ static abstract void VcvttA1(CodeGenContext context, uint encoding);
+ static abstract void VcvttT1(CodeGenContext context, uint encoding);
+ static abstract void VcvttBfsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvttBfsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtBfsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtBfsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtDsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtDsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtHsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtHsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtIsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtIsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtIvA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtIvT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtViA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtViT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtXsA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtXsT1(CodeGenContext context, uint encoding);
+ static abstract void VcvtXvA1(CodeGenContext context, uint encoding);
+ static abstract void VcvtXvT1(CodeGenContext context, uint encoding);
+ static abstract void VdivA1(CodeGenContext context, uint encoding);
+ static abstract void VdivT1(CodeGenContext context, uint encoding);
+ static abstract void VdotA1(CodeGenContext context, uint encoding);
+ static abstract void VdotT1(CodeGenContext context, uint encoding);
+ static abstract void VdotSA1(CodeGenContext context, uint encoding);
+ static abstract void VdotST1(CodeGenContext context, uint encoding);
+ static abstract void VdupRA1(CodeGenContext context, uint encoding);
+ static abstract void VdupRT1(CodeGenContext context, uint encoding);
+ static abstract void VdupSA1(CodeGenContext context, uint encoding);
+ static abstract void VdupST1(CodeGenContext context, uint encoding);
+ static abstract void VeorA1(CodeGenContext context, uint encoding);
+ static abstract void VeorT1(CodeGenContext context, uint encoding);
+ static abstract void VextA1(CodeGenContext context, uint encoding);
+ static abstract void VextT1(CodeGenContext context, uint encoding);
+ static abstract void VfmaA1(CodeGenContext context, uint encoding);
+ static abstract void VfmaA2(CodeGenContext context, uint encoding);
+ static abstract void VfmaT1(CodeGenContext context, uint encoding);
+ static abstract void VfmaT2(CodeGenContext context, uint encoding);
+ static abstract void VfmalA1(CodeGenContext context, uint encoding);
+ static abstract void VfmalT1(CodeGenContext context, uint encoding);
+ static abstract void VfmalSA1(CodeGenContext context, uint encoding);
+ static abstract void VfmalST1(CodeGenContext context, uint encoding);
+ static abstract void VfmaBfA1(CodeGenContext context, uint encoding);
+ static abstract void VfmaBfT1(CodeGenContext context, uint encoding);
+ static abstract void VfmaBfsA1(CodeGenContext context, uint encoding);
+ static abstract void VfmaBfsT1(CodeGenContext context, uint encoding);
+ static abstract void VfmsA1(CodeGenContext context, uint encoding);
+ static abstract void VfmsA2(CodeGenContext context, uint encoding);
+ static abstract void VfmsT1(CodeGenContext context, uint encoding);
+ static abstract void VfmsT2(CodeGenContext context, uint encoding);
+ static abstract void VfmslA1(CodeGenContext context, uint encoding);
+ static abstract void VfmslT1(CodeGenContext context, uint encoding);
+ static abstract void VfmslSA1(CodeGenContext context, uint encoding);
+ static abstract void VfmslST1(CodeGenContext context, uint encoding);
+ static abstract void VfnmaA1(CodeGenContext context, uint encoding);
+ static abstract void VfnmaT1(CodeGenContext context, uint encoding);
+ static abstract void VfnmsA1(CodeGenContext context, uint encoding);
+ static abstract void VfnmsT1(CodeGenContext context, uint encoding);
+ static abstract void VhaddA1(CodeGenContext context, uint encoding);
+ static abstract void VhaddT1(CodeGenContext context, uint encoding);
+ static abstract void VhsubA1(CodeGenContext context, uint encoding);
+ static abstract void VhsubT1(CodeGenContext context, uint encoding);
+ static abstract void VinsA1(CodeGenContext context, uint encoding);
+ static abstract void VinsT1(CodeGenContext context, uint encoding);
+ static abstract void VjcvtA1(CodeGenContext context, uint encoding);
+ static abstract void VjcvtT1(CodeGenContext context, uint encoding);
+ static abstract void Vld11A1(CodeGenContext context, uint encoding);
+ static abstract void Vld11A2(CodeGenContext context, uint encoding);
+ static abstract void Vld11A3(CodeGenContext context, uint encoding);
+ static abstract void Vld11T1(CodeGenContext context, uint encoding);
+ static abstract void Vld11T2(CodeGenContext context, uint encoding);
+ static abstract void Vld11T3(CodeGenContext context, uint encoding);
+ static abstract void Vld1AA1(CodeGenContext context, uint encoding);
+ static abstract void Vld1AT1(CodeGenContext context, uint encoding);
+ static abstract void Vld1MA1(CodeGenContext context, uint encoding);
+ static abstract void Vld1MA2(CodeGenContext context, uint encoding);
+ static abstract void Vld1MA3(CodeGenContext context, uint encoding);
+ static abstract void Vld1MA4(CodeGenContext context, uint encoding);
+ static abstract void Vld1MT1(CodeGenContext context, uint encoding);
+ static abstract void Vld1MT2(CodeGenContext context, uint encoding);
+ static abstract void Vld1MT3(CodeGenContext context, uint encoding);
+ static abstract void Vld1MT4(CodeGenContext context, uint encoding);
+ static abstract void Vld21A1(CodeGenContext context, uint encoding);
+ static abstract void Vld21A2(CodeGenContext context, uint encoding);
+ static abstract void Vld21A3(CodeGenContext context, uint encoding);
+ static abstract void Vld21T1(CodeGenContext context, uint encoding);
+ static abstract void Vld21T2(CodeGenContext context, uint encoding);
+ static abstract void Vld21T3(CodeGenContext context, uint encoding);
+ static abstract void Vld2AA1(CodeGenContext context, uint encoding);
+ static abstract void Vld2AT1(CodeGenContext context, uint encoding);
+ static abstract void Vld2MA1(CodeGenContext context, uint encoding);
+ static abstract void Vld2MA2(CodeGenContext context, uint encoding);
+ static abstract void Vld2MT1(CodeGenContext context, uint encoding);
+ static abstract void Vld2MT2(CodeGenContext context, uint encoding);
+ static abstract void Vld31A1(CodeGenContext context, uint encoding);
+ static abstract void Vld31A2(CodeGenContext context, uint encoding);
+ static abstract void Vld31A3(CodeGenContext context, uint encoding);
+ static abstract void Vld31T1(CodeGenContext context, uint encoding);
+ static abstract void Vld31T2(CodeGenContext context, uint encoding);
+ static abstract void Vld31T3(CodeGenContext context, uint encoding);
+ static abstract void Vld3AA1(CodeGenContext context, uint encoding);
+ static abstract void Vld3AT1(CodeGenContext context, uint encoding);
+ static abstract void Vld3MA1(CodeGenContext context, uint encoding);
+ static abstract void Vld3MT1(CodeGenContext context, uint encoding);
+ static abstract void Vld41A1(CodeGenContext context, uint encoding);
+ static abstract void Vld41A2(CodeGenContext context, uint encoding);
+ static abstract void Vld41A3(CodeGenContext context, uint encoding);
+ static abstract void Vld41T1(CodeGenContext context, uint encoding);
+ static abstract void Vld41T2(CodeGenContext context, uint encoding);
+ static abstract void Vld41T3(CodeGenContext context, uint encoding);
+ static abstract void Vld4AA1(CodeGenContext context, uint encoding);
+ static abstract void Vld4AT1(CodeGenContext context, uint encoding);
+ static abstract void Vld4MA1(CodeGenContext context, uint encoding);
+ static abstract void Vld4MT1(CodeGenContext context, uint encoding);
+ static abstract void VldmA1(CodeGenContext context, uint encoding);
+ static abstract void VldmA2(CodeGenContext context, uint encoding);
+ static abstract void VldmT1(CodeGenContext context, uint encoding);
+ static abstract void VldmT2(CodeGenContext context, uint encoding);
+ static abstract void VldrIA1(CodeGenContext context, uint encoding);
+ static abstract void VldrIT1(CodeGenContext context, uint encoding);
+ static abstract void VldrLA1(CodeGenContext context, uint encoding);
+ static abstract void VldrLT1(CodeGenContext context, uint encoding);
+ static abstract void VmaxnmA1(CodeGenContext context, uint encoding);
+ static abstract void VmaxnmA2(CodeGenContext context, uint encoding);
+ static abstract void VmaxnmT1(CodeGenContext context, uint encoding);
+ static abstract void VmaxnmT2(CodeGenContext context, uint encoding);
+ static abstract void VmaxFA1(CodeGenContext context, uint encoding);
+ static abstract void VmaxFT1(CodeGenContext context, uint encoding);
+ static abstract void VmaxIA1(CodeGenContext context, uint encoding);
+ static abstract void VmaxIT1(CodeGenContext context, uint encoding);
+ static abstract void VminnmA1(CodeGenContext context, uint encoding);
+ static abstract void VminnmA2(CodeGenContext context, uint encoding);
+ static abstract void VminnmT1(CodeGenContext context, uint encoding);
+ static abstract void VminnmT2(CodeGenContext context, uint encoding);
+ static abstract void VminFA1(CodeGenContext context, uint encoding);
+ static abstract void VminFT1(CodeGenContext context, uint encoding);
+ static abstract void VminIA1(CodeGenContext context, uint encoding);
+ static abstract void VminIT1(CodeGenContext context, uint encoding);
+ static abstract void VmlalIA1(CodeGenContext context, uint encoding);
+ static abstract void VmlalIT1(CodeGenContext context, uint encoding);
+ static abstract void VmlalSA1(CodeGenContext context, uint encoding);
+ static abstract void VmlalST1(CodeGenContext context, uint encoding);
+ static abstract void VmlaFA1(CodeGenContext context, uint encoding);
+ static abstract void VmlaFA2(CodeGenContext context, uint encoding);
+ static abstract void VmlaFT1(CodeGenContext context, uint encoding);
+ static abstract void VmlaFT2(CodeGenContext context, uint encoding);
+ static abstract void VmlaIA1(CodeGenContext context, uint encoding);
+ static abstract void VmlaIT1(CodeGenContext context, uint encoding);
+ static abstract void VmlaSA1(CodeGenContext context, uint encoding);
+ static abstract void VmlaST1(CodeGenContext context, uint encoding);
+ static abstract void VmlslIA1(CodeGenContext context, uint encoding);
+ static abstract void VmlslIT1(CodeGenContext context, uint encoding);
+ static abstract void VmlslSA1(CodeGenContext context, uint encoding);
+ static abstract void VmlslST1(CodeGenContext context, uint encoding);
+ static abstract void VmlsFA1(CodeGenContext context, uint encoding);
+ static abstract void VmlsFA2(CodeGenContext context, uint encoding);
+ static abstract void VmlsFT1(CodeGenContext context, uint encoding);
+ static abstract void VmlsFT2(CodeGenContext context, uint encoding);
+ static abstract void VmlsIA1(CodeGenContext context, uint encoding);
+ static abstract void VmlsIT1(CodeGenContext context, uint encoding);
+ static abstract void VmlsSA1(CodeGenContext context, uint encoding);
+ static abstract void VmlsST1(CodeGenContext context, uint encoding);
+ static abstract void VmmlaA1(CodeGenContext context, uint encoding);
+ static abstract void VmmlaT1(CodeGenContext context, uint encoding);
+ static abstract void VmovlA1(CodeGenContext context, uint encoding);
+ static abstract void VmovlT1(CodeGenContext context, uint encoding);
+ static abstract void VmovnA1(CodeGenContext context, uint encoding);
+ static abstract void VmovnT1(CodeGenContext context, uint encoding);
+ static abstract void VmovxA1(CodeGenContext context, uint encoding);
+ static abstract void VmovxT1(CodeGenContext context, uint encoding);
+ static abstract void VmovDA1(CodeGenContext context, uint encoding);
+ static abstract void VmovDT1(CodeGenContext context, uint encoding);
+ static abstract void VmovHA1(CodeGenContext context, uint encoding);
+ static abstract void VmovHT1(CodeGenContext context, uint encoding);
+ static abstract void VmovIA1(CodeGenContext context, uint encoding);
+ static abstract void VmovIA2(CodeGenContext context, uint encoding);
+ static abstract void VmovIA3(CodeGenContext context, uint encoding);
+ static abstract void VmovIA4(CodeGenContext context, uint encoding);
+ static abstract void VmovIA5(CodeGenContext context, uint encoding);
+ static abstract void VmovIT1(CodeGenContext context, uint encoding);
+ static abstract void VmovIT2(CodeGenContext context, uint encoding);
+ static abstract void VmovIT3(CodeGenContext context, uint encoding);
+ static abstract void VmovIT4(CodeGenContext context, uint encoding);
+ static abstract void VmovIT5(CodeGenContext context, uint encoding);
+ static abstract void VmovRA2(CodeGenContext context, uint encoding);
+ static abstract void VmovRT2(CodeGenContext context, uint encoding);
+ static abstract void VmovRsA1(CodeGenContext context, uint encoding);
+ static abstract void VmovRsT1(CodeGenContext context, uint encoding);
+ static abstract void VmovSA1(CodeGenContext context, uint encoding);
+ static abstract void VmovST1(CodeGenContext context, uint encoding);
+ static abstract void VmovSrA1(CodeGenContext context, uint encoding);
+ static abstract void VmovSrT1(CodeGenContext context, uint encoding);
+ static abstract void VmovSsA1(CodeGenContext context, uint encoding);
+ static abstract void VmovSsT1(CodeGenContext context, uint encoding);
+ static abstract void VmrsA1(CodeGenContext context, uint encoding);
+ static abstract void VmrsT1(CodeGenContext context, uint encoding);
+ static abstract void VmsrA1(CodeGenContext context, uint encoding);
+ static abstract void VmsrT1(CodeGenContext context, uint encoding);
+ static abstract void VmullIA1(CodeGenContext context, uint encoding);
+ static abstract void VmullIT1(CodeGenContext context, uint encoding);
+ static abstract void VmullSA1(CodeGenContext context, uint encoding);
+ static abstract void VmullST1(CodeGenContext context, uint encoding);
+ static abstract void VmulFA1(CodeGenContext context, uint encoding);
+ static abstract void VmulFA2(CodeGenContext context, uint encoding);
+ static abstract void VmulFT1(CodeGenContext context, uint encoding);
+ static abstract void VmulFT2(CodeGenContext context, uint encoding);
+ static abstract void VmulIA1(CodeGenContext context, uint encoding);
+ static abstract void VmulIT1(CodeGenContext context, uint encoding);
+ static abstract void VmulSA1(CodeGenContext context, uint encoding);
+ static abstract void VmulST1(CodeGenContext context, uint encoding);
+ static abstract void VmvnIA1(CodeGenContext context, uint encoding);
+ static abstract void VmvnIA2(CodeGenContext context, uint encoding);
+ static abstract void VmvnIA3(CodeGenContext context, uint encoding);
+ static abstract void VmvnIT1(CodeGenContext context, uint encoding);
+ static abstract void VmvnIT2(CodeGenContext context, uint encoding);
+ static abstract void VmvnIT3(CodeGenContext context, uint encoding);
+ static abstract void VmvnRA1(CodeGenContext context, uint encoding);
+ static abstract void VmvnRT1(CodeGenContext context, uint encoding);
+ static abstract void VnegA1(CodeGenContext context, uint encoding);
+ static abstract void VnegA2(CodeGenContext context, uint encoding);
+ static abstract void VnegT1(CodeGenContext context, uint encoding);
+ static abstract void VnegT2(CodeGenContext context, uint encoding);
+ static abstract void VnmlaA1(CodeGenContext context, uint encoding);
+ static abstract void VnmlaT1(CodeGenContext context, uint encoding);
+ static abstract void VnmlsA1(CodeGenContext context, uint encoding);
+ static abstract void VnmlsT1(CodeGenContext context, uint encoding);
+ static abstract void VnmulA1(CodeGenContext context, uint encoding);
+ static abstract void VnmulT1(CodeGenContext context, uint encoding);
+ static abstract void VornRA1(CodeGenContext context, uint encoding);
+ static abstract void VornRT1(CodeGenContext context, uint encoding);
+ static abstract void VorrIA1(CodeGenContext context, uint encoding);
+ static abstract void VorrIA2(CodeGenContext context, uint encoding);
+ static abstract void VorrIT1(CodeGenContext context, uint encoding);
+ static abstract void VorrIT2(CodeGenContext context, uint encoding);
+ static abstract void VorrRA1(CodeGenContext context, uint encoding);
+ static abstract void VorrRT1(CodeGenContext context, uint encoding);
+ static abstract void VpadalA1(CodeGenContext context, uint encoding);
+ static abstract void VpadalT1(CodeGenContext context, uint encoding);
+ static abstract void VpaddlA1(CodeGenContext context, uint encoding);
+ static abstract void VpaddlT1(CodeGenContext context, uint encoding);
+ static abstract void VpaddFA1(CodeGenContext context, uint encoding);
+ static abstract void VpaddFT1(CodeGenContext context, uint encoding);
+ static abstract void VpaddIA1(CodeGenContext context, uint encoding);
+ static abstract void VpaddIT1(CodeGenContext context, uint encoding);
+ static abstract void VpmaxFA1(CodeGenContext context, uint encoding);
+ static abstract void VpmaxFT1(CodeGenContext context, uint encoding);
+ static abstract void VpmaxIA1(CodeGenContext context, uint encoding);
+ static abstract void VpmaxIT1(CodeGenContext context, uint encoding);
+ static abstract void VpminFA1(CodeGenContext context, uint encoding);
+ static abstract void VpminFT1(CodeGenContext context, uint encoding);
+ static abstract void VpminIA1(CodeGenContext context, uint encoding);
+ static abstract void VpminIT1(CodeGenContext context, uint encoding);
+ static abstract void VqabsA1(CodeGenContext context, uint encoding);
+ static abstract void VqabsT1(CodeGenContext context, uint encoding);
+ static abstract void VqaddA1(CodeGenContext context, uint encoding);
+ static abstract void VqaddT1(CodeGenContext context, uint encoding);
+ static abstract void VqdmlalA1(CodeGenContext context, uint encoding);
+ static abstract void VqdmlalA2(CodeGenContext context, uint encoding);
+ static abstract void VqdmlalT1(CodeGenContext context, uint encoding);
+ static abstract void VqdmlalT2(CodeGenContext context, uint encoding);
+ static abstract void VqdmlslA1(CodeGenContext context, uint encoding);
+ static abstract void VqdmlslA2(CodeGenContext context, uint encoding);
+ static abstract void VqdmlslT1(CodeGenContext context, uint encoding);
+ static abstract void VqdmlslT2(CodeGenContext context, uint encoding);
+ static abstract void VqdmulhA1(CodeGenContext context, uint encoding);
+ static abstract void VqdmulhA2(CodeGenContext context, uint encoding);
+ static abstract void VqdmulhT1(CodeGenContext context, uint encoding);
+ static abstract void VqdmulhT2(CodeGenContext context, uint encoding);
+ static abstract void VqdmullA1(CodeGenContext context, uint encoding);
+ static abstract void VqdmullA2(CodeGenContext context, uint encoding);
+ static abstract void VqdmullT1(CodeGenContext context, uint encoding);
+ static abstract void VqdmullT2(CodeGenContext context, uint encoding);
+ static abstract void VqmovnA1(CodeGenContext context, uint encoding);
+ static abstract void VqmovnT1(CodeGenContext context, uint encoding);
+ static abstract void VqnegA1(CodeGenContext context, uint encoding);
+ static abstract void VqnegT1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlahA1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlahA2(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlahT1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlahT2(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlshA1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlshA2(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlshT1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmlshT2(CodeGenContext context, uint encoding);
+ static abstract void VqrdmulhA1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmulhA2(CodeGenContext context, uint encoding);
+ static abstract void VqrdmulhT1(CodeGenContext context, uint encoding);
+ static abstract void VqrdmulhT2(CodeGenContext context, uint encoding);
+ static abstract void VqrshlA1(CodeGenContext context, uint encoding);
+ static abstract void VqrshlT1(CodeGenContext context, uint encoding);
+ static abstract void VqrshrnA1(CodeGenContext context, uint encoding);
+ static abstract void VqrshrnT1(CodeGenContext context, uint encoding);
+ static abstract void VqshlIA1(CodeGenContext context, uint encoding);
+ static abstract void VqshlIT1(CodeGenContext context, uint encoding);
+ static abstract void VqshlRA1(CodeGenContext context, uint encoding);
+ static abstract void VqshlRT1(CodeGenContext context, uint encoding);
+ static abstract void VqshrnA1(CodeGenContext context, uint encoding);
+ static abstract void VqshrnT1(CodeGenContext context, uint encoding);
+ static abstract void VqsubA1(CodeGenContext context, uint encoding);
+ static abstract void VqsubT1(CodeGenContext context, uint encoding);
+ static abstract void VraddhnA1(CodeGenContext context, uint encoding);
+ static abstract void VraddhnT1(CodeGenContext context, uint encoding);
+ static abstract void VrecpeA1(CodeGenContext context, uint encoding);
+ static abstract void VrecpeT1(CodeGenContext context, uint encoding);
+ static abstract void VrecpsA1(CodeGenContext context, uint encoding);
+ static abstract void VrecpsT1(CodeGenContext context, uint encoding);
+ static abstract void Vrev16A1(CodeGenContext context, uint encoding);
+ static abstract void Vrev16T1(CodeGenContext context, uint encoding);
+ static abstract void Vrev32A1(CodeGenContext context, uint encoding);
+ static abstract void Vrev32T1(CodeGenContext context, uint encoding);
+ static abstract void Vrev64A1(CodeGenContext context, uint encoding);
+ static abstract void Vrev64T1(CodeGenContext context, uint encoding);
+ static abstract void VrhaddA1(CodeGenContext context, uint encoding);
+ static abstract void VrhaddT1(CodeGenContext context, uint encoding);
+ static abstract void VrintaAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintaAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintaVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintaVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintmAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintmAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintmVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintmVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintnAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintnAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintnVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintnVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintpAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintpAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintpVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintpVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintrVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintrVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintxAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintxAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintxVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintxVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrintzAsimdA1(CodeGenContext context, uint encoding);
+ static abstract void VrintzAsimdT1(CodeGenContext context, uint encoding);
+ static abstract void VrintzVfpA1(CodeGenContext context, uint encoding);
+ static abstract void VrintzVfpT1(CodeGenContext context, uint encoding);
+ static abstract void VrshlA1(CodeGenContext context, uint encoding);
+ static abstract void VrshlT1(CodeGenContext context, uint encoding);
+ static abstract void VrshrA1(CodeGenContext context, uint encoding);
+ static abstract void VrshrT1(CodeGenContext context, uint encoding);
+ static abstract void VrshrnA1(CodeGenContext context, uint encoding);
+ static abstract void VrshrnT1(CodeGenContext context, uint encoding);
+ static abstract void VrsqrteA1(CodeGenContext context, uint encoding);
+ static abstract void VrsqrteT1(CodeGenContext context, uint encoding);
+ static abstract void VrsqrtsA1(CodeGenContext context, uint encoding);
+ static abstract void VrsqrtsT1(CodeGenContext context, uint encoding);
+ static abstract void VrsraA1(CodeGenContext context, uint encoding);
+ static abstract void VrsraT1(CodeGenContext context, uint encoding);
+ static abstract void VrsubhnA1(CodeGenContext context, uint encoding);
+ static abstract void VrsubhnT1(CodeGenContext context, uint encoding);
+ static abstract void VsdotA1(CodeGenContext context, uint encoding);
+ static abstract void VsdotT1(CodeGenContext context, uint encoding);
+ static abstract void VsdotSA1(CodeGenContext context, uint encoding);
+ static abstract void VsdotST1(CodeGenContext context, uint encoding);
+ static abstract void VselA1(CodeGenContext context, uint encoding);
+ static abstract void VselT1(CodeGenContext context, uint encoding);
+ static abstract void VshllA1(CodeGenContext context, uint encoding);
+ static abstract void VshllA2(CodeGenContext context, uint encoding);
+ static abstract void VshllT1(CodeGenContext context, uint encoding);
+ static abstract void VshllT2(CodeGenContext context, uint encoding);
+ static abstract void VshlIA1(CodeGenContext context, uint encoding);
+ static abstract void VshlIT1(CodeGenContext context, uint encoding);
+ static abstract void VshlRA1(CodeGenContext context, uint encoding);
+ static abstract void VshlRT1(CodeGenContext context, uint encoding);
+ static abstract void VshrA1(CodeGenContext context, uint encoding);
+ static abstract void VshrT1(CodeGenContext context, uint encoding);
+ static abstract void VshrnA1(CodeGenContext context, uint encoding);
+ static abstract void VshrnT1(CodeGenContext context, uint encoding);
+ static abstract void VsliA1(CodeGenContext context, uint encoding);
+ static abstract void VsliT1(CodeGenContext context, uint encoding);
+ static abstract void VsmmlaA1(CodeGenContext context, uint encoding);
+ static abstract void VsmmlaT1(CodeGenContext context, uint encoding);
+ static abstract void VsqrtA1(CodeGenContext context, uint encoding);
+ static abstract void VsqrtT1(CodeGenContext context, uint encoding);
+ static abstract void VsraA1(CodeGenContext context, uint encoding);
+ static abstract void VsraT1(CodeGenContext context, uint encoding);
+ static abstract void VsriA1(CodeGenContext context, uint encoding);
+ static abstract void VsriT1(CodeGenContext context, uint encoding);
+ static abstract void Vst11A1(CodeGenContext context, uint encoding);
+ static abstract void Vst11A2(CodeGenContext context, uint encoding);
+ static abstract void Vst11A3(CodeGenContext context, uint encoding);
+ static abstract void Vst11T1(CodeGenContext context, uint encoding);
+ static abstract void Vst11T2(CodeGenContext context, uint encoding);
+ static abstract void Vst11T3(CodeGenContext context, uint encoding);
+ static abstract void Vst1MA1(CodeGenContext context, uint encoding);
+ static abstract void Vst1MA2(CodeGenContext context, uint encoding);
+ static abstract void Vst1MA3(CodeGenContext context, uint encoding);
+ static abstract void Vst1MA4(CodeGenContext context, uint encoding);
+ static abstract void Vst1MT1(CodeGenContext context, uint encoding);
+ static abstract void Vst1MT2(CodeGenContext context, uint encoding);
+ static abstract void Vst1MT3(CodeGenContext context, uint encoding);
+ static abstract void Vst1MT4(CodeGenContext context, uint encoding);
+ static abstract void Vst21A1(CodeGenContext context, uint encoding);
+ static abstract void Vst21A2(CodeGenContext context, uint encoding);
+ static abstract void Vst21A3(CodeGenContext context, uint encoding);
+ static abstract void Vst21T1(CodeGenContext context, uint encoding);
+ static abstract void Vst21T2(CodeGenContext context, uint encoding);
+ static abstract void Vst21T3(CodeGenContext context, uint encoding);
+ static abstract void Vst2MA1(CodeGenContext context, uint encoding);
+ static abstract void Vst2MA2(CodeGenContext context, uint encoding);
+ static abstract void Vst2MT1(CodeGenContext context, uint encoding);
+ static abstract void Vst2MT2(CodeGenContext context, uint encoding);
+ static abstract void Vst31A1(CodeGenContext context, uint encoding);
+ static abstract void Vst31A2(CodeGenContext context, uint encoding);
+ static abstract void Vst31A3(CodeGenContext context, uint encoding);
+ static abstract void Vst31T1(CodeGenContext context, uint encoding);
+ static abstract void Vst31T2(CodeGenContext context, uint encoding);
+ static abstract void Vst31T3(CodeGenContext context, uint encoding);
+ static abstract void Vst3MA1(CodeGenContext context, uint encoding);
+ static abstract void Vst3MT1(CodeGenContext context, uint encoding);
+ static abstract void Vst41A1(CodeGenContext context, uint encoding);
+ static abstract void Vst41A2(CodeGenContext context, uint encoding);
+ static abstract void Vst41A3(CodeGenContext context, uint encoding);
+ static abstract void Vst41T1(CodeGenContext context, uint encoding);
+ static abstract void Vst41T2(CodeGenContext context, uint encoding);
+ static abstract void Vst41T3(CodeGenContext context, uint encoding);
+ static abstract void Vst4MA1(CodeGenContext context, uint encoding);
+ static abstract void Vst4MT1(CodeGenContext context, uint encoding);
+ static abstract void VstmA1(CodeGenContext context, uint encoding);
+ static abstract void VstmA2(CodeGenContext context, uint encoding);
+ static abstract void VstmT1(CodeGenContext context, uint encoding);
+ static abstract void VstmT2(CodeGenContext context, uint encoding);
+ static abstract void VstrA1(CodeGenContext context, uint encoding);
+ static abstract void VstrT1(CodeGenContext context, uint encoding);
+ static abstract void VsubhnA1(CodeGenContext context, uint encoding);
+ static abstract void VsubhnT1(CodeGenContext context, uint encoding);
+ static abstract void VsublA1(CodeGenContext context, uint encoding);
+ static abstract void VsublT1(CodeGenContext context, uint encoding);
+ static abstract void VsubwA1(CodeGenContext context, uint encoding);
+ static abstract void VsubwT1(CodeGenContext context, uint encoding);
+ static abstract void VsubFA1(CodeGenContext context, uint encoding);
+ static abstract void VsubFA2(CodeGenContext context, uint encoding);
+ static abstract void VsubFT1(CodeGenContext context, uint encoding);
+ static abstract void VsubFT2(CodeGenContext context, uint encoding);
+ static abstract void VsubIA1(CodeGenContext context, uint encoding);
+ static abstract void VsubIT1(CodeGenContext context, uint encoding);
+ static abstract void VsudotSA1(CodeGenContext context, uint encoding);
+ static abstract void VsudotST1(CodeGenContext context, uint encoding);
+ static abstract void VswpA1(CodeGenContext context, uint encoding);
+ static abstract void VswpT1(CodeGenContext context, uint encoding);
+ static abstract void VtblA1(CodeGenContext context, uint encoding);
+ static abstract void VtblT1(CodeGenContext context, uint encoding);
+ static abstract void VtrnA1(CodeGenContext context, uint encoding);
+ static abstract void VtrnT1(CodeGenContext context, uint encoding);
+ static abstract void VtstA1(CodeGenContext context, uint encoding);
+ static abstract void VtstT1(CodeGenContext context, uint encoding);
+ static abstract void VudotA1(CodeGenContext context, uint encoding);
+ static abstract void VudotT1(CodeGenContext context, uint encoding);
+ static abstract void VudotSA1(CodeGenContext context, uint encoding);
+ static abstract void VudotST1(CodeGenContext context, uint encoding);
+ static abstract void VummlaA1(CodeGenContext context, uint encoding);
+ static abstract void VummlaT1(CodeGenContext context, uint encoding);
+ static abstract void VusdotA1(CodeGenContext context, uint encoding);
+ static abstract void VusdotT1(CodeGenContext context, uint encoding);
+ static abstract void VusdotSA1(CodeGenContext context, uint encoding);
+ static abstract void VusdotST1(CodeGenContext context, uint encoding);
+ static abstract void VusmmlaA1(CodeGenContext context, uint encoding);
+ static abstract void VusmmlaT1(CodeGenContext context, uint encoding);
+ static abstract void VuzpA1(CodeGenContext context, uint encoding);
+ static abstract void VuzpT1(CodeGenContext context, uint encoding);
+ static abstract void VzipA1(CodeGenContext context, uint encoding);
+ static abstract void VzipT1(CodeGenContext context, uint encoding);
+ static abstract void WfeA1(CodeGenContext context, uint encoding);
+ static abstract void WfeT1(CodeGenContext context, uint encoding);
+ static abstract void WfeT2(CodeGenContext context, uint encoding);
+ static abstract void WfiA1(CodeGenContext context, uint encoding);
+ static abstract void WfiT1(CodeGenContext context, uint encoding);
+ static abstract void WfiT2(CodeGenContext context, uint encoding);
+ static abstract void YieldA1(CodeGenContext context, uint encoding);
+ static abstract void YieldT1(CodeGenContext context, uint encoding);
+ static abstract void YieldT2(CodeGenContext context, uint encoding);
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs
new file mode 100644
index 00000000..516845fc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs
@@ -0,0 +1,137 @@
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class ImmUtils
+ {
+ public static uint ExpandImm(uint imm)
+ {
+ return BitOperations.RotateRight((byte)imm, (int)(imm >> 8) * 2);
+ }
+
+ public static bool ExpandedImmRotated(uint imm)
+ {
+ return (imm >> 8) != 0;
+ }
+
+ public static uint ExpandImm(uint imm8, uint imm3, uint i)
+ {
+ uint imm = CombineImmU12(imm8, imm3, i);
+
+ if (imm >> 10 == 0)
+ {
+ return ((imm >> 8) & 3) switch
+ {
+ 0 => (byte)imm,
+ 1 => (byte)imm * 0x00010001u,
+ 2 => (byte)imm * 0x01000100u,
+ 3 => (byte)imm * 0x01010101u,
+ _ => 0,
+ };
+ }
+ else
+ {
+ return BitOperations.RotateRight(0x80u | (byte)imm, (int)(imm >> 7));
+ }
+ }
+
+ public static bool ExpandedImmRotated(uint imm8, uint imm3, uint i)
+ {
+ uint imm = CombineImmU12(imm8, imm3, i);
+
+ return (imm >> 7) != 0;
+ }
+
+ public static uint CombineImmU5(uint imm2, uint imm3)
+ {
+ return imm2 | (imm3 << 2);
+ }
+
+ public static uint CombineImmU5IImm4(uint i, uint imm4)
+ {
+ return i | (imm4 << 1);
+ }
+
+ public static uint CombineImmU8(uint imm4l, uint imm4h)
+ {
+ return imm4l | (imm4h << 4);
+ }
+
+ public static uint CombineImmU8(uint imm4, uint imm3, uint i)
+ {
+ return imm4 | (imm3 << 4) | (i << 7);
+ }
+
+ public static uint CombineImmU12(uint imm8, uint imm3, uint i)
+ {
+ return imm8 | (imm3 << 8) | (i << 11);
+ }
+
+ public static uint CombineImmU16(uint imm12, uint imm4)
+ {
+ return imm12 | (imm4 << 12);
+ }
+
+ public static uint CombineImmU16(uint imm8, uint imm3, uint i, uint imm4)
+ {
+ return imm8 | (imm3 << 8) | (i << 11) | (imm4 << 12);
+ }
+
+ public static int CombineSImm20Times2(uint imm11, uint imm6, uint j1, uint j2, uint s)
+ {
+ int imm32 = (int)(imm11 | (imm6 << 11) | (j1 << 17) | (j2 << 18) | (s << 19));
+
+ return (imm32 << 13) >> 12;
+ }
+
+ public static int CombineSImm24Times2(uint imm11, uint imm10, uint j1, uint j2, uint s)
+ {
+ uint i1 = j1 ^ s ^ 1;
+ uint i2 = j2 ^ s ^ 1;
+
+ int imm32 = (int)(imm11 | (imm10 << 11) | (i2 << 21) | (i1 << 22) | (s << 23));
+
+ return (imm32 << 8) >> 7;
+ }
+
+ public static int CombineSImm24Times4(uint imm10L, uint imm10H, uint j1, uint j2, uint s)
+ {
+ uint i1 = j1 ^ s ^ 1;
+ uint i2 = j2 ^ s ^ 1;
+
+ int imm32 = (int)(imm10L | (imm10H << 10) | (i2 << 20) | (i1 << 21) | (s << 22));
+
+ return (imm32 << 9) >> 7;
+ }
+
+ public static uint CombineRegisterList(uint registerList, uint m)
+ {
+ return registerList | (m << 14);
+ }
+
+ public static uint CombineRegisterList(uint registerList, uint m, uint p)
+ {
+ return registerList | (m << 14) | (p << 15);
+ }
+
+ public static int ExtractSImm24Times4(uint encoding)
+ {
+ return (int)(encoding << 8) >> 6;
+ }
+
+ public static int ExtractT16UImm5Times2(uint encoding)
+ {
+ return (int)(encoding >> 18) & 0x3e;
+ }
+
+ public static int ExtractT16SImm8Times2(uint encoding)
+ {
+ return (int)(encoding << 24) >> 23;
+ }
+
+ public static int ExtractT16SImm11Times2(uint encoding)
+ {
+ return (int)(encoding << 21) >> 20;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs
new file mode 100644
index 00000000..41b105e4
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs
@@ -0,0 +1,2927 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRmb19w3Rdnb16w3
+ {
+ private readonly uint _value;
+ public InstRmb19w3Rdnb16w3(uint value) => _value = value;
+ public readonly uint Rdn => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 4) & 0x3;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Rs => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstImm3b22w3Rnb19w3Rdb16w3
+ {
+ private readonly uint _value;
+ public InstImm3b22w3Rnb19w3Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ public readonly uint Imm3 => (_value >> 22) & 0x7;
+ }
+
+ readonly struct InstRdnb24w3Imm8b16w8
+ {
+ private readonly uint _value;
+ public InstRdnb24w3Imm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ public readonly uint Rdn => (_value >> 24) & 0x7;
+ }
+
+ readonly struct InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstRmb22w3Rnb19w3Rdb16w3
+ {
+ private readonly uint _value;
+ public InstRmb22w3Rnb19w3Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ public readonly uint Rm => (_value >> 22) & 0x7;
+ }
+
+ readonly struct InstDnb23w1Rmb19w4Rdnb16w3
+ {
+ private readonly uint _value;
+ public InstDnb23w1Rmb19w4Rdnb16w3(uint value) => _value = value;
+ public readonly uint Rdn => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0xF;
+ public readonly uint Dn => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRdb24w3Imm8b16w8
+ {
+ private readonly uint _value;
+ public InstRdb24w3Imm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ public readonly uint Rd => (_value >> 24) & 0x7;
+ }
+
+ readonly struct InstImm7b16w7
+ {
+ private readonly uint _value;
+ public InstImm7b16w7(uint value) => _value = value;
+ public readonly uint Imm7 => (_value >> 16) & 0x7F;
+ }
+
+ readonly struct InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDmb23w1Rdmb16w3
+ {
+ private readonly uint _value;
+ public InstDmb23w1Rdmb16w3(uint value) => _value = value;
+ public readonly uint Rdm => (_value >> 16) & 0x7;
+ public readonly uint Dm => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstRmb19w4
+ {
+ private readonly uint _value;
+ public InstRmb19w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 19) & 0xF;
+ }
+
+ readonly struct InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 4) & 0x3;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint S => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rdb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Imm24b0w24
+ {
+ private readonly uint _value;
+ public InstCondb28w4Imm24b0w24(uint value) => _value = value;
+ public readonly uint Imm24 => (_value >> 0) & 0xFFFFFF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb24w4Imm8b16w8
+ {
+ private readonly uint _value;
+ public InstCondb24w4Imm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ public readonly uint Cond => (_value >> 24) & 0xF;
+ }
+
+ readonly struct InstImm11b16w11
+ {
+ private readonly uint _value;
+ public InstImm11b16w11(uint value) => _value = value;
+ public readonly uint Imm11 => (_value >> 16) & 0x7FF;
+ }
+
+ readonly struct InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11
+ {
+ private readonly uint _value;
+ public InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11(uint value) => _value = value;
+ public readonly uint Imm11 => (_value >> 0) & 0x7FF;
+ public readonly uint J2 => (_value >> 11) & 0x1;
+ public readonly uint J1 => (_value >> 13) & 0x1;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint Cond => (_value >> 22) & 0xF;
+ public readonly uint S => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11
+ {
+ private readonly uint _value;
+ public InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11(uint value) => _value = value;
+ public readonly uint Imm11 => (_value >> 0) & 0x7FF;
+ public readonly uint J2 => (_value >> 11) & 0x1;
+ public readonly uint J1 => (_value >> 13) & 0x1;
+ public readonly uint Imm10 => (_value >> 16) & 0x3FF;
+ public readonly uint S => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5
+ {
+ private readonly uint _value;
+ public InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5(uint value) => _value = value;
+ public readonly uint Lsb => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Msb => (_value >> 16) & 0x1F;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5
+ {
+ private readonly uint _value;
+ public InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5(uint value) => _value = value;
+ public readonly uint Msb => (_value >> 0) & 0x1F;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ }
+
+ readonly struct InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Lsb => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Msb => (_value >> 16) & 0x1F;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5(uint value) => _value = value;
+ public readonly uint Msb => (_value >> 0) & 0x1F;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Imm12b8w12Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Imm12b8w12Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint Imm12 => (_value >> 8) & 0xFFF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstImm8b16w8
+ {
+ private readonly uint _value;
+ public InstImm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ }
+
+ readonly struct InstCondb28w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstHb24w1Imm24b0w24
+ {
+ private readonly uint _value;
+ public InstHb24w1Imm24b0w24(uint value) => _value = value;
+ public readonly uint Imm24 => (_value >> 0) & 0xFFFFFF;
+ public readonly uint H => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1
+ {
+ private readonly uint _value;
+ public InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1(uint value) => _value = value;
+ public readonly uint H => (_value >> 0) & 0x1;
+ public readonly uint Imm10l => (_value >> 1) & 0x3FF;
+ public readonly uint J2 => (_value >> 11) & 0x1;
+ public readonly uint J1 => (_value >> 13) & 0x1;
+ public readonly uint Imm10h => (_value >> 16) & 0x3FF;
+ public readonly uint S => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstRmb16w4
+ {
+ private readonly uint _value;
+ public InstRmb16w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstOpb27w1Ib25w1Imm5b19w5Rnb16w3
+ {
+ private readonly uint _value;
+ public InstOpb27w1Ib25w1Imm5b19w5Rnb16w3(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 16) & 0x7;
+ public readonly uint Imm5 => (_value >> 19) & 0x1F;
+ public readonly uint I => (_value >> 25) & 0x1;
+ public readonly uint Op => (_value >> 27) & 0x1;
+ }
+
+ readonly struct InstCondb28w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4(uint value) => _value = value;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb12w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb12w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRmb19w3Rnb16w3
+ {
+ private readonly uint _value;
+ public InstRmb19w3Rnb16w3(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 4) & 0x3;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Rs => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb24w3Imm8b16w8
+ {
+ private readonly uint _value;
+ public InstRnb24w3Imm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ public readonly uint Rn => (_value >> 24) & 0x7;
+ }
+
+ readonly struct InstNb23w1Rmb19w4Rnb16w3
+ {
+ private readonly uint _value;
+ public InstNb23w1Rmb19w4Rnb16w3(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0xF;
+ public readonly uint N => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5
+ {
+ private readonly uint _value;
+ public InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5(uint value) => _value = value;
+ public readonly uint Mode => (_value >> 0) & 0x1F;
+ public readonly uint F => (_value >> 6) & 0x1;
+ public readonly uint I => (_value >> 7) & 0x1;
+ public readonly uint A => (_value >> 8) & 0x1;
+ public readonly uint M => (_value >> 17) & 0x1;
+ public readonly uint Imod => (_value >> 18) & 0x3;
+ }
+
+ readonly struct InstImb20w1Ab18w1Ib17w1Fb16w1
+ {
+ private readonly uint _value;
+ public InstImb20w1Ab18w1Ib17w1Fb16w1(uint value) => _value = value;
+ public readonly uint F => (_value >> 16) & 0x1;
+ public readonly uint I => (_value >> 17) & 0x1;
+ public readonly uint A => (_value >> 18) & 0x1;
+ public readonly uint Im => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5
+ {
+ private readonly uint _value;
+ public InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5(uint value) => _value = value;
+ public readonly uint Mode => (_value >> 0) & 0x1F;
+ public readonly uint F => (_value >> 5) & 0x1;
+ public readonly uint I => (_value >> 6) & 0x1;
+ public readonly uint A => (_value >> 7) & 0x1;
+ public readonly uint M => (_value >> 8) & 0x1;
+ public readonly uint Imod => (_value >> 9) & 0x3;
+ }
+
+ readonly struct InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Sz => (_value >> 21) & 0x3;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Szb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Szb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Sz => (_value >> 4) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Optionb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Optionb0w4(uint value) => _value = value;
+ public readonly uint Option => (_value >> 0) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstOptionb0w4
+ {
+ private readonly uint _value;
+ public InstOptionb0w4(uint value) => _value = value;
+ public readonly uint Option => (_value >> 0) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7(uint value) => _value = value;
+ public readonly uint Imm871 => (_value >> 1) & 0x7F;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7(uint value) => _value = value;
+ public readonly uint Imm871 => (_value >> 1) & 0x7F;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstImm6b16w6
+ {
+ private readonly uint _value;
+ public InstImm6b16w6(uint value) => _value = value;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ }
+
+ readonly struct InstFirstcondb20w4Maskb16w4
+ {
+ private readonly uint _value;
+ public InstFirstcondb20w4Maskb16w4(uint value) => _value = value;
+ public readonly uint Mask => (_value >> 16) & 0xF;
+ public readonly uint Firstcond => (_value >> 20) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rtb12w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rtb12w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Rt2b8w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Rt2b8w4(uint value) => _value = value;
+ public readonly uint Rt2 => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Wb21w1Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Wb21w1Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16
+ {
+ private readonly uint _value;
+ public InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 0) & 0xFFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb24w3RegisterListb16w8
+ {
+ private readonly uint _value;
+ public InstRnb24w3RegisterListb16w8(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 16) & 0xFF;
+ public readonly uint Rn => (_value >> 24) & 0x7;
+ }
+
+ readonly struct InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14
+ {
+ private readonly uint _value;
+ public InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 0) & 0x3FFF;
+ public readonly uint M => (_value >> 14) & 0x1;
+ public readonly uint P => (_value >> 15) & 0x1;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstImm5b22w5Rnb19w3Rtb16w3
+ {
+ private readonly uint _value;
+ public InstImm5b22w5Rnb19w3Rtb16w3(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ public readonly uint Imm5 => (_value >> 22) & 0x1F;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint W => (_value >> 8) & 0x1;
+ public readonly uint U => (_value >> 9) & 0x1;
+ public readonly uint P => (_value >> 10) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb23w1Rtb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstUb23w1Rtb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRmb22w3Rnb19w3Rtb16w3
+ {
+ private readonly uint _value;
+ public InstRmb22w3Rnb19w3Rtb16w3(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ public readonly uint Rm => (_value >> 22) & 0x7;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Imm2 => (_value >> 4) & 0x3;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Imm4h => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rt2 => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Imm4h => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rt2 => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Imm4h => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Imm4h => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRtb24w3Imm8b16w8
+ {
+ private readonly uint _value;
+ public InstRtb24w3Imm8b16w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 16) & 0xFF;
+ public readonly uint Rt => (_value >> 24) & 0x7;
+ }
+
+ readonly struct InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4(uint value) => _value = value;
+ public readonly uint Crm => (_value >> 0) & 0xF;
+ public readonly uint Opc2 => (_value >> 5) & 0x7;
+ public readonly uint Coproc0 => (_value >> 8) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Crn => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x7;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4
+ {
+ private readonly uint _value;
+ public InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4(uint value) => _value = value;
+ public readonly uint Crm => (_value >> 0) & 0xF;
+ public readonly uint Opc2 => (_value >> 5) & 0x7;
+ public readonly uint Coproc0 => (_value >> 8) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Crn => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x7;
+ }
+
+ readonly struct InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4(uint value) => _value = value;
+ public readonly uint Crm => (_value >> 0) & 0xF;
+ public readonly uint Opc1 => (_value >> 4) & 0xF;
+ public readonly uint Coproc0 => (_value >> 8) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rt2 => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4
+ {
+ private readonly uint _value;
+ public InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4(uint value) => _value = value;
+ public readonly uint Crm => (_value >> 0) & 0xF;
+ public readonly uint Opc1 => (_value >> 4) & 0xF;
+ public readonly uint Coproc0 => (_value >> 8) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rt2 => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rab12w4Rdb8w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rab12w4Rdb8w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Imm4 => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Imm4 => (_value >> 16) & 0xF;
+ public readonly uint I => (_value >> 26) & 0x1;
+ }
+
+ readonly struct InstDb23w1Rmb19w4Rdb16w3
+ {
+ private readonly uint _value;
+ public InstDb23w1Rmb19w4Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0xF;
+ public readonly uint D => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3
+ {
+ private readonly uint _value;
+ public InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0x7;
+ public readonly uint Imm5 => (_value >> 22) & 0x1F;
+ public readonly uint Op => (_value >> 27) & 0x3;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Rs => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRsb19w3Rdmb16w3
+ {
+ private readonly uint _value;
+ public InstRsb19w3Rdmb16w3(uint value) => _value = value;
+ public readonly uint Rdm => (_value >> 16) & 0x7;
+ public readonly uint Rs => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4
+ {
+ private readonly uint _value;
+ public InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4(uint value) => _value = value;
+ public readonly uint Rs => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rm => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Stype => (_value >> 21) & 0x3;
+ }
+
+ readonly struct InstCondb28w4Rb22w1Rdb12w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rb22w1Rdb12w4(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRb20w1Rdb8w4
+ {
+ private readonly uint _value;
+ public InstRb20w1Rdb8w4(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint R => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1(uint value) => _value = value;
+ public readonly uint M => (_value >> 8) & 0x1;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint M1 => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRb20w1M1b16w4Rdb8w4Mb4w1
+ {
+ private readonly uint _value;
+ public InstRb20w1M1b16w4Rdb8w4Mb4w1(uint value) => _value = value;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint M1 => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 8) & 0x1;
+ public readonly uint M1 => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRb20w1Rnb16w4M1b8w4Mb4w1
+ {
+ private readonly uint _value;
+ public InstRb20w1Rnb16w4M1b8w4Mb4w1(uint value) => _value = value;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint M1 => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rb22w1Maskb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rb22w1Maskb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Mask => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rb22w1Maskb16w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rb22w1Maskb16w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Mask => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRb20w1Rnb16w4Maskb8w4
+ {
+ private readonly uint _value;
+ public InstRb20w1Rnb16w4Maskb8w4(uint value) => _value = value;
+ public readonly uint Mask => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb19w3Rdmb16w3
+ {
+ private readonly uint _value;
+ public InstRnb19w3Rdmb16w3(uint value) => _value = value;
+ public readonly uint Rdm => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstRmb19w3Rdb16w3
+ {
+ private readonly uint _value;
+ public InstRmb19w3Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rm => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Tb => (_value >> 6) & 0x1;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Tb => (_value >> 5) & 0x1;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstUb23w1Rb22w1Rnb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstUb23w1Rb22w1Rnb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstWb21w1Rnb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstWb21w1Rnb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstWb21w1Rnb16w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstWb21w1Rnb16w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstUb23w1Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstUb23w1Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint R => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstWb21w1Rnb16w4Imm2b4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstWb21w1Rnb16w4Imm2b4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Imm2 => (_value >> 4) & 0x3;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstUb23w1Rnb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstUb23w1Rnb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstRnb16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Stype => (_value >> 5) & 0x3;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstRnb16w4Imm2b4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm2b4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Imm2 => (_value >> 4) & 0x3;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstPb24w1RegisterListb16w8
+ {
+ private readonly uint _value;
+ public InstPb24w1RegisterListb16w8(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 16) & 0xFF;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstMb24w1RegisterListb16w8
+ {
+ private readonly uint _value;
+ public InstMb24w1RegisterListb16w8(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 16) & 0xFF;
+ public readonly uint M => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rdb12w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rdb12w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb19w3Rdb16w3
+ {
+ private readonly uint _value;
+ public InstRnb19w3Rdb16w3(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 16) & 0x7;
+ public readonly uint Rn => (_value >> 19) & 0x7;
+ }
+
+ readonly struct InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Lsb => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Widthm1 => (_value >> 16) & 0x1F;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5
+ {
+ private readonly uint _value;
+ public InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5(uint value) => _value = value;
+ public readonly uint Widthm1 => (_value >> 0) & 0x1F;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstEb9w1
+ {
+ private readonly uint _value;
+ public InstEb9w1(uint value) => _value = value;
+ public readonly uint E => (_value >> 9) & 0x1;
+ }
+
+ readonly struct InstEb19w1
+ {
+ private readonly uint _value;
+ public InstEb19w1(uint value) => _value = value;
+ public readonly uint E => (_value >> 19) & 0x1;
+ }
+
+ readonly struct InstImm1b9w1
+ {
+ private readonly uint _value;
+ public InstImm1b9w1(uint value) => _value = value;
+ public readonly uint Imm1 => (_value >> 9) & 0x1;
+ }
+
+ readonly struct InstImm1b19w1
+ {
+ private readonly uint _value;
+ public InstImm1b19w1(uint value) => _value = value;
+ public readonly uint Imm1 => (_value >> 19) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint M => (_value >> 6) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rdhi => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rdhi => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint M => (_value >> 6) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rdhi => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint Rdhi => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rdhi => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint Rdhi => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 6) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint R => (_value >> 5) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint R => (_value >> 4) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Ra => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint R => (_value >> 5) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Rb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Rb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint R => (_value >> 4) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint M => (_value >> 6) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 4) & 0x1;
+ public readonly uint N => (_value >> 5) & 0x1;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 6) & 0x1;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rd => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Sh => (_value >> 6) & 0x1;
+ public readonly uint Imm5 => (_value >> 7) & 0x1F;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint SatImm => (_value >> 16) & 0x1F;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5
+ {
+ private readonly uint _value;
+ public InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5(uint value) => _value = value;
+ public readonly uint SatImm => (_value >> 0) & 0x1F;
+ public readonly uint Imm2 => (_value >> 6) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Imm3 => (_value >> 12) & 0x7;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Sh => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint SatImm => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4SatImmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4SatImmb0w4(uint value) => _value = value;
+ public readonly uint SatImm => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rtb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rtb0w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 0) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rdb12w4Rtb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rdb12w4Rtb0w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 0) & 0xF;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Rdb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Rdb0w4(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 0) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4(uint value) => _value = value;
+ public readonly uint Rd => (_value >> 0) & 0xF;
+ public readonly uint Rt2 => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstWb21w1Rnb16w4Mb14w1RegisterListb0w14
+ {
+ private readonly uint _value;
+ public InstWb21w1Rnb16w4Mb14w1RegisterListb0w14(uint value) => _value = value;
+ public readonly uint RegisterList => (_value >> 0) & 0x3FFF;
+ public readonly uint M => (_value >> 14) & 0x1;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ }
+
+ readonly struct InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rotate => (_value >> 10) & 0x3;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rotate => (_value >> 4) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rotate => (_value >> 10) & 0x3;
+ public readonly uint Rd => (_value >> 12) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRdb8w4Rotateb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRdb8w4Rotateb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Rotate => (_value >> 4) & 0x3;
+ public readonly uint Rd => (_value >> 8) & 0xF;
+ }
+
+ readonly struct InstRnb16w4Hb4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstRnb16w4Hb4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint H => (_value >> 4) & 0x1;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstImm12b8w12Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstImm12b8w12Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint Imm12 => (_value >> 8) & 0xFFF;
+ }
+
+ readonly struct InstImm4b16w4Imm12b0w12
+ {
+ private readonly uint _value;
+ public InstImm4b16w4Imm12b0w12(uint value) => _value = value;
+ public readonly uint Imm12 => (_value >> 0) & 0xFFF;
+ public readonly uint Imm4 => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4(uint value) => _value = value;
+ public readonly uint Rn => (_value >> 0) & 0xF;
+ public readonly uint Rm => (_value >> 8) & 0xF;
+ public readonly uint Rdlo => (_value >> 12) & 0xF;
+ public readonly uint Rdhi => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Sz => (_value >> 20) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint F => (_value >> 10) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm3 => (_value >> 16) & 0x7;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint I => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm3 => (_value >> 16) & 0x7;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint I => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Rot => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint S => (_value >> 20) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Rot => (_value >> 23) & 0x3;
+ }
+
+ readonly struct InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Rot => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint S => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Vdb12w4Sizeb8w2(uint value) => _value = value;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Vdb12w4Sizeb8w2
+ {
+ private readonly uint _value;
+ public InstDb22w1Vdb12w4Sizeb8w2(uint value) => _value = value;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Op => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 7) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Sz => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Op => (_value >> 16) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Sz => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Op => (_value >> 16) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Op => (_value >> 7) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 7) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint I => (_value >> 5) & 0x1;
+ public readonly uint Sx => (_value >> 7) & 0x1;
+ public readonly uint Sf => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint U => (_value >> 16) & 0x1;
+ public readonly uint Op => (_value >> 18) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4(uint value) => _value = value;
+ public readonly uint Imm4 => (_value >> 0) & 0xF;
+ public readonly uint I => (_value >> 5) & 0x1;
+ public readonly uint Sx => (_value >> 7) & 0x1;
+ public readonly uint Sf => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint U => (_value >> 16) & 0x1;
+ public readonly uint Op => (_value >> 18) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1
+ {
+ private readonly uint _value;
+ public InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1(uint value) => _value = value;
+ public readonly uint E => (_value >> 5) & 0x1;
+ public readonly uint D => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vd => (_value >> 16) & 0xF;
+ public readonly uint Q => (_value >> 21) & 0x1;
+ public readonly uint B => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1
+ {
+ private readonly uint _value;
+ public InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1(uint value) => _value = value;
+ public readonly uint E => (_value >> 5) & 0x1;
+ public readonly uint D => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vd => (_value >> 16) & 0xF;
+ public readonly uint Q => (_value >> 21) & 0x1;
+ public readonly uint B => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm4 => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Imm4 => (_value >> 8) & 0xF;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint IndexAlign => (_value >> 4) & 0xF;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint A => (_value >> 4) & 0x1;
+ public readonly uint T => (_value >> 5) & 0x1;
+ public readonly uint Size => (_value >> 6) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint Align => (_value >> 4) & 0x3;
+ public readonly uint Size => (_value >> 6) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4(uint value) => _value = value;
+ public readonly uint Rm => (_value >> 0) & 0xF;
+ public readonly uint T => (_value >> 5) & 0x1;
+ public readonly uint Size => (_value >> 6) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint W => (_value >> 21) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint P => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Rn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8
+ {
+ private readonly uint _value;
+ public InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8(uint value) => _value = value;
+ public readonly uint Imm8 => (_value >> 0) & 0xFF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint F => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Q => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint F => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Q => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm3h => (_value >> 19) & 0x7;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm3h => (_value >> 19) & 0x7;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rt2 => (_value >> 16) & 0xF;
+ public readonly uint Op => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Rt2 => (_value >> 16) & 0xF;
+ public readonly uint Op => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1
+ {
+ private readonly uint _value;
+ public InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1(uint value) => _value = value;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Op => (_value >> 20) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstOpb20w1Vnb16w4Rtb12w4Nb7w1
+ {
+ private readonly uint _value;
+ public InstOpb20w1Vnb16w4Rtb12w4Nb7w1(uint value) => _value = value;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Op => (_value >> 20) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm4h => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4(uint value) => _value = value;
+ public readonly uint Imm4l => (_value >> 0) & 0xF;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm4h => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2
+ {
+ private readonly uint _value;
+ public InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2(uint value) => _value = value;
+ public readonly uint Opc2 => (_value >> 5) & 0x3;
+ public readonly uint D => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vd => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x3;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2
+ {
+ private readonly uint _value;
+ public InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2(uint value) => _value = value;
+ public readonly uint Opc2 => (_value >> 5) & 0x3;
+ public readonly uint D => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vd => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x3;
+ }
+
+ readonly struct InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2
+ {
+ private readonly uint _value;
+ public InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2(uint value) => _value = value;
+ public readonly uint Opc2 => (_value >> 5) & 0x3;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x3;
+ public readonly uint U => (_value >> 23) & 0x1;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2
+ {
+ private readonly uint _value;
+ public InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2(uint value) => _value = value;
+ public readonly uint Opc2 => (_value >> 5) & 0x3;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Opc1 => (_value >> 21) & 0x3;
+ public readonly uint U => (_value >> 23) & 0x1;
+ }
+
+ readonly struct InstCondb28w4Regb16w4Rtb12w4
+ {
+ private readonly uint _value;
+ public InstCondb28w4Regb16w4Rtb12w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Reg => (_value >> 16) & 0xF;
+ public readonly uint Cond => (_value >> 28) & 0xF;
+ }
+
+ readonly struct InstRegb16w4Rtb12w4
+ {
+ private readonly uint _value;
+ public InstRegb16w4Rtb12w4(uint value) => _value = value;
+ public readonly uint Rt => (_value >> 12) & 0xF;
+ public readonly uint Reg => (_value >> 16) & 0xF;
+ }
+
+ readonly struct InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Op => (_value >> 9) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Op => (_value >> 9) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Op => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Op => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Sz => (_value >> 20) & 0x1;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Q => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Size => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint Q => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 6) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint L => (_value >> 7) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint L => (_value >> 7) & 0x1;
+ public readonly uint Op => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint F => (_value >> 8) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Size => (_value >> 18) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint L => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint L => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Size => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint Cc => (_value >> 20) & 0x3;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 24) & 0x1;
+ }
+
+ readonly struct InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ public readonly uint U => (_value >> 28) & 0x1;
+ }
+
+ readonly struct InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint L => (_value >> 7) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Imm6 => (_value >> 16) & 0x3F;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Q => (_value >> 6) & 0x1;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+
+ readonly struct InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4
+ {
+ private readonly uint _value;
+ public InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4(uint value) => _value = value;
+ public readonly uint Vm => (_value >> 0) & 0xF;
+ public readonly uint M => (_value >> 5) & 0x1;
+ public readonly uint Op => (_value >> 6) & 0x1;
+ public readonly uint N => (_value >> 7) & 0x1;
+ public readonly uint Len => (_value >> 8) & 0x3;
+ public readonly uint Vd => (_value >> 12) & 0xF;
+ public readonly uint Vn => (_value >> 16) & 0xF;
+ public readonly uint D => (_value >> 22) & 0x1;
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs
new file mode 100644
index 00000000..a1937e08
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs
@@ -0,0 +1,63 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ [Flags]
+ enum InstFlags
+ {
+ None = 0,
+ Cond = 1 << 0,
+ Rd = 1 << 1,
+ RdLo = 1 << 2,
+ RdHi = 1 << 3,
+ Rdn = 1 << 4,
+ Dn = 1 << 5,
+ Rt = 1 << 6,
+ Rt2 = 1 << 7,
+ Rlist = 1 << 8,
+ Rd16 = 1 << 9,
+ ReadRd = 1 << 10,
+ WBack = 1 << 11,
+ Thumb16 = 1 << 12,
+
+ RdnDn = Rdn | Dn,
+ RdRd16 = Rd | Rd16,
+ RtRt2 = Rt | Rt2,
+ RdLoRdHi = RdLo | RdHi,
+ RdLoHi = Rd | RdHi,
+ RdRtRead = Rd | RtRead,
+ RdRtReadRd16 = Rd | RtRead | Rd16,
+ RdRt2Read = Rd | Rt2 | RtRead,
+ RdRt2ReadRd16 = Rd | Rt2 | RtRead | Rd16,
+ RtRd16 = Rt | Rd16,
+ RtWBack = Rt | WBack,
+ Rt2WBack = Rt2 | RtWBack,
+ RtRead = Rt | ReadRd,
+ RtReadRd16 = Rt | ReadRd | Rd16,
+ Rt2Read = Rt2 | RtRead,
+ RtReadWBack = RtRead | WBack,
+ Rt2ReadWBack = Rt2 | RtReadWBack,
+ RlistWBack = Rlist | WBack,
+ RlistRead = Rlist | ReadRd,
+ RlistReadWBack = Rlist | ReadRd | WBack,
+
+ CondRd = Cond | Rd,
+ CondRdLoHi = Cond | Rd | RdHi,
+ CondRt = Cond | Rt,
+ CondRt2 = Cond | Rt | Rt2,
+ CondRd16 = Cond | Rd | Rd16,
+ CondWBack = Cond | WBack,
+ CondRdRtRead = Cond | Rd | RtRead,
+ CondRdRt2Read = Cond | Rd | Rt2 | RtRead,
+ CondRtWBack = Cond | RtWBack,
+ CondRt2WBack = Cond | Rt2 | RtWBack,
+ CondRtRead = Cond | RtRead,
+ CondRt2Read = Cond | Rt2 | RtRead,
+ CondRtReadWBack = Cond | RtReadWBack,
+ CondRt2ReadWBack = Cond | Rt2 | RtReadWBack,
+ CondRlist = Cond | Rlist,
+ CondRlistWBack = Cond | Rlist | WBack,
+ CondRlistRead = Cond | Rlist | ReadRd,
+ CondRlistReadWBack = Cond | Rlist | ReadRd | WBack,
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs
new file mode 100644
index 00000000..80481ec6
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct InstInfo
+ {
+ public readonly uint Encoding;
+ public readonly InstName Name;
+ public readonly Action EmitFunc;
+ public readonly InstFlags Flags;
+
+ public InstInfo(uint encoding, InstName name, Action emitFunc, InstFlags flags)
+ {
+ Encoding = encoding;
+ Name = name;
+ EmitFunc = emitFunc;
+ Flags = flags;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs
new file mode 100644
index 00000000..25739d56
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs
@@ -0,0 +1,79 @@
+using Ryujinx.Cpu.LightningJit.Table;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct InstInfoForTable : IInstInfo
+ {
+ public uint Encoding { get; }
+ public uint EncodingMask { get; }
+ public InstEncoding[] Constraints { get; }
+ public InstMeta Meta { get; }
+ public IsaVersion Version => Meta.Version;
+ public IsaFeature Feature => Meta.Feature;
+
+ public InstInfoForTable(
+ uint encoding,
+ uint encodingMask,
+ InstEncoding[] constraints,
+ InstName name,
+ Action emitFunc,
+ IsaVersion isaVersion,
+ IsaFeature isaFeature,
+ InstFlags flags)
+ {
+ Encoding = encoding;
+ EncodingMask = encodingMask;
+ Constraints = constraints;
+ Meta = new(name, emitFunc, isaVersion, isaFeature, flags);
+ }
+
+ public InstInfoForTable(
+ uint encoding,
+ uint encodingMask,
+ InstEncoding[] constraints,
+ InstName name,
+ Action emitFunc,
+ IsaVersion isaVersion,
+ InstFlags flags) : this(encoding, encodingMask, constraints, name, emitFunc, isaVersion, IsaFeature.None, flags)
+ {
+ }
+
+ public InstInfoForTable(
+ uint encoding,
+ uint encodingMask,
+ InstName name,
+ Action emitFunc,
+ IsaVersion isaVersion,
+ IsaFeature isaFeature,
+ InstFlags flags) : this(encoding, encodingMask, null, name, emitFunc, isaVersion, isaFeature, flags)
+ {
+ }
+
+ public InstInfoForTable(
+ uint encoding,
+ uint encodingMask,
+ InstName name,
+ Action emitFunc,
+ IsaVersion isaVersion,
+ InstFlags flags) : this(encoding, encodingMask, null, name, emitFunc, isaVersion, IsaFeature.None, flags)
+ {
+ }
+
+ public bool IsConstrained(uint encoding)
+ {
+ if (Constraints != null)
+ {
+ foreach (InstEncoding constraint in Constraints)
+ {
+ if ((encoding & constraint.EncodingMask) == constraint.Encoding)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs
new file mode 100644
index 00000000..64eb41bb
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct InstMeta
+ {
+ public readonly InstName Name;
+ public readonly Action EmitFunc;
+ public readonly IsaVersion Version;
+ public readonly IsaFeature Feature;
+ public readonly InstFlags Flags;
+
+ public InstMeta(InstName name, Action emitFunc, IsaVersion isaVersion, IsaFeature isaFeature, InstFlags flags)
+ {
+ Name = name;
+ EmitFunc = emitFunc;
+ Version = isaVersion;
+ Feature = isaFeature;
+ Flags = flags;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs
new file mode 100644
index 00000000..2ee67aa0
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs
@@ -0,0 +1,562 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ enum InstName
+ {
+ AdcI,
+ AdcR,
+ AdcRr,
+ AddI,
+ AddR,
+ AddRr,
+ AddSpI,
+ AddSpR,
+ Adr,
+ Aesd,
+ Aese,
+ Aesimc,
+ Aesmc,
+ AndI,
+ AndR,
+ AndRr,
+ B,
+ Bfc,
+ Bfi,
+ BicI,
+ BicR,
+ BicRr,
+ Bkpt,
+ BlxR,
+ BlI,
+ Bx,
+ Bxj,
+ Cbnz,
+ Clrbhb,
+ Clrex,
+ Clz,
+ CmnI,
+ CmnR,
+ CmnRr,
+ CmpI,
+ CmpR,
+ CmpRr,
+ Cps,
+ Crc32,
+ Crc32c,
+ Csdb,
+ Dbg,
+ Dcps1,
+ Dcps2,
+ Dcps3,
+ Dmb,
+ Dsb,
+ EorI,
+ EorR,
+ EorRr,
+ Eret,
+ Esb,
+ Fldmx,
+ Fstmx,
+ Hlt,
+ Hvc,
+ Isb,
+ It,
+ Lda,
+ Ldab,
+ Ldaex,
+ Ldaexb,
+ Ldaexd,
+ Ldaexh,
+ Ldah,
+ LdcI,
+ LdcL,
+ Ldm,
+ Ldmda,
+ Ldmdb,
+ Ldmib,
+ LdmE,
+ LdmU,
+ Ldrbt,
+ LdrbI,
+ LdrbL,
+ LdrbR,
+ LdrdI,
+ LdrdL,
+ LdrdR,
+ Ldrex,
+ Ldrexb,
+ Ldrexd,
+ Ldrexh,
+ Ldrht,
+ LdrhI,
+ LdrhL,
+ LdrhR,
+ Ldrsbt,
+ LdrsbI,
+ LdrsbL,
+ LdrsbR,
+ Ldrsht,
+ LdrshI,
+ LdrshL,
+ LdrshR,
+ Ldrt,
+ LdrI,
+ LdrL,
+ LdrR,
+ Mcr,
+ Mcrr,
+ Mla,
+ Mls,
+ Movt,
+ MovI,
+ MovR,
+ MovRr,
+ Mrc,
+ Mrrc,
+ Mrs,
+ MrsBr,
+ MsrBr,
+ MsrI,
+ MsrR,
+ Mul,
+ MvnI,
+ MvnR,
+ MvnRr,
+ Nop,
+ OrnI,
+ OrnR,
+ OrrI,
+ OrrR,
+ OrrRr,
+ Pkh,
+ PldI,
+ PldL,
+ PldR,
+ PliI,
+ PliR,
+ Pop,
+ Pssbb,
+ Push,
+ Qadd,
+ Qadd16,
+ Qadd8,
+ Qasx,
+ Qdadd,
+ Qdsub,
+ Qsax,
+ Qsub,
+ Qsub16,
+ Qsub8,
+ Rbit,
+ Rev,
+ Rev16,
+ Revsh,
+ Rfe,
+ RsbI,
+ RsbR,
+ RsbRr,
+ RscI,
+ RscR,
+ RscRr,
+ Sadd16,
+ Sadd8,
+ Sasx,
+ Sb,
+ SbcI,
+ SbcR,
+ SbcRr,
+ Sbfx,
+ Sdiv,
+ Sel,
+ Setend,
+ Setpan,
+ Sev,
+ Sevl,
+ Sha1c,
+ Sha1h,
+ Sha1m,
+ Sha1p,
+ Sha1su0,
+ Sha1su1,
+ Sha256h,
+ Sha256h2,
+ Sha256su0,
+ Sha256su1,
+ Shadd16,
+ Shadd8,
+ Shasx,
+ Shsax,
+ Shsub16,
+ Shsub8,
+ Smc,
+ Smlabb,
+ Smlad,
+ Smlal,
+ Smlalbb,
+ Smlald,
+ Smlawb,
+ Smlsd,
+ Smlsld,
+ Smmla,
+ Smmls,
+ Smmul,
+ Smuad,
+ Smulbb,
+ Smull,
+ Smulwb,
+ Smusd,
+ Srs,
+ Ssat,
+ Ssat16,
+ Ssax,
+ Ssbb,
+ Ssub16,
+ Ssub8,
+ Stc,
+ Stl,
+ Stlb,
+ Stlex,
+ Stlexb,
+ Stlexd,
+ Stlexh,
+ Stlh,
+ Stm,
+ Stmda,
+ Stmdb,
+ Stmib,
+ StmU,
+ Strbt,
+ StrbI,
+ StrbR,
+ StrdI,
+ StrdR,
+ Strex,
+ Strexb,
+ Strexd,
+ Strexh,
+ Strht,
+ StrhI,
+ StrhR,
+ Strt,
+ StrI,
+ StrR,
+ SubI,
+ SubR,
+ SubRr,
+ SubSpI,
+ SubSpR,
+ Svc,
+ Sxtab,
+ Sxtab16,
+ Sxtah,
+ Sxtb,
+ Sxtb16,
+ Sxth,
+ Tbb,
+ TeqI,
+ TeqR,
+ TeqRr,
+ Tsb,
+ TstI,
+ TstR,
+ TstRr,
+ Uadd16,
+ Uadd8,
+ Uasx,
+ Ubfx,
+ Udf,
+ Udiv,
+ Uhadd16,
+ Uhadd8,
+ Uhasx,
+ Uhsax,
+ Uhsub16,
+ Uhsub8,
+ Umaal,
+ Umlal,
+ Umull,
+ Uqadd16,
+ Uqadd8,
+ Uqasx,
+ Uqsax,
+ Uqsub16,
+ Uqsub8,
+ Usad8,
+ Usada8,
+ Usat,
+ Usat16,
+ Usax,
+ Usub16,
+ Usub8,
+ Uxtab,
+ Uxtab16,
+ Uxtah,
+ Uxtb,
+ Uxtb16,
+ Uxth,
+ Vaba,
+ Vabal,
+ VabdlI,
+ VabdF,
+ VabdI,
+ Vabs,
+ Vacge,
+ Vacgt,
+ Vaddhn,
+ Vaddl,
+ Vaddw,
+ VaddF,
+ VaddI,
+ VandR,
+ VbicI,
+ VbicR,
+ Vbif,
+ Vbit,
+ Vbsl,
+ Vcadd,
+ VceqI,
+ VceqR,
+ VcgeI,
+ VcgeR,
+ VcgtI,
+ VcgtR,
+ VcleI,
+ Vcls,
+ VcltI,
+ Vclz,
+ Vcmla,
+ VcmlaS,
+ Vcmp,
+ Vcmpe,
+ Vcnt,
+ VcvtaAsimd,
+ VcvtaVfp,
+ Vcvtb,
+ VcvtbBfs,
+ VcvtmAsimd,
+ VcvtmVfp,
+ VcvtnAsimd,
+ VcvtnVfp,
+ VcvtpAsimd,
+ VcvtpVfp,
+ VcvtrIv,
+ Vcvtt,
+ VcvttBfs,
+ VcvtBfs,
+ VcvtDs,
+ VcvtHs,
+ VcvtIs,
+ VcvtIv,
+ VcvtVi,
+ VcvtXs,
+ VcvtXv,
+ Vdiv,
+ Vdot,
+ VdotS,
+ VdupR,
+ VdupS,
+ Veor,
+ Vext,
+ Vfma,
+ Vfmal,
+ VfmalS,
+ VfmaBf,
+ VfmaBfs,
+ Vfms,
+ Vfmsl,
+ VfmslS,
+ Vfnma,
+ Vfnms,
+ Vhadd,
+ Vhsub,
+ Vins,
+ Vjcvt,
+ Vld11,
+ Vld1A,
+ Vld1M,
+ Vld21,
+ Vld2A,
+ Vld2M,
+ Vld31,
+ Vld3A,
+ Vld3M,
+ Vld41,
+ Vld4A,
+ Vld4M,
+ Vldm,
+ VldrI,
+ VldrL,
+ Vmaxnm,
+ VmaxF,
+ VmaxI,
+ Vminnm,
+ VminF,
+ VminI,
+ VmlalI,
+ VmlalS,
+ VmlaF,
+ VmlaI,
+ VmlaS,
+ VmlslI,
+ VmlslS,
+ VmlsF,
+ VmlsI,
+ VmlsS,
+ Vmmla,
+ Vmovl,
+ Vmovn,
+ Vmovx,
+ VmovD,
+ VmovH,
+ VmovI,
+ VmovR,
+ VmovRs,
+ VmovS,
+ VmovSr,
+ VmovSs,
+ Vmrs,
+ Vmsr,
+ VmullI,
+ VmullS,
+ VmulF,
+ VmulI,
+ VmulS,
+ VmvnI,
+ VmvnR,
+ Vneg,
+ Vnmla,
+ Vnmls,
+ Vnmul,
+ VornR,
+ VorrI,
+ VorrR,
+ Vpadal,
+ Vpaddl,
+ VpaddF,
+ VpaddI,
+ VpmaxF,
+ VpmaxI,
+ VpminF,
+ VpminI,
+ Vqabs,
+ Vqadd,
+ Vqdmlal,
+ Vqdmlsl,
+ Vqdmulh,
+ Vqdmull,
+ Vqmovn,
+ Vqneg,
+ Vqrdmlah,
+ Vqrdmlsh,
+ Vqrdmulh,
+ Vqrshl,
+ Vqrshrn,
+ VqshlI,
+ VqshlR,
+ Vqshrn,
+ Vqsub,
+ Vraddhn,
+ Vrecpe,
+ Vrecps,
+ Vrev16,
+ Vrev32,
+ Vrev64,
+ Vrhadd,
+ VrintaAsimd,
+ VrintaVfp,
+ VrintmAsimd,
+ VrintmVfp,
+ VrintnAsimd,
+ VrintnVfp,
+ VrintpAsimd,
+ VrintpVfp,
+ VrintrVfp,
+ VrintxAsimd,
+ VrintxVfp,
+ VrintzAsimd,
+ VrintzVfp,
+ Vrshl,
+ Vrshr,
+ Vrshrn,
+ Vrsqrte,
+ Vrsqrts,
+ Vrsra,
+ Vrsubhn,
+ Vsdot,
+ VsdotS,
+ Vsel,
+ Vshll,
+ VshlI,
+ VshlR,
+ Vshr,
+ Vshrn,
+ Vsli,
+ Vsmmla,
+ Vsqrt,
+ Vsra,
+ Vsri,
+ Vst11,
+ Vst1M,
+ Vst21,
+ Vst2M,
+ Vst31,
+ Vst3M,
+ Vst41,
+ Vst4M,
+ Vstm,
+ Vstr,
+ Vsubhn,
+ Vsubl,
+ Vsubw,
+ VsubF,
+ VsubI,
+ VsudotS,
+ Vswp,
+ Vtbl,
+ Vtrn,
+ Vtst,
+ Vudot,
+ VudotS,
+ Vummla,
+ Vusdot,
+ VusdotS,
+ Vusmmla,
+ Vuzp,
+ Vzip,
+ Wfe,
+ Wfi,
+ Yield,
+ }
+
+ static class InstNameExtensions
+ {
+ public static bool IsCall(this InstName name)
+ {
+ return name == InstName.BlI || name == InstName.BlxR;
+ }
+
+ public static bool IsSystem(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Mcr:
+ case InstName.Mcrr:
+ case InstName.Mrc:
+ case InstName.Mrs:
+ case InstName.MrsBr:
+ case InstName.MsrBr:
+ case InstName.MsrI:
+ case InstName.MsrR:
+ case InstName.Mrrc:
+ case InstName.Svc:
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool IsSystemOrCall(this InstName name)
+ {
+ return name.IsSystem() || name.IsCall();
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs
new file mode 100644
index 00000000..2168c0b9
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs
@@ -0,0 +1,1194 @@
+using Ryujinx.Cpu.LightningJit.Table;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class InstTableA32 where T : IInstEmit
+ {
+ private static readonly InstTableLevel _table;
+
+ static InstTableA32()
+ {
+ InstEncoding[] condConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ };
+
+ InstEncoding[] condRnsRnConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x000F0000, 0x001F0000),
+ new(0x000D0000, 0x000F0000),
+ };
+
+ InstEncoding[] condRnConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x000D0000, 0x000F0000),
+ };
+
+ InstEncoding[] vdVmConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] condRnConstraints2 = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x0000000F, 0x0000000F),
+ };
+
+ InstEncoding[] optionConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x0000000F),
+ };
+
+ InstEncoding[] condPuwPwPuwPuwConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00000000, 0x01A00000),
+ new(0x01000000, 0x01200000),
+ new(0x00200000, 0x01A00000),
+ new(0x01A00000, 0x01A00000),
+ };
+
+ InstEncoding[] condRnPuwConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x000F0000, 0x000F0000),
+ new(0x00000000, 0x01A00000),
+ };
+
+ InstEncoding[] condPuwConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00000000, 0x01A00000),
+ };
+
+ InstEncoding[] condRnPwConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x000F0000, 0x000F0000),
+ new(0x00200000, 0x01200000),
+ };
+
+ InstEncoding[] condPwConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00200000, 0x01200000),
+ };
+
+ InstEncoding[] condRnConstraints3 = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x000F0000, 0x000F0000),
+ };
+
+ InstEncoding[] condMaskrConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00000000, 0x004F0000),
+ };
+
+ InstEncoding[] rnConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ };
+
+ InstEncoding[] vdVnVmConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00010000, 0x00010000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] condRaConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x0000F000, 0x0000F000),
+ };
+
+ InstEncoding[] sizeQvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] qvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeVnVmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00010000, 0x00010000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] sizeVdOpvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ new(0x00010100, 0x00010100),
+ };
+
+ InstEncoding[] cmodeCmodeQvdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00000100),
+ new(0x00000C00, 0x00000C00),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qvdQvnQvmOpConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnQvmSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ };
+
+ InstEncoding[] qvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00000300),
+ };
+
+ InstEncoding[] vmConstraints = new InstEncoding[]
+ {
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] opvdOpvmConstraints = new InstEncoding[]
+ {
+ new(0x00001100, 0x00001100),
+ new(0x00000001, 0x00000101),
+ };
+
+ InstEncoding[] imm6Opimm6Imm6QvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00200000, 0x00300200),
+ new(0x00000000, 0x00200000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] condQvdEbConstraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00210000, 0x00210000),
+ new(0x00400020, 0x00400020),
+ };
+
+ InstEncoding[] imm4QvdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00070000),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qvdQvnQvmQimm4Constraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000800, 0x00000840),
+ };
+
+ InstEncoding[] qvdConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] vdVnConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00010000, 0x00010000),
+ };
+
+ InstEncoding[] sizeConstraints2 = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ };
+
+ InstEncoding[] sizeIndexAlignIndexAlignConstraints = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ new(0x00000010, 0x00000030),
+ new(0x00000020, 0x00000030),
+ };
+
+ InstEncoding[] sizeSizeaConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000010, 0x000000D0),
+ };
+
+ InstEncoding[] alignConstraints = new InstEncoding[]
+ {
+ new(0x00000020, 0x00000020),
+ };
+
+ InstEncoding[] alignConstraints2 = new InstEncoding[]
+ {
+ new(0x00000030, 0x00000030),
+ };
+
+ InstEncoding[] sizeConstraints3 = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ };
+
+ InstEncoding[] alignSizeConstraints = new InstEncoding[]
+ {
+ new(0x00000030, 0x00000030),
+ new(0x000000C0, 0x000000C0),
+ };
+
+ InstEncoding[] sizeAConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000010, 0x00000010),
+ };
+
+ InstEncoding[] sizeAlignConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000020, 0x00000020),
+ };
+
+ InstEncoding[] sizeIndexAlignConstraints = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ new(0x00000030, 0x00000030),
+ };
+
+ InstEncoding[] sizeaConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000D0),
+ };
+
+ InstEncoding[] sizeSizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeQvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x01001000, 0x01001000),
+ new(0x01010000, 0x01010000),
+ };
+
+ InstEncoding[] imm3hImm3hImm3hImm3hImm3hVdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00180000, 0x00380000),
+ new(0x00280000, 0x00380000),
+ new(0x00300000, 0x00380000),
+ new(0x00380000, 0x00380000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeVmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] condOpc1opc2Constraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00000040, 0x00400060),
+ };
+
+ InstEncoding[] condUopc1opc2Uopc1opc2Constraints = new InstEncoding[]
+ {
+ new(0xF0000000, 0xF0000000),
+ new(0x00800000, 0x00C00060),
+ new(0x00000040, 0x00400060),
+ };
+
+ InstEncoding[] sizeOpuOpsizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x01000200, 0x01000200),
+ new(0x00100200, 0x00300200),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeOpsizeOpsizeQvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x01100000, 0x01300000),
+ new(0x01200000, 0x01300000),
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] cmodeQvdConstraints = new InstEncoding[]
+ {
+ new(0x00000E00, 0x00000E00),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qConstraints = new InstEncoding[]
+ {
+ new(0x00000040, 0x00000040),
+ };
+
+ InstEncoding[] sizeQConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000040, 0x00000040),
+ };
+
+ InstEncoding[] sizeConstraints4 = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnQvmSizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x00300000),
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] sizeSizeQvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000000, 0x00300000),
+ new(0x01001000, 0x01001000),
+ new(0x01010000, 0x01010000),
+ };
+
+ InstEncoding[] opSizeVmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x000000C0),
+ new(0x000C0000, 0x000C0000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] qvdQvmQvnConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ new(0x00010040, 0x00010040),
+ };
+
+ InstEncoding[] imm6UopVmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00000000, 0x01000100),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] imm6lUopQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380080),
+ new(0x00000000, 0x01000100),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] qvdQvmSizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ };
+
+ InstEncoding[] sizeSizeSizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00040000, 0x000C0000),
+ new(0x00080000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeSizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00080000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] imm6lQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380080),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] imm6VmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] imm6VdImm6Imm6Imm6Constraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00001000, 0x00001000),
+ new(0x00080000, 0x003F0000),
+ new(0x00100000, 0x003F0000),
+ new(0x00200000, 0x003F0000),
+ };
+
+ InstEncoding[] sizeVdConstraints2 = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeQsizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00080000, 0x000C0040),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ List insts = new()
+ {
+ new(0x02A00000, 0x0FE00000, condConstraints, InstName.AdcI, T.AdcIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00A00000, 0x0FE00010, condConstraints, InstName.AdcR, T.AdcRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00A00010, 0x0FE00090, condConstraints, InstName.AdcRr, T.AdcRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x02800000, 0x0FE00000, condRnsRnConstraints, InstName.AddI, T.AddIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00800000, 0x0FE00010, condRnConstraints, InstName.AddR, T.AddRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00800010, 0x0FE00090, condConstraints, InstName.AddRr, T.AddRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x028D0000, 0x0FEF0000, condConstraints, InstName.AddSpI, T.AddSpIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x008D0000, 0x0FEF0010, condConstraints, InstName.AddSpR, T.AddSpRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x028F0000, 0x0FFF0000, condConstraints, InstName.Adr, T.AdrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x024F0000, 0x0FFF0000, condConstraints, InstName.Adr, T.AdrA2, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF3B00340, 0xFFBF0FD0, vdVmConstraints, InstName.Aesd, T.AesdA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xF3B00300, 0xFFBF0FD0, vdVmConstraints, InstName.Aese, T.AeseA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xF3B003C0, 0xFFBF0FD0, vdVmConstraints, InstName.Aesimc, T.AesimcA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xF3B00380, 0xFFBF0FD0, vdVmConstraints, InstName.Aesmc, T.AesmcA1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0x02000000, 0x0FE00000, condConstraints, InstName.AndI, T.AndIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00000000, 0x0FE00010, condConstraints, InstName.AndR, T.AndRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00000010, 0x0FE00090, condConstraints, InstName.AndRr, T.AndRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0A000000, 0x0F000000, condConstraints, InstName.B, T.BA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x07C0001F, 0x0FE0007F, condConstraints, InstName.Bfc, T.BfcA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x07C00010, 0x0FE00070, condRnConstraints2, InstName.Bfi, T.BfiA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x03C00000, 0x0FE00000, condConstraints, InstName.BicI, T.BicIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01C00000, 0x0FE00010, condConstraints, InstName.BicR, T.BicRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01C00010, 0x0FE00090, condConstraints, InstName.BicRr, T.BicRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01200070, 0x0FF000F0, condConstraints, InstName.Bkpt, T.BkptA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x012FFF30, 0x0FFFFFF0, condConstraints, InstName.BlxR, T.BlxRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0B000000, 0x0F000000, condConstraints, InstName.BlI, T.BlIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xFA000000, 0xFE000000, InstName.BlI, T.BlIA2, IsaVersion.v80, InstFlags.None),
+ new(0x012FFF10, 0x0FFFFFF0, condConstraints, InstName.Bx, T.BxA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x012FFF20, 0x0FFFFFF0, condConstraints, InstName.Bxj, T.BxjA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F016, 0x0FFFFFFF, condConstraints, InstName.Clrbhb, T.ClrbhbA1, IsaVersion.v89, IsaFeature.FeatClrbhb, InstFlags.Cond),
+ new(0xF57FF01F, 0xFFFFFFFF, InstName.Clrex, T.ClrexA1, IsaVersion.v80, InstFlags.None),
+ new(0x016F0F10, 0x0FFF0FF0, condConstraints, InstName.Clz, T.ClzA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x03700000, 0x0FF0F000, condConstraints, InstName.CmnI, T.CmnIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01700000, 0x0FF0F010, condConstraints, InstName.CmnR, T.CmnRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01700010, 0x0FF0F090, condConstraints, InstName.CmnRr, T.CmnRrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x03500000, 0x0FF0F000, condConstraints, InstName.CmpI, T.CmpIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01500000, 0x0FF0F010, condConstraints, InstName.CmpR, T.CmpRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01500010, 0x0FF0F090, condConstraints, InstName.CmpRr, T.CmpRrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xF1000000, 0xFFF1FE20, InstName.Cps, T.CpsA1, IsaVersion.v80, InstFlags.None),
+ new(0x01000040, 0x0F900FF0, condConstraints, InstName.Crc32, T.Crc32A1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.CondRd),
+ new(0x01000240, 0x0F900FF0, condConstraints, InstName.Crc32c, T.Crc32cA1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.CondRd),
+ new(0x0320F014, 0x0FFFFFFF, condConstraints, InstName.Csdb, T.CsdbA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F0F0, 0x0FFFFFF0, condConstraints, InstName.Dbg, T.DbgA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xF57FF050, 0xFFFFFFF0, InstName.Dmb, T.DmbA1, IsaVersion.v80, InstFlags.None),
+ new(0xF57FF040, 0xFFFFFFF0, optionConstraints, InstName.Dsb, T.DsbA1, IsaVersion.v80, InstFlags.None),
+ new(0x02200000, 0x0FE00000, condConstraints, InstName.EorI, T.EorIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00200000, 0x0FE00010, condConstraints, InstName.EorR, T.EorRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00200010, 0x0FE00090, condConstraints, InstName.EorRr, T.EorRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0160006E, 0x0FFFFFFF, condConstraints, InstName.Eret, T.EretA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F010, 0x0FFFFFFF, condConstraints, InstName.Esb, T.EsbA1, IsaVersion.v82, IsaFeature.FeatRas, InstFlags.Cond),
+ new(0x0C100B01, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Fldmx, T.FldmxA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0C000B01, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Fstmx, T.FstmxA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x01000070, 0x0FF000F0, condConstraints, InstName.Hlt, T.HltA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01400070, 0x0FF000F0, condConstraints, InstName.Hvc, T.HvcA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xF57FF060, 0xFFFFFFF0, InstName.Isb, T.IsbA1, IsaVersion.v80, InstFlags.None),
+ new(0x01900C9F, 0x0FF00FFF, condConstraints, InstName.Lda, T.LdaA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01D00C9F, 0x0FF00FFF, condConstraints, InstName.Ldab, T.LdabA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01900E9F, 0x0FF00FFF, condConstraints, InstName.Ldaex, T.LdaexA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01D00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexb, T.LdaexbA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01B00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexd, T.LdaexdA1, IsaVersion.v80, InstFlags.CondRt2),
+ new(0x01F00E9F, 0x0FF00FFF, condConstraints, InstName.Ldaexh, T.LdaexhA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01F00C9F, 0x0FF00FFF, condConstraints, InstName.Ldah, T.LdahA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x0C105E00, 0x0E50FF00, condRnPuwConstraints, InstName.LdcI, T.LdcIA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0C1F5E00, 0x0E5FFF00, condPuwConstraints, InstName.LdcL, T.LdcLA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x08900000, 0x0FD00000, condConstraints, InstName.Ldm, T.LdmA1, IsaVersion.v80, InstFlags.CondRlistWBack),
+ new(0x08100000, 0x0FD00000, condConstraints, InstName.Ldmda, T.LdmdaA1, IsaVersion.v80, InstFlags.CondRlistWBack),
+ new(0x09100000, 0x0FD00000, condConstraints, InstName.Ldmdb, T.LdmdbA1, IsaVersion.v80, InstFlags.CondRlistWBack),
+ new(0x09900000, 0x0FD00000, condConstraints, InstName.Ldmib, T.LdmibA1, IsaVersion.v80, InstFlags.CondRlistWBack),
+ new(0x08508000, 0x0E508000, condConstraints, InstName.LdmE, T.LdmEA1, IsaVersion.v80, InstFlags.CondRlistWBack),
+ new(0x08500000, 0x0E708000, condConstraints, InstName.LdmU, T.LdmUA1, IsaVersion.v80, InstFlags.CondRlist),
+ new(0x04700000, 0x0F700000, condConstraints, InstName.Ldrbt, T.LdrbtA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x06700000, 0x0F700010, condConstraints, InstName.Ldrbt, T.LdrbtA2, IsaVersion.v80, InstFlags.CondRt),
+ new(0x04500000, 0x0E500000, condRnPwConstraints, InstName.LdrbI, T.LdrbIA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x045F0000, 0x0E5F0000, condPwConstraints, InstName.LdrbL, T.LdrbLA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x06500000, 0x0E500010, condPwConstraints, InstName.LdrbR, T.LdrbRA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x004000D0, 0x0E5000F0, condRnConstraints3, InstName.LdrdI, T.LdrdIA1, IsaVersion.v80, InstFlags.CondRt2WBack),
+ new(0x014F00D0, 0x0F7F00F0, condConstraints, InstName.LdrdL, T.LdrdLA1, IsaVersion.v80, InstFlags.CondRt2),
+ new(0x000000D0, 0x0E500FF0, condConstraints, InstName.LdrdR, T.LdrdRA1, IsaVersion.v80, InstFlags.CondRt2WBack),
+ new(0x01900F9F, 0x0FF00FFF, condConstraints, InstName.Ldrex, T.LdrexA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01D00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexb, T.LdrexbA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x01B00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexd, T.LdrexdA1, IsaVersion.v80, InstFlags.CondRt2),
+ new(0x01F00F9F, 0x0FF00FFF, condConstraints, InstName.Ldrexh, T.LdrexhA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x007000B0, 0x0F7000F0, condConstraints, InstName.Ldrht, T.LdrhtA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x003000B0, 0x0F700FF0, condConstraints, InstName.Ldrht, T.LdrhtA2, IsaVersion.v80, InstFlags.CondRt),
+ new(0x005000B0, 0x0E5000F0, condRnPwConstraints, InstName.LdrhI, T.LdrhIA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x005F00B0, 0x0E5F00F0, condPwConstraints, InstName.LdrhL, T.LdrhLA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x001000B0, 0x0E500FF0, condPwConstraints, InstName.LdrhR, T.LdrhRA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x007000D0, 0x0F7000F0, condConstraints, InstName.Ldrsbt, T.LdrsbtA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x003000D0, 0x0F700FF0, condConstraints, InstName.Ldrsbt, T.LdrsbtA2, IsaVersion.v80, InstFlags.CondRt),
+ new(0x005000D0, 0x0E5000F0, condRnPwConstraints, InstName.LdrsbI, T.LdrsbIA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x005F00D0, 0x0E5F00F0, condPwConstraints, InstName.LdrsbL, T.LdrsbLA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x001000D0, 0x0E500FF0, condPwConstraints, InstName.LdrsbR, T.LdrsbRA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x007000F0, 0x0F7000F0, condConstraints, InstName.Ldrsht, T.LdrshtA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x003000F0, 0x0F700FF0, condConstraints, InstName.Ldrsht, T.LdrshtA2, IsaVersion.v80, InstFlags.CondRt),
+ new(0x005000F0, 0x0E5000F0, condRnPwConstraints, InstName.LdrshI, T.LdrshIA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x005F00F0, 0x0E5F00F0, condPwConstraints, InstName.LdrshL, T.LdrshLA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x001000F0, 0x0E500FF0, condPwConstraints, InstName.LdrshR, T.LdrshRA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x04300000, 0x0F700000, condConstraints, InstName.Ldrt, T.LdrtA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x06300000, 0x0F700010, condConstraints, InstName.Ldrt, T.LdrtA2, IsaVersion.v80, InstFlags.CondRt),
+ new(0x04100000, 0x0E500000, condRnPwConstraints, InstName.LdrI, T.LdrIA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x041F0000, 0x0E5F0000, condPwConstraints, InstName.LdrL, T.LdrLA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x06100000, 0x0E500010, condPwConstraints, InstName.LdrR, T.LdrRA1, IsaVersion.v80, InstFlags.CondRtWBack),
+ new(0x0E000E10, 0x0F100E10, condConstraints, InstName.Mcr, T.McrA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x0C400E00, 0x0FF00E00, condConstraints, InstName.Mcrr, T.McrrA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x00200090, 0x0FE000F0, condConstraints, InstName.Mla, T.MlaA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x00600090, 0x0FF000F0, condConstraints, InstName.Mls, T.MlsA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x03400000, 0x0FF00000, condConstraints, InstName.Movt, T.MovtA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x03A00000, 0x0FEF0000, condConstraints, InstName.MovI, T.MovIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x03000000, 0x0FF00000, condConstraints, InstName.MovI, T.MovIA2, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01A00000, 0x0FEF0010, condConstraints, InstName.MovR, T.MovRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01A00010, 0x0FEF0090, condConstraints, InstName.MovRr, T.MovRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0E100E10, 0x0F100E10, condConstraints, InstName.Mrc, T.MrcA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x0C500E00, 0x0FF00E00, condConstraints, InstName.Mrrc, T.MrrcA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x010F0000, 0x0FBF0FFF, condConstraints, InstName.Mrs, T.MrsA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01000200, 0x0FB00EFF, condConstraints, InstName.MrsBr, T.MrsBrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0120F200, 0x0FB0FEF0, condConstraints, InstName.MsrBr, T.MsrBrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F000, 0x0FB0F000, condMaskrConstraints, InstName.MsrI, T.MsrIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0120F000, 0x0FB0FFF0, condConstraints, InstName.MsrR, T.MsrRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x00000090, 0x0FE0F0F0, condConstraints, InstName.Mul, T.MulA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x03E00000, 0x0FEF0000, condConstraints, InstName.MvnI, T.MvnIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01E00000, 0x0FEF0010, condConstraints, InstName.MvnR, T.MvnRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01E00010, 0x0FEF0090, condConstraints, InstName.MvnRr, T.MvnRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0320F000, 0x0FFFFFFF, condConstraints, InstName.Nop, T.NopA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x03800000, 0x0FE00000, condConstraints, InstName.OrrI, T.OrrIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01800000, 0x0FE00010, condConstraints, InstName.OrrR, T.OrrRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01800010, 0x0FE00090, condConstraints, InstName.OrrRr, T.OrrRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06800010, 0x0FF00030, condConstraints, InstName.Pkh, T.PkhA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF510F000, 0xFF30F000, rnConstraints, InstName.PldI, T.PldIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF55FF000, 0xFF7FF000, InstName.PldL, T.PldLA1, IsaVersion.v80, InstFlags.None),
+ new(0xF710F000, 0xFF30F010, InstName.PldR, T.PldRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF450F000, 0xFF70F000, InstName.PliI, T.PliIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF650F000, 0xFF70F010, InstName.PliR, T.PliRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF57FF044, 0xFFFFFFFF, InstName.Pssbb, T.PssbbA1, IsaVersion.v80, InstFlags.None),
+ new(0x01000050, 0x0FF00FF0, condConstraints, InstName.Qadd, T.QaddA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200F10, 0x0FF00FF0, condConstraints, InstName.Qadd16, T.Qadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200F90, 0x0FF00FF0, condConstraints, InstName.Qadd8, T.Qadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200F30, 0x0FF00FF0, condConstraints, InstName.Qasx, T.QasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01400050, 0x0FF00FF0, condConstraints, InstName.Qdadd, T.QdaddA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01600050, 0x0FF00FF0, condConstraints, InstName.Qdsub, T.QdsubA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200F50, 0x0FF00FF0, condConstraints, InstName.Qsax, T.QsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01200050, 0x0FF00FF0, condConstraints, InstName.Qsub, T.QsubA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200F70, 0x0FF00FF0, condConstraints, InstName.Qsub16, T.Qsub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06200FF0, 0x0FF00FF0, condConstraints, InstName.Qsub8, T.Qsub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06FF0F30, 0x0FFF0FF0, condConstraints, InstName.Rbit, T.RbitA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06BF0F30, 0x0FFF0FF0, condConstraints, InstName.Rev, T.RevA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06BF0FB0, 0x0FFF0FF0, condConstraints, InstName.Rev16, T.Rev16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06FF0FB0, 0x0FFF0FF0, condConstraints, InstName.Revsh, T.RevshA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF8100A00, 0xFE50FFFF, InstName.Rfe, T.RfeA1, IsaVersion.v80, InstFlags.WBack),
+ new(0x02600000, 0x0FE00000, condConstraints, InstName.RsbI, T.RsbIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00600000, 0x0FE00010, condConstraints, InstName.RsbR, T.RsbRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00600010, 0x0FE00090, condConstraints, InstName.RsbRr, T.RsbRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x02E00000, 0x0FE00000, condConstraints, InstName.RscI, T.RscIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00E00000, 0x0FE00010, condConstraints, InstName.RscR, T.RscRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00E00010, 0x0FE00090, condConstraints, InstName.RscRr, T.RscRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06100F10, 0x0FF00FF0, condConstraints, InstName.Sadd16, T.Sadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06100F90, 0x0FF00FF0, condConstraints, InstName.Sadd8, T.Sadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06100F30, 0x0FF00FF0, condConstraints, InstName.Sasx, T.SasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF57FF070, 0xFFFFFFFF, InstName.Sb, T.SbA1, IsaVersion.v85, IsaFeature.FeatSb, InstFlags.None),
+ new(0x02C00000, 0x0FE00000, condConstraints, InstName.SbcI, T.SbcIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00C00000, 0x0FE00010, condConstraints, InstName.SbcR, T.SbcRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00C00010, 0x0FE00090, condConstraints, InstName.SbcRr, T.SbcRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x07A00050, 0x0FE00070, condConstraints, InstName.Sbfx, T.SbfxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0710F010, 0x0FF0F0F0, condConstraints, InstName.Sdiv, T.SdivA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x06800FB0, 0x0FF00FF0, condConstraints, InstName.Sel, T.SelA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF1010000, 0xFFFFFDFF, InstName.Setend, T.SetendA1, IsaVersion.v80, InstFlags.None),
+ new(0xF1100000, 0xFFFFFDFF, InstName.Setpan, T.SetpanA1, IsaVersion.v81, IsaFeature.FeatPan, InstFlags.None),
+ new(0x0320F004, 0x0FFFFFFF, condConstraints, InstName.Sev, T.SevA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F005, 0x0FFFFFFF, condConstraints, InstName.Sevl, T.SevlA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xF2000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1c, T.Sha1cA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF3B902C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1h, T.Sha1hA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF2200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1m, T.Sha1mA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF2100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1p, T.Sha1pA1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF2300C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1su0, T.Sha1su0A1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF3BA0380, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1su1, T.Sha1su1A1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xF3000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h, T.Sha256hA1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xF3100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h2, T.Sha256h2A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xF3BA03C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha256su0, T.Sha256su0A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xF3200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256su1, T.Sha256su1A1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0x06300F10, 0x0FF00FF0, condConstraints, InstName.Shadd16, T.Shadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06300F90, 0x0FF00FF0, condConstraints, InstName.Shadd8, T.Shadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06300F30, 0x0FF00FF0, condConstraints, InstName.Shasx, T.ShasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06300F50, 0x0FF00FF0, condConstraints, InstName.Shsax, T.ShsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06300F70, 0x0FF00FF0, condConstraints, InstName.Shsub16, T.Shsub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06300FF0, 0x0FF00FF0, condConstraints, InstName.Shsub8, T.Shsub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x01600070, 0x0FFFFFF0, condConstraints, InstName.Smc, T.SmcA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01000080, 0x0FF00090, condConstraints, InstName.Smlabb, T.SmlabbA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x07000010, 0x0FF000D0, condRaConstraints, InstName.Smlad, T.SmladA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x00E00090, 0x0FE000F0, condConstraints, InstName.Smlal, T.SmlalA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x01400080, 0x0FF00090, condConstraints, InstName.Smlalbb, T.SmlalbbA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x07400010, 0x0FF000D0, condConstraints, InstName.Smlald, T.SmlaldA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x01200080, 0x0FF000B0, condConstraints, InstName.Smlawb, T.SmlawbA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x07000050, 0x0FF000D0, condRaConstraints, InstName.Smlsd, T.SmlsdA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x07400050, 0x0FF000D0, condConstraints, InstName.Smlsld, T.SmlsldA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x07500010, 0x0FF000D0, condRaConstraints, InstName.Smmla, T.SmmlaA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x075000D0, 0x0FF000D0, condConstraints, InstName.Smmls, T.SmmlsA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x0750F010, 0x0FF0F0D0, condConstraints, InstName.Smmul, T.SmmulA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x0700F010, 0x0FF0F0D0, condConstraints, InstName.Smuad, T.SmuadA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x01600080, 0x0FF0F090, condConstraints, InstName.Smulbb, T.SmulbbA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x00C00090, 0x0FE000F0, condConstraints, InstName.Smull, T.SmullA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x012000A0, 0x0FF0F0B0, condConstraints, InstName.Smulwb, T.SmulwbA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x0700F050, 0x0FF0F0D0, condConstraints, InstName.Smusd, T.SmusdA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0xF84D0500, 0xFE5FFFE0, InstName.Srs, T.SrsA1, IsaVersion.v80, InstFlags.WBack),
+ new(0x06A00010, 0x0FE00030, condConstraints, InstName.Ssat, T.SsatA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06A00F30, 0x0FF00FF0, condConstraints, InstName.Ssat16, T.Ssat16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06100F50, 0x0FF00FF0, condConstraints, InstName.Ssax, T.SsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF57FF040, 0xFFFFFFFF, InstName.Ssbb, T.SsbbA1, IsaVersion.v80, InstFlags.None),
+ new(0x06100F70, 0x0FF00FF0, condConstraints, InstName.Ssub16, T.Ssub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06100FF0, 0x0FF00FF0, condConstraints, InstName.Ssub8, T.Ssub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0C005E00, 0x0E50FF00, condPuwConstraints, InstName.Stc, T.StcA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0180FC90, 0x0FF0FFF0, condConstraints, InstName.Stl, T.StlA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x01C0FC90, 0x0FF0FFF0, condConstraints, InstName.Stlb, T.StlbA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x01800E90, 0x0FF00FF0, condConstraints, InstName.Stlex, T.StlexA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x01C00E90, 0x0FF00FF0, condConstraints, InstName.Stlexb, T.StlexbA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x01A00E90, 0x0FF00FF0, condConstraints, InstName.Stlexd, T.StlexdA1, IsaVersion.v80, InstFlags.CondRdRt2Read),
+ new(0x01E00E90, 0x0FF00FF0, condConstraints, InstName.Stlexh, T.StlexhA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x01E0FC90, 0x0FF0FFF0, condConstraints, InstName.Stlh, T.StlhA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x08800000, 0x0FD00000, condConstraints, InstName.Stm, T.StmA1, IsaVersion.v80, InstFlags.CondRlistReadWBack),
+ new(0x08000000, 0x0FD00000, condConstraints, InstName.Stmda, T.StmdaA1, IsaVersion.v80, InstFlags.CondRlistReadWBack),
+ new(0x09000000, 0x0FD00000, condConstraints, InstName.Stmdb, T.StmdbA1, IsaVersion.v80, InstFlags.CondRlistReadWBack),
+ new(0x09800000, 0x0FD00000, condConstraints, InstName.Stmib, T.StmibA1, IsaVersion.v80, InstFlags.CondRlistReadWBack),
+ new(0x08400000, 0x0E700000, condConstraints, InstName.StmU, T.StmUA1, IsaVersion.v80, InstFlags.CondRlistRead),
+ new(0x04600000, 0x0F700000, condConstraints, InstName.Strbt, T.StrbtA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x06600000, 0x0F700010, condConstraints, InstName.Strbt, T.StrbtA2, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x04400000, 0x0E500000, condPwConstraints, InstName.StrbI, T.StrbIA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x06400000, 0x0E500010, condPwConstraints, InstName.StrbR, T.StrbRA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x004000F0, 0x0E5000F0, condConstraints, InstName.StrdI, T.StrdIA1, IsaVersion.v80, InstFlags.CondRt2ReadWBack),
+ new(0x000000F0, 0x0E500FF0, condConstraints, InstName.StrdR, T.StrdRA1, IsaVersion.v80, InstFlags.CondRt2ReadWBack),
+ new(0x01800F90, 0x0FF00FF0, condConstraints, InstName.Strex, T.StrexA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x01C00F90, 0x0FF00FF0, condConstraints, InstName.Strexb, T.StrexbA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x01A00F90, 0x0FF00FF0, condConstraints, InstName.Strexd, T.StrexdA1, IsaVersion.v80, InstFlags.CondRdRt2Read),
+ new(0x01E00F90, 0x0FF00FF0, condConstraints, InstName.Strexh, T.StrexhA1, IsaVersion.v80, InstFlags.CondRdRtRead),
+ new(0x006000B0, 0x0F7000F0, condConstraints, InstName.Strht, T.StrhtA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x002000B0, 0x0F700FF0, condConstraints, InstName.Strht, T.StrhtA2, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x004000B0, 0x0E5000F0, condPwConstraints, InstName.StrhI, T.StrhIA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x000000B0, 0x0E500FF0, condPwConstraints, InstName.StrhR, T.StrhRA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x04200000, 0x0F700000, condConstraints, InstName.Strt, T.StrtA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x06200000, 0x0F700010, condConstraints, InstName.Strt, T.StrtA2, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x04000000, 0x0E500000, condPwConstraints, InstName.StrI, T.StrIA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x06000000, 0x0E500010, condPwConstraints, InstName.StrR, T.StrRA1, IsaVersion.v80, InstFlags.CondRtReadWBack),
+ new(0x02400000, 0x0FE00000, condRnsRnConstraints, InstName.SubI, T.SubIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00400000, 0x0FE00010, condRnConstraints, InstName.SubR, T.SubRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00400010, 0x0FE00090, condConstraints, InstName.SubRr, T.SubRrA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x024D0000, 0x0FEF0000, condConstraints, InstName.SubSpI, T.SubSpIA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x004D0000, 0x0FEF0010, condConstraints, InstName.SubSpR, T.SubSpRA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0F000000, 0x0F000000, condConstraints, InstName.Svc, T.SvcA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x06A00070, 0x0FF003F0, condRnConstraints3, InstName.Sxtab, T.SxtabA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06800070, 0x0FF003F0, condRnConstraints3, InstName.Sxtab16, T.Sxtab16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06B00070, 0x0FF003F0, condRnConstraints3, InstName.Sxtah, T.SxtahA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06AF0070, 0x0FFF03F0, condConstraints, InstName.Sxtb, T.SxtbA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x068F0070, 0x0FFF03F0, condConstraints, InstName.Sxtb16, T.Sxtb16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06BF0070, 0x0FFF03F0, condConstraints, InstName.Sxth, T.SxthA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x03300000, 0x0FF0F000, condConstraints, InstName.TeqI, T.TeqIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01300000, 0x0FF0F010, condConstraints, InstName.TeqR, T.TeqRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01300010, 0x0FF0F090, condConstraints, InstName.TeqRr, T.TeqRrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F012, 0x0FFFFFFF, condConstraints, InstName.Tsb, T.TsbA1, IsaVersion.v84, IsaFeature.FeatTrf, InstFlags.Cond),
+ new(0x03100000, 0x0FF0F000, condConstraints, InstName.TstI, T.TstIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01100000, 0x0FF0F010, condConstraints, InstName.TstR, T.TstRA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x01100010, 0x0FF0F090, condConstraints, InstName.TstRr, T.TstRrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x06500F10, 0x0FF00FF0, condConstraints, InstName.Uadd16, T.Uadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06500F90, 0x0FF00FF0, condConstraints, InstName.Uadd8, T.Uadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06500F30, 0x0FF00FF0, condConstraints, InstName.Uasx, T.UasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x07E00050, 0x0FE00070, condConstraints, InstName.Ubfx, T.UbfxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xE7F000F0, 0xFFF000F0, InstName.Udf, T.UdfA1, IsaVersion.v80, InstFlags.None),
+ new(0x0730F010, 0x0FF0F0F0, condConstraints, InstName.Udiv, T.UdivA1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x06700F10, 0x0FF00FF0, condConstraints, InstName.Uhadd16, T.Uhadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06700F90, 0x0FF00FF0, condConstraints, InstName.Uhadd8, T.Uhadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06700F30, 0x0FF00FF0, condConstraints, InstName.Uhasx, T.UhasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06700F50, 0x0FF00FF0, condConstraints, InstName.Uhsax, T.UhsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06700F70, 0x0FF00FF0, condConstraints, InstName.Uhsub16, T.Uhsub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06700FF0, 0x0FF00FF0, condConstraints, InstName.Uhsub8, T.Uhsub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x00400090, 0x0FF000F0, condConstraints, InstName.Umaal, T.UmaalA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x00A00090, 0x0FE000F0, condConstraints, InstName.Umlal, T.UmlalA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x00800090, 0x0FE000F0, condConstraints, InstName.Umull, T.UmullA1, IsaVersion.v80, InstFlags.CondRdLoHi),
+ new(0x06600F10, 0x0FF00FF0, condConstraints, InstName.Uqadd16, T.Uqadd16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06600F90, 0x0FF00FF0, condConstraints, InstName.Uqadd8, T.Uqadd8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06600F30, 0x0FF00FF0, condConstraints, InstName.Uqasx, T.UqasxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06600F50, 0x0FF00FF0, condConstraints, InstName.Uqsax, T.UqsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06600F70, 0x0FF00FF0, condConstraints, InstName.Uqsub16, T.Uqsub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06600FF0, 0x0FF00FF0, condConstraints, InstName.Uqsub8, T.Uqsub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x0780F010, 0x0FF0F0F0, condConstraints, InstName.Usad8, T.Usad8A1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x07800010, 0x0FF000F0, condRaConstraints, InstName.Usada8, T.Usada8A1, IsaVersion.v80, InstFlags.CondRd16),
+ new(0x06E00010, 0x0FE00030, condConstraints, InstName.Usat, T.UsatA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06E00F30, 0x0FF00FF0, condConstraints, InstName.Usat16, T.Usat16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06500F50, 0x0FF00FF0, condConstraints, InstName.Usax, T.UsaxA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06500F70, 0x0FF00FF0, condConstraints, InstName.Usub16, T.Usub16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06500FF0, 0x0FF00FF0, condConstraints, InstName.Usub8, T.Usub8A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06E00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtab, T.UxtabA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06C00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtab16, T.Uxtab16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06F00070, 0x0FF003F0, condRnConstraints3, InstName.Uxtah, T.UxtahA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06EF0070, 0x0FFF03F0, condConstraints, InstName.Uxtb, T.UxtbA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06CF0070, 0x0FFF03F0, condConstraints, InstName.Uxtb16, T.Uxtb16A1, IsaVersion.v80, InstFlags.CondRd),
+ new(0x06FF0070, 0x0FFF03F0, condConstraints, InstName.Uxth, T.UxthA1, IsaVersion.v80, InstFlags.CondRd),
+ new(0xF2000710, 0xFE800F10, sizeQvdQvnQvmConstraints, InstName.Vaba, T.VabaA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800500, 0xFE800F50, sizeVdConstraints, InstName.Vabal, T.VabalA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800700, 0xFE800F50, sizeVdConstraints, InstName.VabdlI, T.VabdlIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000700, 0xFE800F10, sizeQvdQvnQvmConstraints, InstName.VabdI, T.VabdIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B10300, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90700, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50700, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB00AC0, 0x0FBF0ED0, condConstraints, InstName.Vabs, T.VabsA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB009C0, 0x0FBF0FD0, condConstraints, InstName.Vabs, T.VabsA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3000E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3200E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3300E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vaddhn, T.VaddhnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800000, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vaddl, T.VaddlA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800100, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vaddw, T.VaddwA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2100D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0E300A00, 0x0FB00E50, condConstraints, InstName.VaddF, T.VaddFA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E300900, 0x0FB00F50, condConstraints, InstName.VaddF, T.VaddFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VaddI, T.VaddIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VandR, T.VandRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800130, 0xFEB809B0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800930, 0xFEB80DB0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2100110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VbicR, T.VbicRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3300110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbif, T.VbifA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3200110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbit, T.VbitA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbsl, T.VbslA1, IsaVersion.v80, InstFlags.None),
+ new(0xFC900800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0xFC800800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddA1, IsaVersion.v83, IsaFeature.FeatFcma | IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B10100, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90500, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50500, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.VceqR, T.VceqRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B10080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90480, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50480, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000310, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VcgeR, T.VcgeRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRA2, IsaVersion.v80, InstFlags.None),
+ new(0xF3100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B10000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90400, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50400, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000300, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VcgtR, T.VcgtRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3200E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRA2, IsaVersion.v80, InstFlags.None),
+ new(0xF3300E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B10180, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90580, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50580, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B00400, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vcls, T.VclsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B10200, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90600, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50600, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B00480, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vclz, T.VclzA1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200800, 0xFE200F10, qvdQvnQvmConstraints, InstName.Vcmla, T.VcmlaA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0xFE000800, 0xFF000F10, qvdQvnConstraints, InstName.VcmlaS, T.VcmlaSA1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0x0EB40A40, 0x0FBF0ED0, condConstraints, InstName.Vcmp, T.VcmpA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB40940, 0x0FBF0FD0, condConstraints, InstName.Vcmp, T.VcmpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0EB50A40, 0x0FBF0EFF, condConstraints, InstName.Vcmp, T.VcmpA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB50940, 0x0FBF0FFF, condConstraints, InstName.Vcmp, T.VcmpA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0EB40AC0, 0x0FBF0ED0, condConstraints, InstName.Vcmpe, T.VcmpeA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB409C0, 0x0FBF0FD0, condConstraints, InstName.Vcmpe, T.VcmpeA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0EB50AC0, 0x0FBF0EFF, condConstraints, InstName.Vcmpe, T.VcmpeA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB509C0, 0x0FBF0FFF, condConstraints, InstName.Vcmpe, T.VcmpeA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3B00500, 0xFFBF0F90, qvdQvmConstraints, InstName.Vcnt, T.VcntA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BB0000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B70000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBC0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBC0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB20A40, 0x0FBE0ED0, condConstraints, InstName.Vcvtb, T.VcvtbA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB30940, 0x0FBF0FD0, condConstraints, InstName.VcvtbBfs, T.VcvtbBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.Cond),
+ new(0xF3BB0300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B70300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBF0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBF0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3BB0100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B70100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBD0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBD0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3BB0200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B70200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBE0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBE0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EBC0A40, 0x0FBE0ED0, condConstraints, InstName.VcvtrIv, T.VcvtrIvA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EBC0940, 0x0FBE0FD0, condConstraints, InstName.VcvtrIv, T.VcvtrIvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0EB20AC0, 0x0FBE0ED0, condConstraints, InstName.Vcvtt, T.VcvttA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB309C0, 0x0FBF0FD0, condConstraints, InstName.VcvttBfs, T.VcvttBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.Cond),
+ new(0xF3B60640, 0xFFBF0FD0, vmConstraints, InstName.VcvtBfs, T.VcvtBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0x0EB70AC0, 0x0FBF0ED0, condConstraints, InstName.VcvtDs, T.VcvtDsA1, IsaVersion.v80, InstFlags.Cond),
+ new(0xF3B60600, 0xFFBF0ED0, opvdOpvmConstraints, InstName.VcvtHs, T.VcvtHsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BB0600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B70600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EBC0AC0, 0x0FBE0ED0, condConstraints, InstName.VcvtIv, T.VcvtIvA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EBC09C0, 0x0FBE0FD0, condConstraints, InstName.VcvtIv, T.VcvtIvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0EB80A40, 0x0FBF0E50, condConstraints, InstName.VcvtVi, T.VcvtViA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB80940, 0x0FBF0F50, condConstraints, InstName.VcvtVi, T.VcvtViA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2800E10, 0xFE800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800C10, 0xFE800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EBA0A40, 0x0FBA0E50, condConstraints, InstName.VcvtXv, T.VcvtXvA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EBA0940, 0x0FBA0F50, condConstraints, InstName.VcvtXv, T.VcvtXvA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0E800A00, 0x0FB00E50, condConstraints, InstName.Vdiv, T.VdivA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E800900, 0x0FB00F50, condConstraints, InstName.Vdiv, T.VdivA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xFC000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vdot, T.VdotA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFE000D00, 0xFFB00F10, qvdQvnConstraints, InstName.VdotS, T.VdotSA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0x0E800B10, 0x0F900F5F, condQvdEbConstraints, InstName.VdupR, T.VdupRA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0xF3B00C00, 0xFFB00F90, imm4QvdConstraints, InstName.VdupS, T.VdupSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Veor, T.VeorA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2B00000, 0xFFB00010, qvdQvnQvmQimm4Constraints, InstName.Vext, T.VextA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2100C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EA00A00, 0x0FB00E50, condConstraints, InstName.Vfma, T.VfmaA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EA00900, 0x0FB00F50, condConstraints, InstName.Vfma, T.VfmaA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xFC200810, 0xFFB00F10, qvdConstraints, InstName.Vfmal, T.VfmalA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFE000810, 0xFFB00F10, qvdConstraints, InstName.VfmalS, T.VfmalSA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFC300810, 0xFFB00F10, vdVnVmConstraints, InstName.VfmaBf, T.VfmaBfA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFE300810, 0xFFB00F10, vdVnConstraints, InstName.VfmaBfs, T.VfmaBfsA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xF2200C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2300C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EA00A40, 0x0FB00E50, condConstraints, InstName.Vfms, T.VfmsA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EA00940, 0x0FB00F50, condConstraints, InstName.Vfms, T.VfmsA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xFCA00810, 0xFFB00F10, qvdConstraints, InstName.Vfmsl, T.VfmslA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFE100810, 0xFFB00F10, qvdConstraints, InstName.VfmslS, T.VfmslSA1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0x0E900A40, 0x0FB00E50, condConstraints, InstName.Vfnma, T.VfnmaA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E900940, 0x0FB00F50, condConstraints, InstName.Vfnma, T.VfnmaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0E900A00, 0x0FB00E50, condConstraints, InstName.Vfnms, T.VfnmsA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E900900, 0x0FB00F50, condConstraints, InstName.Vfnms, T.VfnmsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2000000, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vhadd, T.VhaddA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000200, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vhsub, T.VhsubA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB00AC0, 0xFFBF0FD0, InstName.Vins, T.VinsA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB90BC0, 0x0FBF0FD0, condConstraints, InstName.Vjcvt, T.VjcvtA1, IsaVersion.v83, IsaFeature.FeatJscvt, InstFlags.Cond),
+ new(0xF4A00000, 0xFFB00F10, sizeConstraints2, InstName.Vld11, T.Vld11A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00400, 0xFFB00F20, sizeConstraints2, InstName.Vld11, T.Vld11A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vld11, T.Vld11A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00C00, 0xFFB00F00, sizeSizeaConstraints, InstName.Vld1A, T.Vld1AA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200700, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200A00, 0xFFB00F00, alignConstraints2, InstName.Vld1M, T.Vld1MA2, IsaVersion.v80, InstFlags.None),
+ new(0xF4200600, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MA3, IsaVersion.v80, InstFlags.None),
+ new(0xF4200200, 0xFFB00F00, InstName.Vld1M, T.Vld1MA4, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00100, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00500, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00900, 0xFFB00F20, sizeConstraints2, InstName.Vld21, T.Vld21A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00D00, 0xFFB00F00, sizeConstraints3, InstName.Vld2A, T.Vld2AA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200800, 0xFFB00E00, alignSizeConstraints, InstName.Vld2M, T.Vld2MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200300, 0xFFB00F00, sizeConstraints3, InstName.Vld2M, T.Vld2MA2, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00200, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00600, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00A00, 0xFFB00F30, sizeConstraints2, InstName.Vld31, T.Vld31A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00E00, 0xFFB00F10, sizeAConstraints, InstName.Vld3A, T.Vld3AA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200400, 0xFFB00E00, sizeAlignConstraints, InstName.Vld3M, T.Vld3MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00300, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00700, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vld41, T.Vld41A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4A00F00, 0xFFB00F00, sizeaConstraints, InstName.Vld4A, T.Vld4AA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4200000, 0xFFB00E00, sizeConstraints3, InstName.Vld4M, T.Vld4MA1, IsaVersion.v80, InstFlags.None),
+ new(0x0C100B00, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Vldm, T.VldmA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0C100A00, 0x0E100F00, condPuwPwPuwPuwConstraints, InstName.Vldm, T.VldmA2, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0D100A00, 0x0F300E00, condRnConstraints3, InstName.VldrI, T.VldrIA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0D100900, 0x0F300F00, condRnConstraints3, InstName.VldrI, T.VldrIA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0D1F0A00, 0x0F3F0E00, condConstraints, InstName.VldrL, T.VldrLA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0D1F0900, 0x0F3F0F00, condConstraints, InstName.VldrL, T.VldrLA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFE800A00, 0xFFB00E50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmA2, IsaVersion.v80, InstFlags.None),
+ new(0xFE800900, 0xFFB00F50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2100F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000600, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VmaxI, T.VmaxIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFE800A40, 0xFFB00E50, sizeConstraints, InstName.Vminnm, T.VminnmA2, IsaVersion.v80, InstFlags.None),
+ new(0xFE800940, 0xFFB00F50, sizeConstraints, InstName.Vminnm, T.VminnmA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2200F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2300F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000610, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.VminI, T.VminIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800800, 0xFE800F50, sizeVdConstraints, InstName.VmlalI, T.VmlalIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800240, 0xFE800F50, sizeSizeVdConstraints, InstName.VmlalS, T.VmlalSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0E000A00, 0x0FB00E50, condConstraints, InstName.VmlaF, T.VmlaFA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E000900, 0x0FB00F50, condConstraints, InstName.VmlaF, T.VmlaFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlaI, T.VmlaIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2A00040, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900040, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900140, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2800A00, 0xFE800F50, sizeVdConstraints, InstName.VmlslI, T.VmlslIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800640, 0xFE800F50, sizeSizeVdConstraints, InstName.VmlslS, T.VmlslSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2300D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0E000A40, 0x0FB00E50, condConstraints, InstName.VmlsF, T.VmlsFA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E000940, 0x0FB00F50, condConstraints, InstName.VmlsF, T.VmlsFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlsI, T.VmlsIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2A00440, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900440, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900540, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFC000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vmmla, T.VmmlaA1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xF2800A10, 0xFE870FD0, imm3hImm3hImm3hImm3hImm3hVdConstraints, InstName.Vmovl, T.VmovlA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B20200, 0xFFB30FD0, sizeVmConstraints, InstName.Vmovn, T.VmovnA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB00A40, 0xFFBF0FD0, InstName.Vmovx, T.VmovxA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0C400B10, 0x0FE00FD0, condConstraints, InstName.VmovD, T.VmovDA1, IsaVersion.v80, InstFlags.CondRt2Read),
+ new(0x0E000910, 0x0FE00F7F, condConstraints, InstName.VmovH, T.VmovHA1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.CondRt),
+ new(0xF2800010, 0xFEB809B0, qvdConstraints, InstName.VmovI, T.VmovIA1, IsaVersion.v80, InstFlags.None),
+ new(0x0EB00A00, 0x0FB00EF0, condConstraints, InstName.VmovI, T.VmovIA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB00900, 0x0FB00FF0, condConstraints, InstName.VmovI, T.VmovIA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2800810, 0xFEB80DB0, qvdConstraints, InstName.VmovI, T.VmovIA3, IsaVersion.v80, InstFlags.None),
+ new(0xF2800C10, 0xFEB80CB0, qvdConstraints, InstName.VmovI, T.VmovIA4, IsaVersion.v80, InstFlags.None),
+ new(0xF2800E30, 0xFEB80FB0, qvdConstraints, InstName.VmovI, T.VmovIA5, IsaVersion.v80, InstFlags.None),
+ new(0x0EB00A40, 0x0FBF0ED0, condConstraints, InstName.VmovR, T.VmovRA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E000B10, 0x0F900F1F, condOpc1opc2Constraints, InstName.VmovRs, T.VmovRsA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x0E000A10, 0x0FE00F7F, condConstraints, InstName.VmovS, T.VmovSA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0x0E100B10, 0x0F100F1F, condUopc1opc2Uopc1opc2Constraints, InstName.VmovSr, T.VmovSrA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x0C400A10, 0x0FE00FD0, condConstraints, InstName.VmovSs, T.VmovSsA1, IsaVersion.v80, InstFlags.CondRt2Read),
+ new(0x0EF00A10, 0x0FF00FFF, condConstraints, InstName.Vmrs, T.VmrsA1, IsaVersion.v80, InstFlags.CondRt),
+ new(0x0EE00A10, 0x0FF00FFF, condConstraints, InstName.Vmsr, T.VmsrA1, IsaVersion.v80, InstFlags.CondRtRead),
+ new(0xF2800C00, 0xFE800D50, sizeOpuOpsizeVdConstraints, InstName.VmullI, T.VmullIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800A40, 0xFE800F50, sizeSizeVdConstraints, InstName.VmullS, T.VmullSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0E200A00, 0x0FB00E50, condConstraints, InstName.VmulF, T.VmulFA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E200900, 0x0FB00F50, condConstraints, InstName.VmulF, T.VmulFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2000910, 0xFE800F10, sizeOpsizeOpsizeQvdQvnQvmConstraints, InstName.VmulI, T.VmulIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2A00840, 0xFEA00E50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900840, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2900940, 0xFEB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulSA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2800030, 0xFEB809B0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800830, 0xFEB80DB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2800C30, 0xFEB80EB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIA3, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00580, 0xFFBF0F90, qvdQvmConstraints, InstName.VmvnR, T.VmvnRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B10380, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B90780, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B50780, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB10A40, 0x0FBF0ED0, condConstraints, InstName.Vneg, T.VnegA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB10940, 0x0FBF0FD0, condConstraints, InstName.Vneg, T.VnegA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0E100A40, 0x0FB00E50, condConstraints, InstName.Vnmla, T.VnmlaA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E100940, 0x0FB00F50, condConstraints, InstName.Vnmla, T.VnmlaA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0E100A00, 0x0FB00E50, condConstraints, InstName.Vnmls, T.VnmlsA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E100900, 0x0FB00F50, condConstraints, InstName.Vnmls, T.VnmlsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0x0E200A40, 0x0FB00E50, condConstraints, InstName.Vnmul, T.VnmulA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E200940, 0x0FB00F50, condConstraints, InstName.Vnmul, T.VnmulA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2300110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VornR, T.VornRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800110, 0xFEB809B0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800910, 0xFEB80DB0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2200110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VorrR, T.VorrRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00600, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpadal, T.VpadalA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00200, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpaddl, T.VpaddlA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000B10, 0xFF800F10, sizeQConstraints, InstName.VpaddI, T.VpaddIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3100F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000A00, 0xFE800F50, sizeConstraints4, InstName.VpmaxI, T.VpmaxIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3200F00, 0xFFB00F50, InstName.VpminF, T.VpminFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3300F00, 0xFFB00F50, InstName.VpminF, T.VpminFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2000A10, 0xFE800F50, sizeConstraints4, InstName.VpminI, T.VpminIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00700, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqabs, T.VqabsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000010, 0xFE800F10, qvdQvnQvmConstraints, InstName.Vqadd, T.VqaddA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800900, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800340, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2800B00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800740, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqdmulh, T.VqdmulhA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800C40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqdmulh, T.VqdmulhA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2800D00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800B40, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullA2, IsaVersion.v80, InstFlags.None),
+ new(0xF3B20200, 0xFFB30F10, opSizeVmConstraints, InstName.Vqmovn, T.VqmovnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00780, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqneg, T.VqnegA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3000B10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlah, T.VqrdmlahA1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xF2800E40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlah, T.VqrdmlahA2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xF3000C10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlsh, T.VqrdmlshA1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xF2800F40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlsh, T.VqrdmlshA2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xF3000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmulh, T.VqrdmulhA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800D40, 0xFE800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmulh, T.VqrdmulhA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2000510, 0xFE800F10, qvdQvmQvnConstraints, InstName.Vqrshl, T.VqrshlA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800850, 0xFE800ED0, imm6UopVmConstraints, InstName.Vqrshrn, T.VqrshrnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800610, 0xFE800E10, imm6lUopQvdQvmConstraints, InstName.VqshlI, T.VqshlIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000410, 0xFE800F10, qvdQvmQvnConstraints, InstName.VqshlR, T.VqshlRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800810, 0xFE800ED0, imm6UopVmConstraints, InstName.Vqshrn, T.VqshrnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000210, 0xFE800F10, qvdQvnQvmConstraints, InstName.Vqsub, T.VqsubA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vraddhn, T.VraddhnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B30400, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrecpe, T.VrecpeA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3B00100, 0xFFB30F90, sizeSizeSizeQvdQvmConstraints, InstName.Vrev16, T.Vrev16A1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00080, 0xFFB30F90, sizeSizeQvdQvmConstraints, InstName.Vrev32, T.Vrev32A1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vrev64, T.Vrev64A1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000100, 0xFE800F10, qvdQvnQvmSizeConstraints, InstName.Vrhadd, T.VrhaddA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BA0500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEB80A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB80940, 0xFFBF0FD0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3BA0680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBB0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBB0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3BA0400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEB90A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB90940, 0xFFBF0FD0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF3BA0780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBA0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpA1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBA0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB60A40, 0x0FBF0ED0, condConstraints, InstName.VrintrVfp, T.VrintrVfpA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB60940, 0x0FBF0FD0, condConstraints, InstName.VrintrVfp, T.VrintrVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3BA0480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB70A40, 0x0FBF0ED0, condConstraints, InstName.VrintxVfp, T.VrintxVfpA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB70940, 0x0FBF0FD0, condConstraints, InstName.VrintxVfp, T.VrintxVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3BA0580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B60580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0EB60AC0, 0x0FBF0ED0, condConstraints, InstName.VrintzVfp, T.VrintzVfpA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB609C0, 0x0FBF0FD0, condConstraints, InstName.VrintzVfp, T.VrintzVfpA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2000500, 0xFE800F10, qvdQvmQvnConstraints, InstName.Vrshl, T.VrshlA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800210, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vrshr, T.VrshrA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800850, 0xFF800FD0, imm6VmConstraints, InstName.Vrshrn, T.VrshrnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B30480, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrsqrte, T.VrsqrteA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2800310, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vrsra, T.VrsraA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vrsubhn, T.VrsubhnA1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vsdot, T.VsdotA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE200D00, 0xFFB00F10, qvdQvnConstraints, InstName.VsdotS, T.VsdotSA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE000A00, 0xFF800E50, sizeConstraints, InstName.Vsel, T.VselA1, IsaVersion.v80, InstFlags.None),
+ new(0xFE000900, 0xFF800F50, sizeConstraints, InstName.Vsel, T.VselA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xF2800A10, 0xFE800FD0, imm6VdImm6Imm6Imm6Constraints, InstName.Vshll, T.VshllA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B20300, 0xFFB30FD0, sizeVdConstraints2, InstName.Vshll, T.VshllA2, IsaVersion.v80, InstFlags.None),
+ new(0xF2800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.VshlI, T.VshlIA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000400, 0xFE800F10, qvdQvmQvnConstraints, InstName.VshlR, T.VshlRA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800010, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vshr, T.VshrA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800810, 0xFF800FD0, imm6VmConstraints, InstName.Vshrn, T.VshrnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsli, T.VsliA1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vsmmla, T.VsmmlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0x0EB10AC0, 0x0FBF0ED0, condConstraints, InstName.Vsqrt, T.VsqrtA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0EB109C0, 0x0FBF0FD0, condConstraints, InstName.Vsqrt, T.VsqrtA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2800110, 0xFE800F10, imm6lQvdQvmConstraints, InstName.Vsra, T.VsraA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3800410, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsri, T.VsriA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800000, 0xFFB00F10, sizeConstraints2, InstName.Vst11, T.Vst11A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800400, 0xFFB00F20, sizeConstraints2, InstName.Vst11, T.Vst11A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4800800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vst11, T.Vst11A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4000700, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4000A00, 0xFFB00F00, alignConstraints2, InstName.Vst1M, T.Vst1MA2, IsaVersion.v80, InstFlags.None),
+ new(0xF4000600, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MA3, IsaVersion.v80, InstFlags.None),
+ new(0xF4000200, 0xFFB00F00, InstName.Vst1M, T.Vst1MA4, IsaVersion.v80, InstFlags.None),
+ new(0xF4800100, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800500, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4800900, 0xFFB00F20, sizeConstraints2, InstName.Vst21, T.Vst21A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4000800, 0xFFB00E00, alignSizeConstraints, InstName.Vst2M, T.Vst2MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4000300, 0xFFB00F00, sizeConstraints3, InstName.Vst2M, T.Vst2MA2, IsaVersion.v80, InstFlags.None),
+ new(0xF4800200, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800600, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4800A00, 0xFFB00F30, sizeConstraints2, InstName.Vst31, T.Vst31A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4000400, 0xFFB00E00, sizeAlignConstraints, InstName.Vst3M, T.Vst3MA1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800300, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41A1, IsaVersion.v80, InstFlags.None),
+ new(0xF4800700, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41A2, IsaVersion.v80, InstFlags.None),
+ new(0xF4800B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vst41, T.Vst41A3, IsaVersion.v80, InstFlags.None),
+ new(0xF4000000, 0xFFB00E00, sizeConstraints3, InstName.Vst4M, T.Vst4MA1, IsaVersion.v80, InstFlags.None),
+ new(0x0C000B00, 0x0E100F01, condPuwPwPuwPuwConstraints, InstName.Vstm, T.VstmA1, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0C000A00, 0x0E100F00, condPuwPwPuwPuwConstraints, InstName.Vstm, T.VstmA2, IsaVersion.v80, InstFlags.CondWBack),
+ new(0x0D000A00, 0x0F300E00, condConstraints, InstName.Vstr, T.VstrA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0D000900, 0x0F300F00, condConstraints, InstName.Vstr, T.VstrA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF2800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vsubhn, T.VsubhnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800200, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vsubl, T.VsublA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2800300, 0xFE800F50, sizeVdOpvnConstraints, InstName.Vsubw, T.VsubwA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFA1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0x0E300A40, 0x0FB00E50, condConstraints, InstName.VsubF, T.VsubFA2, IsaVersion.v80, InstFlags.Cond),
+ new(0x0E300940, 0x0FB00F50, condConstraints, InstName.VsubF, T.VsubFA2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.Cond),
+ new(0xF3000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VsubI, T.VsubIA1, IsaVersion.v80, InstFlags.None),
+ new(0xFE800D10, 0xFFB00F10, qvdQvnConstraints, InstName.VsudotS, T.VsudotSA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xF3B20000, 0xFFBF0F90, qvdQvmConstraints, InstName.Vswp, T.VswpA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B00800, 0xFFB00C10, InstName.Vtbl, T.VtblA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B20080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vtrn, T.VtrnA1, IsaVersion.v80, InstFlags.None),
+ new(0xF2000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.Vtst, T.VtstA1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vudot, T.VudotA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE200D10, 0xFFB00F10, qvdQvnConstraints, InstName.VudotS, T.VudotSA1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFC200C50, 0xFFB00F50, vdVnVmConstraints, InstName.Vummla, T.VummlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFCA00D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vusdot, T.VusdotA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFE800D00, 0xFFB00F10, qvdQvnConstraints, InstName.VusdotS, T.VusdotSA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFCA00C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vusmmla, T.VusmmlaA1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xF3B20100, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vuzp, T.VuzpA1, IsaVersion.v80, InstFlags.None),
+ new(0xF3B20180, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vzip, T.VzipA1, IsaVersion.v80, InstFlags.None),
+ new(0x0320F002, 0x0FFFFFFF, condConstraints, InstName.Wfe, T.WfeA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F003, 0x0FFFFFFF, condConstraints, InstName.Wfi, T.WfiA1, IsaVersion.v80, InstFlags.Cond),
+ new(0x0320F001, 0x0FFFFFFF, condConstraints, InstName.Yield, T.YieldA1, IsaVersion.v80, InstFlags.Cond),
+ };
+
+ _table = new(insts);
+ }
+
+ public static InstMeta GetMeta(uint encoding, IsaVersion version, IsaFeature features)
+ {
+ if (_table.TryFind(encoding, version, features, out InstInfoForTable info))
+ {
+ return info.Meta;
+ }
+
+ return new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs
new file mode 100644
index 00000000..7ff5f6c9
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs
@@ -0,0 +1,146 @@
+using Ryujinx.Cpu.LightningJit.Table;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class InstTableT16 where T : IInstEmit
+ {
+ private static readonly InstTableLevel _table;
+
+ static InstTableT16()
+ {
+ InstEncoding[] rmRdndnConstraints = new InstEncoding[]
+ {
+ new(0x00680000, 0x00780000),
+ new(0x00850000, 0x00870000),
+ };
+
+ InstEncoding[] rmConstraints = new InstEncoding[]
+ {
+ new(0x00680000, 0x00780000),
+ };
+
+ InstEncoding[] condCondConstraints = new InstEncoding[]
+ {
+ new(0x0E000000, 0x0F000000),
+ new(0x0F000000, 0x0F000000),
+ };
+
+ InstEncoding[] maskConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x000F0000),
+ };
+
+ InstEncoding[] opConstraints = new InstEncoding[]
+ {
+ new(0x18000000, 0x18000000),
+ };
+
+ InstEncoding[] opOpOpOpConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x03C00000),
+ new(0x00400000, 0x03C00000),
+ new(0x01400000, 0x03C00000),
+ new(0x01800000, 0x03C00000),
+ };
+
+ List insts = new()
+ {
+ new(0x41400000, 0xFFC00000, InstName.AdcR, T.AdcRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0x1C000000, 0xFE000000, InstName.AddI, T.AddIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x30000000, 0xF8000000, InstName.AddI, T.AddIT2, IsaVersion.v80, InstFlags.Rdn),
+ new(0x18000000, 0xFE000000, InstName.AddR, T.AddRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x44000000, 0xFF000000, rmRdndnConstraints, InstName.AddR, T.AddRT2, IsaVersion.v80, InstFlags.RdnDn),
+ new(0xA8000000, 0xF8000000, InstName.AddSpI, T.AddSpIT1, IsaVersion.v80, InstFlags.RdRd16),
+ new(0xB0000000, 0xFF800000, InstName.AddSpI, T.AddSpIT2, IsaVersion.v80, InstFlags.None),
+ new(0x44680000, 0xFF780000, InstName.AddSpR, T.AddSpRT1, IsaVersion.v80, InstFlags.None),
+ new(0x44850000, 0xFF870000, rmConstraints, InstName.AddSpR, T.AddSpRT2, IsaVersion.v80, InstFlags.None),
+ new(0xA0000000, 0xF8000000, InstName.Adr, T.AdrT1, IsaVersion.v80, InstFlags.RdRd16),
+ new(0x40000000, 0xFFC00000, InstName.AndR, T.AndRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0xD0000000, 0xF0000000, condCondConstraints, InstName.B, T.BT1, IsaVersion.v80, InstFlags.Cond),
+ new(0xE0000000, 0xF8000000, InstName.B, T.BT2, IsaVersion.v80, InstFlags.None),
+ new(0x43800000, 0xFFC00000, InstName.BicR, T.BicRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0xBE000000, 0xFF000000, InstName.Bkpt, T.BkptT1, IsaVersion.v80, InstFlags.None),
+ new(0x47800000, 0xFF870000, InstName.BlxR, T.BlxRT1, IsaVersion.v80, InstFlags.None),
+ new(0x47000000, 0xFF870000, InstName.Bx, T.BxT1, IsaVersion.v80, InstFlags.None),
+ new(0xB1000000, 0xF5000000, InstName.Cbnz, T.CbnzT1, IsaVersion.v80, InstFlags.None),
+ new(0x42C00000, 0xFFC00000, InstName.CmnR, T.CmnRT1, IsaVersion.v80, InstFlags.None),
+ new(0x28000000, 0xF8000000, InstName.CmpI, T.CmpIT1, IsaVersion.v80, InstFlags.None),
+ new(0x42800000, 0xFFC00000, InstName.CmpR, T.CmpRT1, IsaVersion.v80, InstFlags.None),
+ new(0x45000000, 0xFF000000, InstName.CmpR, T.CmpRT2, IsaVersion.v80, InstFlags.None),
+ new(0xB6600000, 0xFFE80000, InstName.Cps, T.CpsT1, IsaVersion.v80, InstFlags.None),
+ new(0x40400000, 0xFFC00000, InstName.EorR, T.EorRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0xBA800000, 0xFFC00000, InstName.Hlt, T.HltT1, IsaVersion.v80, InstFlags.None),
+ new(0xBF000000, 0xFF000000, maskConstraints, InstName.It, T.ItT1, IsaVersion.v80, InstFlags.None),
+ new(0xC8000000, 0xF8000000, InstName.Ldm, T.LdmT1, IsaVersion.v80, InstFlags.Rlist),
+ new(0x78000000, 0xF8000000, InstName.LdrbI, T.LdrbIT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x5C000000, 0xFE000000, InstName.LdrbR, T.LdrbRT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x88000000, 0xF8000000, InstName.LdrhI, T.LdrhIT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x5A000000, 0xFE000000, InstName.LdrhR, T.LdrhRT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x56000000, 0xFE000000, InstName.LdrsbR, T.LdrsbRT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x5E000000, 0xFE000000, InstName.LdrshR, T.LdrshRT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x68000000, 0xF8000000, InstName.LdrI, T.LdrIT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x98000000, 0xF8000000, InstName.LdrI, T.LdrIT2, IsaVersion.v80, InstFlags.RtRd16),
+ new(0x48000000, 0xF8000000, InstName.LdrL, T.LdrLT1, IsaVersion.v80, InstFlags.RtRd16),
+ new(0x58000000, 0xFE000000, InstName.LdrR, T.LdrRT1, IsaVersion.v80, InstFlags.Rt),
+ new(0x20000000, 0xF8000000, InstName.MovI, T.MovIT1, IsaVersion.v80, InstFlags.RdRd16),
+ new(0x46000000, 0xFF000000, InstName.MovR, T.MovRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x00000000, 0xE0000000, opConstraints, InstName.MovR, T.MovRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0x40000000, 0xFE000000, opOpOpOpConstraints, InstName.MovRr, T.MovRrT1, IsaVersion.v80, InstFlags.None),
+ new(0x43400000, 0xFFC00000, InstName.Mul, T.MulT1, IsaVersion.v80, InstFlags.None),
+ new(0x43C00000, 0xFFC00000, InstName.MvnR, T.MvnRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xBF000000, 0xFFFF0000, InstName.Nop, T.NopT1, IsaVersion.v80, InstFlags.None),
+ new(0x43000000, 0xFFC00000, InstName.OrrR, T.OrrRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0xBC000000, 0xFE000000, InstName.Pop, T.PopT1, IsaVersion.v80, InstFlags.Rlist),
+ new(0xB4000000, 0xFE000000, InstName.Push, T.PushT1, IsaVersion.v80, InstFlags.RlistRead),
+ new(0xBA000000, 0xFFC00000, InstName.Rev, T.RevT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xBA400000, 0xFFC00000, InstName.Rev16, T.Rev16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xBAC00000, 0xFFC00000, InstName.Revsh, T.RevshT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x42400000, 0xFFC00000, InstName.RsbI, T.RsbIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x41800000, 0xFFC00000, InstName.SbcR, T.SbcRT1, IsaVersion.v80, InstFlags.Rdn),
+ new(0xB6500000, 0xFFF70000, InstName.Setend, T.SetendT1, IsaVersion.v80, InstFlags.None),
+ new(0xB6100000, 0xFFF70000, InstName.Setpan, T.SetpanT1, IsaVersion.v81, IsaFeature.FeatPan, InstFlags.None),
+ new(0xBF400000, 0xFFFF0000, InstName.Sev, T.SevT1, IsaVersion.v80, InstFlags.None),
+ new(0xBF500000, 0xFFFF0000, InstName.Sevl, T.SevlT1, IsaVersion.v80, InstFlags.None),
+ new(0xC0000000, 0xF8000000, InstName.Stm, T.StmT1, IsaVersion.v80, InstFlags.RlistRead),
+ new(0x70000000, 0xF8000000, InstName.StrbI, T.StrbIT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x54000000, 0xFE000000, InstName.StrbR, T.StrbRT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x80000000, 0xF8000000, InstName.StrhI, T.StrhIT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x52000000, 0xFE000000, InstName.StrhR, T.StrhRT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x60000000, 0xF8000000, InstName.StrI, T.StrIT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x90000000, 0xF8000000, InstName.StrI, T.StrIT2, IsaVersion.v80, InstFlags.RtReadRd16),
+ new(0x50000000, 0xFE000000, InstName.StrR, T.StrRT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0x1E000000, 0xFE000000, InstName.SubI, T.SubIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x38000000, 0xF8000000, InstName.SubI, T.SubIT2, IsaVersion.v80, InstFlags.Rdn),
+ new(0x1A000000, 0xFE000000, InstName.SubR, T.SubRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xB0800000, 0xFF800000, InstName.SubSpI, T.SubSpIT1, IsaVersion.v80, InstFlags.None),
+ new(0xDF000000, 0xFF000000, InstName.Svc, T.SvcT1, IsaVersion.v80, InstFlags.None),
+ new(0xB2400000, 0xFFC00000, InstName.Sxtb, T.SxtbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xB2000000, 0xFFC00000, InstName.Sxth, T.SxthT1, IsaVersion.v80, InstFlags.Rd),
+ new(0x42000000, 0xFFC00000, InstName.TstR, T.TstRT1, IsaVersion.v80, InstFlags.None),
+ new(0xDE000000, 0xFF000000, InstName.Udf, T.UdfT1, IsaVersion.v80, InstFlags.None),
+ new(0xB2C00000, 0xFFC00000, InstName.Uxtb, T.UxtbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xB2800000, 0xFFC00000, InstName.Uxth, T.UxthT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xBF200000, 0xFFFF0000, InstName.Wfe, T.WfeT1, IsaVersion.v80, InstFlags.None),
+ new(0xBF300000, 0xFFFF0000, InstName.Wfi, T.WfiT1, IsaVersion.v80, InstFlags.None),
+ new(0xBF100000, 0xFFFF0000, InstName.Yield, T.YieldT1, IsaVersion.v80, InstFlags.None),
+ };
+
+ _table = new(insts);
+ }
+
+ public static bool TryGetMeta(uint encoding, IsaVersion version, IsaFeature features, out InstMeta meta)
+ {
+ if (_table.TryFind(encoding, version, features, out InstInfoForTable info))
+ {
+ meta = info.Meta;
+
+ return true;
+ }
+
+ meta = new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None);
+
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs
new file mode 100644
index 00000000..4a11effd
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs
@@ -0,0 +1,1212 @@
+using Ryujinx.Cpu.LightningJit.Table;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class InstTableT32 where T : IInstEmit
+ {
+ private static readonly InstTableLevel _table;
+
+ static InstTableT32()
+ {
+ InstEncoding[] rnRdsConstraints = new InstEncoding[]
+ {
+ new(0x000D0000, 0x000F0000),
+ new(0x00100F00, 0x00100F00),
+ };
+
+ InstEncoding[] rnRnConstraints = new InstEncoding[]
+ {
+ new(0x000D0000, 0x000F0000),
+ new(0x000F0000, 0x000F0000),
+ };
+
+ InstEncoding[] rdsConstraints = new InstEncoding[]
+ {
+ new(0x00100F00, 0x00100F00),
+ };
+
+ InstEncoding[] vdVmConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] condCondCondConstraints = new InstEncoding[]
+ {
+ new(0x03800000, 0x03C00000),
+ new(0x03C00000, 0x03C00000),
+ new(0x03800000, 0x03800000),
+ };
+
+ InstEncoding[] rnConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ };
+
+ InstEncoding[] hConstraints = new InstEncoding[]
+ {
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] imodmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00000700),
+ };
+
+ InstEncoding[] optionConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x0000000F),
+ };
+
+ InstEncoding[] puwPwPuwPuwConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x01A00000),
+ new(0x01000000, 0x01200000),
+ new(0x00200000, 0x01A00000),
+ new(0x01A00000, 0x01A00000),
+ };
+
+ InstEncoding[] rnPuwConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ new(0x00000000, 0x01A00000),
+ };
+
+ InstEncoding[] puwConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x01A00000),
+ };
+
+ InstEncoding[] rnRtConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ new(0x0000F000, 0x0000F000),
+ };
+
+ InstEncoding[] rnRtpuwPuwPwConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ new(0x0000F400, 0x0000F700),
+ new(0x00000600, 0x00000700),
+ new(0x00000000, 0x00000500),
+ };
+
+ InstEncoding[] rtConstraints = new InstEncoding[]
+ {
+ new(0x0000F000, 0x0000F000),
+ };
+
+ InstEncoding[] rnPwConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ new(0x00000000, 0x01200000),
+ };
+
+ InstEncoding[] pwConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x01200000),
+ };
+
+ InstEncoding[] rnPuwPwConstraints = new InstEncoding[]
+ {
+ new(0x000F0000, 0x000F0000),
+ new(0x00000600, 0x00000700),
+ new(0x00000000, 0x00000500),
+ };
+
+ InstEncoding[] raConstraints = new InstEncoding[]
+ {
+ new(0x0000F000, 0x0000F000),
+ };
+
+ InstEncoding[] sTConstraints = new InstEncoding[]
+ {
+ new(0x00100000, 0x00100000),
+ new(0x00000010, 0x00000010),
+ };
+
+ InstEncoding[] vdVnVmConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00010000, 0x00010000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] shimm2imm3Constraints = new InstEncoding[]
+ {
+ new(0x00200000, 0x002070C0),
+ };
+
+ InstEncoding[] rnimm8Constraints = new InstEncoding[]
+ {
+ new(0x000E0000, 0x000F00FF),
+ };
+
+ InstEncoding[] sizeQvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] qvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeVnVmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00010000, 0x00010000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] sizeVdOpvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ new(0x00010100, 0x00010100),
+ };
+
+ InstEncoding[] cmodeCmodeQvdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00000100),
+ new(0x00000C00, 0x00000C00),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qvdQvnQvmOpConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnQvmSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ };
+
+ InstEncoding[] qvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00000300),
+ };
+
+ InstEncoding[] vmConstraints = new InstEncoding[]
+ {
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] opvdOpvmConstraints = new InstEncoding[]
+ {
+ new(0x00001100, 0x00001100),
+ new(0x00000001, 0x00000101),
+ };
+
+ InstEncoding[] imm6Opimm6Imm6QvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00200000, 0x00300200),
+ new(0x00000000, 0x00200000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] qvdEbConstraints = new InstEncoding[]
+ {
+ new(0x00210000, 0x00210000),
+ new(0x00400020, 0x00400020),
+ };
+
+ InstEncoding[] imm4QvdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00070000),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qvdQvnQvmQimm4Constraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000800, 0x00000840),
+ };
+
+ InstEncoding[] qvdConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] vdVnConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ new(0x00010000, 0x00010000),
+ };
+
+ InstEncoding[] sizeConstraints2 = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ };
+
+ InstEncoding[] sizeIndexAlignIndexAlignConstraints = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ new(0x00000010, 0x00000030),
+ new(0x00000020, 0x00000030),
+ };
+
+ InstEncoding[] sizeSizeaConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000010, 0x000000D0),
+ };
+
+ InstEncoding[] alignConstraints = new InstEncoding[]
+ {
+ new(0x00000020, 0x00000020),
+ };
+
+ InstEncoding[] alignConstraints2 = new InstEncoding[]
+ {
+ new(0x00000030, 0x00000030),
+ };
+
+ InstEncoding[] sizeConstraints3 = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ };
+
+ InstEncoding[] alignSizeConstraints = new InstEncoding[]
+ {
+ new(0x00000030, 0x00000030),
+ new(0x000000C0, 0x000000C0),
+ };
+
+ InstEncoding[] sizeAConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000010, 0x00000010),
+ };
+
+ InstEncoding[] sizeAlignConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000C0),
+ new(0x00000020, 0x00000020),
+ };
+
+ InstEncoding[] sizeIndexAlignConstraints = new InstEncoding[]
+ {
+ new(0x00000C00, 0x00000C00),
+ new(0x00000030, 0x00000030),
+ };
+
+ InstEncoding[] sizeaConstraints = new InstEncoding[]
+ {
+ new(0x000000C0, 0x000000D0),
+ };
+
+ InstEncoding[] sizeSizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000000, 0x00300000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeQvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x10001000, 0x10001000),
+ new(0x10010000, 0x10010000),
+ };
+
+ InstEncoding[] imm3hImm3hImm3hImm3hImm3hVdConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00180000, 0x00380000),
+ new(0x00280000, 0x00380000),
+ new(0x00300000, 0x00380000),
+ new(0x00380000, 0x00380000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeVmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] opc1opc2Constraints = new InstEncoding[]
+ {
+ new(0x00000040, 0x00400060),
+ };
+
+ InstEncoding[] uopc1opc2Uopc1opc2Constraints = new InstEncoding[]
+ {
+ new(0x00800000, 0x00C00060),
+ new(0x00000040, 0x00400060),
+ };
+
+ InstEncoding[] sizeOpuOpsizeVdConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x10000200, 0x10000200),
+ new(0x00100200, 0x00300200),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeOpsizeOpsizeQvdQvnQvmConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x10100000, 0x10300000),
+ new(0x10200000, 0x10300000),
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] cmodeQvdConstraints = new InstEncoding[]
+ {
+ new(0x00000E00, 0x00000E00),
+ new(0x00001040, 0x00001040),
+ };
+
+ InstEncoding[] qConstraints = new InstEncoding[]
+ {
+ new(0x00000040, 0x00000040),
+ };
+
+ InstEncoding[] sizeQConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000040, 0x00000040),
+ };
+
+ InstEncoding[] sizeConstraints4 = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] qvdQvnQvmSizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00010040, 0x00010040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x00300000),
+ new(0x00300000, 0x00300000),
+ };
+
+ InstEncoding[] sizeSizeQvdQvnConstraints = new InstEncoding[]
+ {
+ new(0x00300000, 0x00300000),
+ new(0x00000000, 0x00300000),
+ new(0x10001000, 0x10001000),
+ new(0x10010000, 0x10010000),
+ };
+
+ InstEncoding[] opSizeVmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x000000C0),
+ new(0x000C0000, 0x000C0000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] qvdQvmQvnConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ new(0x00010040, 0x00010040),
+ };
+
+ InstEncoding[] imm6UopVmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00000000, 0x10000100),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] imm6lUopQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380080),
+ new(0x00000000, 0x10000100),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] qvdQvmSizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ new(0x00000000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ };
+
+ InstEncoding[] sizeSizeSizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00040000, 0x000C0000),
+ new(0x00080000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] sizeSizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00080000, 0x000C0000),
+ new(0x000C0000, 0x000C0000),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] imm6lQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380080),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ InstEncoding[] imm6VmConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] imm6VdImm6Imm6Imm6Constraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00380000),
+ new(0x00001000, 0x00001000),
+ new(0x00080000, 0x003F0000),
+ new(0x00100000, 0x003F0000),
+ new(0x00200000, 0x003F0000),
+ };
+
+ InstEncoding[] sizeVdConstraints2 = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] sizeQsizeQvdQvmConstraints = new InstEncoding[]
+ {
+ new(0x000C0000, 0x000C0000),
+ new(0x00080000, 0x000C0040),
+ new(0x00001040, 0x00001040),
+ new(0x00000041, 0x00000041),
+ };
+
+ List insts = new()
+ {
+ new(0xF1400000, 0xFBE08000, InstName.AdcI, T.AdcIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEB400000, 0xFFE08000, InstName.AdcR, T.AdcRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF1000000, 0xFBE08000, rnRdsConstraints, InstName.AddI, T.AddIT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2000000, 0xFBF08000, rnRnConstraints, InstName.AddI, T.AddIT4, IsaVersion.v80, InstFlags.Rd),
+ new(0xEB000000, 0xFFE08000, rnRdsConstraints, InstName.AddR, T.AddRT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xF10D0000, 0xFBEF8000, rdsConstraints, InstName.AddSpI, T.AddSpIT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xF20D0000, 0xFBFF8000, InstName.AddSpI, T.AddSpIT4, IsaVersion.v80, InstFlags.Rd),
+ new(0xEB0D0000, 0xFFEF8000, rdsConstraints, InstName.AddSpR, T.AddSpRT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2AF0000, 0xFBFF8000, InstName.Adr, T.AdrT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF20F0000, 0xFBFF8000, InstName.Adr, T.AdrT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xFFB00340, 0xFFBF0FD0, vdVmConstraints, InstName.Aesd, T.AesdT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xFFB00300, 0xFFBF0FD0, vdVmConstraints, InstName.Aese, T.AeseT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xFFB003C0, 0xFFBF0FD0, vdVmConstraints, InstName.Aesimc, T.AesimcT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xFFB00380, 0xFFBF0FD0, vdVmConstraints, InstName.Aesmc, T.AesmcT1, IsaVersion.v80, IsaFeature.FeatAes, InstFlags.None),
+ new(0xF0000000, 0xFBE08000, rdsConstraints, InstName.AndI, T.AndIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA000000, 0xFFE08000, rdsConstraints, InstName.AndR, T.AndRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF0008000, 0xF800D000, condCondCondConstraints, InstName.B, T.BT3, IsaVersion.v80, InstFlags.Cond),
+ new(0xF0009000, 0xF800D000, InstName.B, T.BT4, IsaVersion.v80, InstFlags.None),
+ new(0xF36F0000, 0xFFFF8020, InstName.Bfc, T.BfcT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3600000, 0xFFF08020, rnConstraints, InstName.Bfi, T.BfiT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF0200000, 0xFBE08000, InstName.BicI, T.BicIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA200000, 0xFFE08000, InstName.BicR, T.BicRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF000D000, 0xF800D000, InstName.BlI, T.BlIT1, IsaVersion.v80, InstFlags.None),
+ new(0xF000C000, 0xF800D000, hConstraints, InstName.BlI, T.BlIT2, IsaVersion.v80, InstFlags.None),
+ new(0xF3C08F00, 0xFFF0FFFF, InstName.Bxj, T.BxjT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8016, 0xFFFFFFFF, InstName.Clrbhb, T.ClrbhbT1, IsaVersion.v89, IsaFeature.FeatClrbhb, InstFlags.None),
+ new(0xF3BF8F2F, 0xFFFFFFFF, InstName.Clrex, T.ClrexT1, IsaVersion.v80, InstFlags.None),
+ new(0xFAB0F080, 0xFFF0F0F0, InstName.Clz, T.ClzT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF1100F00, 0xFBF08F00, InstName.CmnI, T.CmnIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEB100F00, 0xFFF08F00, InstName.CmnR, T.CmnRT2, IsaVersion.v80, InstFlags.None),
+ new(0xF1B00F00, 0xFBF08F00, InstName.CmpI, T.CmpIT2, IsaVersion.v80, InstFlags.None),
+ new(0xEBB00F00, 0xFFF08F00, InstName.CmpR, T.CmpRT3, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8000, 0xFFFFF800, imodmConstraints, InstName.Cps, T.CpsT2, IsaVersion.v80, InstFlags.None),
+ new(0xFAC0F080, 0xFFF0F0C0, InstName.Crc32, T.Crc32T1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.Rd),
+ new(0xFAD0F080, 0xFFF0F0C0, InstName.Crc32c, T.Crc32cT1, IsaVersion.v80, IsaFeature.FeatCrc32, InstFlags.Rd),
+ new(0xF3AF8014, 0xFFFFFFFF, InstName.Csdb, T.CsdbT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF80F0, 0xFFFFFFF0, InstName.Dbg, T.DbgT1, IsaVersion.v80, InstFlags.None),
+ new(0xF78F8001, 0xFFFFFFFF, InstName.Dcps1, T.Dcps1T1, IsaVersion.v80, InstFlags.None),
+ new(0xF78F8002, 0xFFFFFFFF, InstName.Dcps2, T.Dcps2T1, IsaVersion.v80, InstFlags.None),
+ new(0xF78F8003, 0xFFFFFFFF, InstName.Dcps3, T.Dcps3T1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BF8F50, 0xFFFFFFF0, InstName.Dmb, T.DmbT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BF8F40, 0xFFFFFFF0, optionConstraints, InstName.Dsb, T.DsbT1, IsaVersion.v80, InstFlags.None),
+ new(0xF0800000, 0xFBE08000, rdsConstraints, InstName.EorI, T.EorIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA800000, 0xFFE08000, rdsConstraints, InstName.EorR, T.EorRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3DE8F00, 0xFFFFFFFF, InstName.Eret, T.EretT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8010, 0xFFFFFFFF, InstName.Esb, T.EsbT1, IsaVersion.v82, IsaFeature.FeatRas, InstFlags.None),
+ new(0xEC100B01, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Fldmx, T.FldmxT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xEC000B01, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Fstmx, T.FstmxT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xF7E08000, 0xFFF0F000, InstName.Hvc, T.HvcT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BF8F60, 0xFFFFFFF0, InstName.Isb, T.IsbT1, IsaVersion.v80, InstFlags.None),
+ new(0xE8D00FAF, 0xFFF00FFF, InstName.Lda, T.LdaT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D00F8F, 0xFFF00FFF, InstName.Ldab, T.LdabT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D00FEF, 0xFFF00FFF, InstName.Ldaex, T.LdaexT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D00FCF, 0xFFF00FFF, InstName.Ldaexb, T.LdaexbT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D000FF, 0xFFF000FF, InstName.Ldaexd, T.LdaexdT1, IsaVersion.v80, InstFlags.RtRt2),
+ new(0xE8D00FDF, 0xFFF00FFF, InstName.Ldaexh, T.LdaexhT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D00F9F, 0xFFF00FFF, InstName.Ldah, T.LdahT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xEC105E00, 0xFE50FF00, rnPuwConstraints, InstName.LdcI, T.LdcIT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xEC1F5E00, 0xFE5FFF00, puwConstraints, InstName.LdcL, T.LdcLT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xE8900000, 0xFFD00000, InstName.Ldm, T.LdmT2, IsaVersion.v80, InstFlags.RlistWBack),
+ new(0xE9100000, 0xFFD00000, InstName.Ldmdb, T.LdmdbT1, IsaVersion.v80, InstFlags.RlistWBack),
+ new(0xF8100E00, 0xFFF00F00, rnConstraints, InstName.Ldrbt, T.LdrbtT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8900000, 0xFFF00000, rnRtConstraints, InstName.LdrbI, T.LdrbIT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8100800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrbI, T.LdrbIT3, IsaVersion.v80, InstFlags.RtWBack),
+ new(0xF81F0000, 0xFF7F0000, rtConstraints, InstName.LdrbL, T.LdrbLT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8100000, 0xFFF00FC0, rnRtConstraints, InstName.LdrbR, T.LdrbRT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8500000, 0xFE500000, rnPwConstraints, InstName.LdrdI, T.LdrdIT1, IsaVersion.v80, InstFlags.Rt2WBack),
+ new(0xE85F0000, 0xFE5F0000, pwConstraints, InstName.LdrdL, T.LdrdLT1, IsaVersion.v80, InstFlags.Rt2WBack),
+ new(0xE8500F00, 0xFFF00F00, InstName.Ldrex, T.LdrexT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D00F4F, 0xFFF00FFF, InstName.Ldrexb, T.LdrexbT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xE8D0007F, 0xFFF000FF, InstName.Ldrexd, T.LdrexdT1, IsaVersion.v80, InstFlags.RtRt2),
+ new(0xE8D00F5F, 0xFFF00FFF, InstName.Ldrexh, T.LdrexhT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8300E00, 0xFFF00F00, rnConstraints, InstName.Ldrht, T.LdrhtT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8B00000, 0xFFF00000, rnRtConstraints, InstName.LdrhI, T.LdrhIT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8300800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrhI, T.LdrhIT3, IsaVersion.v80, InstFlags.RtWBack),
+ new(0xF83F0000, 0xFF7F0000, rtConstraints, InstName.LdrhL, T.LdrhLT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8300000, 0xFFF00FC0, rnRtConstraints, InstName.LdrhR, T.LdrhRT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9100E00, 0xFFF00F00, rnConstraints, InstName.Ldrsbt, T.LdrsbtT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9900000, 0xFFF00000, rnRtConstraints, InstName.LdrsbI, T.LdrsbIT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9100800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrsbI, T.LdrsbIT2, IsaVersion.v80, InstFlags.RtWBack),
+ new(0xF91F0000, 0xFF7F0000, rtConstraints, InstName.LdrsbL, T.LdrsbLT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9100000, 0xFFF00FC0, rnRtConstraints, InstName.LdrsbR, T.LdrsbRT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9300E00, 0xFFF00F00, rnConstraints, InstName.Ldrsht, T.LdrshtT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9B00000, 0xFFF00000, rnRtConstraints, InstName.LdrshI, T.LdrshIT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9300800, 0xFFF00800, rnRtpuwPuwPwConstraints, InstName.LdrshI, T.LdrshIT2, IsaVersion.v80, InstFlags.RtWBack),
+ new(0xF93F0000, 0xFF7F0000, rtConstraints, InstName.LdrshL, T.LdrshLT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF9300000, 0xFFF00FC0, rnRtConstraints, InstName.LdrshR, T.LdrshRT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8500E00, 0xFFF00F00, rnConstraints, InstName.Ldrt, T.LdrtT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8D00000, 0xFFF00000, rnConstraints, InstName.LdrI, T.LdrIT3, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8500800, 0xFFF00800, rnPuwPwConstraints, InstName.LdrI, T.LdrIT4, IsaVersion.v80, InstFlags.RtWBack),
+ new(0xF85F0000, 0xFF7F0000, InstName.LdrL, T.LdrLT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xF8500000, 0xFFF00FC0, rnConstraints, InstName.LdrR, T.LdrRT2, IsaVersion.v80, InstFlags.Rt),
+ new(0xEE000E10, 0xFF100E10, InstName.Mcr, T.McrT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xEC400E00, 0xFFF00E00, InstName.Mcrr, T.McrrT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xFB000000, 0xFFF000F0, raConstraints, InstName.Mla, T.MlaT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB000010, 0xFFF000F0, InstName.Mls, T.MlsT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2C00000, 0xFBF08000, InstName.Movt, T.MovtT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF04F0000, 0xFBEF8000, InstName.MovI, T.MovIT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2400000, 0xFBF08000, InstName.MovI, T.MovIT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA4F0000, 0xFFEF8000, InstName.MovR, T.MovRT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA00F000, 0xFF80F0F0, InstName.MovRr, T.MovRrT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xEE100E10, 0xFF100E10, InstName.Mrc, T.MrcT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xEC500E00, 0xFFF00E00, InstName.Mrrc, T.MrrcT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xF3EF8000, 0xFFEFF0FF, InstName.Mrs, T.MrsT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3E08020, 0xFFE0F0EF, InstName.MrsBr, T.MrsBrT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3808020, 0xFFE0F0EF, InstName.MsrBr, T.MsrBrT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3808000, 0xFFE0F0FF, InstName.MsrR, T.MsrRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFB00F000, 0xFFF0F0F0, InstName.Mul, T.MulT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF06F0000, 0xFBEF8000, InstName.MvnI, T.MvnIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA6F0000, 0xFFEF8000, InstName.MvnR, T.MvnRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3AF8000, 0xFFFFFFFF, InstName.Nop, T.NopT2, IsaVersion.v80, InstFlags.None),
+ new(0xF0600000, 0xFBE08000, rnConstraints, InstName.OrnI, T.OrnIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA600000, 0xFFE08000, rnConstraints, InstName.OrnR, T.OrnRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF0400000, 0xFBE08000, rnConstraints, InstName.OrrI, T.OrrIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEA400000, 0xFFE08000, rnConstraints, InstName.OrrR, T.OrrRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xEAC00000, 0xFFF08010, sTConstraints, InstName.Pkh, T.PkhT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF890F000, 0xFFD0F000, rnConstraints, InstName.PldI, T.PldIT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xF810FC00, 0xFFD0FF00, rnConstraints, InstName.PldI, T.PldIT2, IsaVersion.v80, InstFlags.WBack),
+ new(0xF81FF000, 0xFF7FF000, InstName.PldL, T.PldLT1, IsaVersion.v80, InstFlags.None),
+ new(0xF810F000, 0xFFD0FFC0, rnConstraints, InstName.PldR, T.PldRT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xF990F000, 0xFFF0F000, rnConstraints, InstName.PliI, T.PliIT1, IsaVersion.v80, InstFlags.None),
+ new(0xF910FC00, 0xFFF0FF00, rnConstraints, InstName.PliI, T.PliIT2, IsaVersion.v80, InstFlags.None),
+ new(0xF91FF000, 0xFF7FF000, InstName.PliI, T.PliIT3, IsaVersion.v80, InstFlags.None),
+ new(0xF910F000, 0xFFF0FFC0, rnConstraints, InstName.PliR, T.PliRT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3BF8F44, 0xFFFFFFFF, InstName.Pssbb, T.PssbbT1, IsaVersion.v80, InstFlags.None),
+ new(0xFA80F080, 0xFFF0F0F0, InstName.Qadd, T.QaddT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F010, 0xFFF0F0F0, InstName.Qadd16, T.Qadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F010, 0xFFF0F0F0, InstName.Qadd8, T.Qadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F010, 0xFFF0F0F0, InstName.Qasx, T.QasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F090, 0xFFF0F0F0, InstName.Qdadd, T.QdaddT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F0B0, 0xFFF0F0F0, InstName.Qdsub, T.QdsubT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F010, 0xFFF0F0F0, InstName.Qsax, T.QsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F0A0, 0xFFF0F0F0, InstName.Qsub, T.QsubT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAD0F010, 0xFFF0F0F0, InstName.Qsub16, T.Qsub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F010, 0xFFF0F0F0, InstName.Qsub8, T.Qsub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F0A0, 0xFFF0F0F0, InstName.Rbit, T.RbitT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F080, 0xFFF0F0F0, InstName.Rev, T.RevT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F090, 0xFFF0F0F0, InstName.Rev16, T.Rev16T2, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F0B0, 0xFFF0F0F0, InstName.Revsh, T.RevshT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xE810C000, 0xFFD0FFFF, InstName.Rfe, T.RfeT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xE990C000, 0xFFD0FFFF, InstName.Rfe, T.RfeT2, IsaVersion.v80, InstFlags.WBack),
+ new(0xF1C00000, 0xFBE08000, InstName.RsbI, T.RsbIT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xEBC00000, 0xFFE08000, InstName.RsbR, T.RsbRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F000, 0xFFF0F0F0, InstName.Sadd16, T.Sadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F000, 0xFFF0F0F0, InstName.Sadd8, T.Sadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F000, 0xFFF0F0F0, InstName.Sasx, T.SasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3BF8F70, 0xFFFFFFFF, InstName.Sb, T.SbT1, IsaVersion.v85, IsaFeature.FeatSb, InstFlags.None),
+ new(0xF1600000, 0xFBE08000, InstName.SbcI, T.SbcIT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEB600000, 0xFFE08000, InstName.SbcR, T.SbcRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3400000, 0xFFF08020, InstName.Sbfx, T.SbfxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB90F0F0, 0xFFF0F0F0, InstName.Sdiv, T.SdivT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F080, 0xFFF0F0F0, InstName.Sel, T.SelT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3AF8004, 0xFFFFFFFF, InstName.Sev, T.SevT2, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8005, 0xFFFFFFFF, InstName.Sevl, T.SevlT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1c, T.Sha1cT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xFFB902C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1h, T.Sha1hT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xEF200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1m, T.Sha1mT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xEF100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1p, T.Sha1pT1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xEF300C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha1su0, T.Sha1su0T1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xFFBA0380, 0xFFBF0FD0, vdVmConstraints, InstName.Sha1su1, T.Sha1su1T1, IsaVersion.v80, IsaFeature.FeatSha1, InstFlags.None),
+ new(0xFF000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h, T.Sha256hT1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xFF100C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256h2, T.Sha256h2T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xFFBA03C0, 0xFFBF0FD0, vdVmConstraints, InstName.Sha256su0, T.Sha256su0T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xFF200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Sha256su1, T.Sha256su1T1, IsaVersion.v80, IsaFeature.FeatSha256, InstFlags.None),
+ new(0xFA90F020, 0xFFF0F0F0, InstName.Shadd16, T.Shadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F020, 0xFFF0F0F0, InstName.Shadd8, T.Shadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F020, 0xFFF0F0F0, InstName.Shasx, T.ShasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F020, 0xFFF0F0F0, InstName.Shsax, T.ShsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAD0F020, 0xFFF0F0F0, InstName.Shsub16, T.Shsub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F020, 0xFFF0F0F0, InstName.Shsub8, T.Shsub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF7F08000, 0xFFF0FFFF, InstName.Smc, T.SmcT1, IsaVersion.v80, InstFlags.None),
+ new(0xFB100000, 0xFFF000C0, raConstraints, InstName.Smlabb, T.SmlabbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB200000, 0xFFF000E0, raConstraints, InstName.Smlad, T.SmladT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFBC00000, 0xFFF000F0, InstName.Smlal, T.SmlalT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFBC00080, 0xFFF000C0, InstName.Smlalbb, T.SmlalbbT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFBC000C0, 0xFFF000E0, InstName.Smlald, T.SmlaldT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFB300000, 0xFFF000E0, raConstraints, InstName.Smlawb, T.SmlawbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB400000, 0xFFF000E0, raConstraints, InstName.Smlsd, T.SmlsdT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFBD000C0, 0xFFF000E0, InstName.Smlsld, T.SmlsldT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFB500000, 0xFFF000E0, raConstraints, InstName.Smmla, T.SmmlaT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB600000, 0xFFF000E0, InstName.Smmls, T.SmmlsT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB50F000, 0xFFF0F0E0, InstName.Smmul, T.SmmulT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB20F000, 0xFFF0F0E0, InstName.Smuad, T.SmuadT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB10F000, 0xFFF0F0C0, InstName.Smulbb, T.SmulbbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB800000, 0xFFF000F0, InstName.Smull, T.SmullT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFB30F000, 0xFFF0F0E0, InstName.Smulwb, T.SmulwbT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB40F000, 0xFFF0F0E0, InstName.Smusd, T.SmusdT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xE80DC000, 0xFFDFFFE0, InstName.Srs, T.SrsT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xE98DC000, 0xFFDFFFE0, InstName.Srs, T.SrsT2, IsaVersion.v80, InstFlags.WBack),
+ new(0xF3000000, 0xFFD08020, shimm2imm3Constraints, InstName.Ssat, T.SsatT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3200000, 0xFFF0F0F0, InstName.Ssat16, T.Ssat16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F000, 0xFFF0F0F0, InstName.Ssax, T.SsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3BF8F40, 0xFFFFFFFF, InstName.Ssbb, T.SsbbT1, IsaVersion.v80, InstFlags.None),
+ new(0xFAD0F000, 0xFFF0F0F0, InstName.Ssub16, T.Ssub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F000, 0xFFF0F0F0, InstName.Ssub8, T.Ssub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xEC005E00, 0xFE50FF00, puwConstraints, InstName.Stc, T.StcT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xE8C00FAF, 0xFFF00FFF, InstName.Stl, T.StlT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xE8C00F8F, 0xFFF00FFF, InstName.Stlb, T.StlbT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xE8C00FE0, 0xFFF00FF0, InstName.Stlex, T.StlexT1, IsaVersion.v80, InstFlags.RdRtReadRd16),
+ new(0xE8C00FC0, 0xFFF00FF0, InstName.Stlexb, T.StlexbT1, IsaVersion.v80, InstFlags.RdRtReadRd16),
+ new(0xE8C000F0, 0xFFF000F0, InstName.Stlexd, T.StlexdT1, IsaVersion.v80, InstFlags.RdRt2ReadRd16),
+ new(0xE8C00FD0, 0xFFF00FF0, InstName.Stlexh, T.StlexhT1, IsaVersion.v80, InstFlags.RdRtReadRd16),
+ new(0xE8C00F9F, 0xFFF00FFF, InstName.Stlh, T.StlhT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xE8800000, 0xFFD08000, InstName.Stm, T.StmT2, IsaVersion.v80, InstFlags.RlistReadWBack),
+ new(0xE9000000, 0xFFD08000, InstName.Stmdb, T.StmdbT1, IsaVersion.v80, InstFlags.RlistReadWBack),
+ new(0xF8000E00, 0xFFF00F00, rnConstraints, InstName.Strbt, T.StrbtT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8800000, 0xFFF00000, rnConstraints, InstName.StrbI, T.StrbIT2, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8000800, 0xFFF00800, rnPuwPwConstraints, InstName.StrbI, T.StrbIT3, IsaVersion.v80, InstFlags.RtReadWBack),
+ new(0xF8000000, 0xFFF00FC0, rnConstraints, InstName.StrbR, T.StrbRT2, IsaVersion.v80, InstFlags.RtRead),
+ new(0xE8400000, 0xFE500000, rnPwConstraints, InstName.StrdI, T.StrdIT1, IsaVersion.v80, InstFlags.Rt2ReadWBack),
+ new(0xE8400000, 0xFFF00000, InstName.Strex, T.StrexT1, IsaVersion.v80, InstFlags.RdRtRead),
+ new(0xE8C00F40, 0xFFF00FF0, InstName.Strexb, T.StrexbT1, IsaVersion.v80, InstFlags.RdRtReadRd16),
+ new(0xE8C00070, 0xFFF000F0, InstName.Strexd, T.StrexdT1, IsaVersion.v80, InstFlags.RdRt2ReadRd16),
+ new(0xE8C00F50, 0xFFF00FF0, InstName.Strexh, T.StrexhT1, IsaVersion.v80, InstFlags.RdRtReadRd16),
+ new(0xF8200E00, 0xFFF00F00, rnConstraints, InstName.Strht, T.StrhtT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8A00000, 0xFFF00000, rnConstraints, InstName.StrhI, T.StrhIT2, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8200800, 0xFFF00800, rnPuwPwConstraints, InstName.StrhI, T.StrhIT3, IsaVersion.v80, InstFlags.RtReadWBack),
+ new(0xF8200000, 0xFFF00FC0, rnConstraints, InstName.StrhR, T.StrhRT2, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8400E00, 0xFFF00F00, rnConstraints, InstName.Strt, T.StrtT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8C00000, 0xFFF00000, rnConstraints, InstName.StrI, T.StrIT3, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF8400800, 0xFFF00800, rnPuwPwConstraints, InstName.StrI, T.StrIT4, IsaVersion.v80, InstFlags.RtReadWBack),
+ new(0xF8400000, 0xFFF00FC0, rnConstraints, InstName.StrR, T.StrRT2, IsaVersion.v80, InstFlags.RtRead),
+ new(0xF1A00000, 0xFBE08000, rnRdsConstraints, InstName.SubI, T.SubIT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2A00000, 0xFBF08000, rnRnConstraints, InstName.SubI, T.SubIT4, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3D08F00, 0xFFF0FF00, rnimm8Constraints, InstName.SubI, T.SubIT5, IsaVersion.v80, InstFlags.None),
+ new(0xEBA00000, 0xFFE08000, rnRdsConstraints, InstName.SubR, T.SubRT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF1AD0000, 0xFBEF8000, rdsConstraints, InstName.SubSpI, T.SubSpIT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xF2AD0000, 0xFBFF8000, InstName.SubSpI, T.SubSpIT3, IsaVersion.v80, InstFlags.Rd),
+ new(0xEBAD0000, 0xFFEF8000, rdsConstraints, InstName.SubSpR, T.SubSpRT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA40F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtab, T.SxtabT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA20F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtab16, T.Sxtab16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA00F080, 0xFFF0F0C0, rnConstraints, InstName.Sxtah, T.SxtahT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA4FF080, 0xFFFFF0C0, InstName.Sxtb, T.SxtbT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA2FF080, 0xFFFFF0C0, InstName.Sxtb16, T.Sxtb16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA0FF080, 0xFFFFF0C0, InstName.Sxth, T.SxthT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xE8D0F000, 0xFFF0FFE0, InstName.Tbb, T.TbbT1, IsaVersion.v80, InstFlags.None),
+ new(0xF0900F00, 0xFBF08F00, InstName.TeqI, T.TeqIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEA900F00, 0xFFF08F00, InstName.TeqR, T.TeqRT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8012, 0xFFFFFFFF, InstName.Tsb, T.TsbT1, IsaVersion.v84, IsaFeature.FeatTrf, InstFlags.None),
+ new(0xF0100F00, 0xFBF08F00, InstName.TstI, T.TstIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEA100F00, 0xFFF08F00, InstName.TstR, T.TstRT2, IsaVersion.v80, InstFlags.None),
+ new(0xFA90F040, 0xFFF0F0F0, InstName.Uadd16, T.Uadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F040, 0xFFF0F0F0, InstName.Uadd8, T.Uadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F040, 0xFFF0F0F0, InstName.Uasx, T.UasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3C00000, 0xFFF08020, InstName.Ubfx, T.UbfxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF7F0A000, 0xFFF0F000, InstName.Udf, T.UdfT2, IsaVersion.v80, InstFlags.None),
+ new(0xFBB0F0F0, 0xFFF0F0F0, InstName.Udiv, T.UdivT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA90F060, 0xFFF0F0F0, InstName.Uhadd16, T.Uhadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F060, 0xFFF0F0F0, InstName.Uhadd8, T.Uhadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F060, 0xFFF0F0F0, InstName.Uhasx, T.UhasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F060, 0xFFF0F0F0, InstName.Uhsax, T.UhsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAD0F060, 0xFFF0F0F0, InstName.Uhsub16, T.Uhsub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F060, 0xFFF0F0F0, InstName.Uhsub8, T.Uhsub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFBE00060, 0xFFF000F0, InstName.Umaal, T.UmaalT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFBE00000, 0xFFF000F0, InstName.Umlal, T.UmlalT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFBA00000, 0xFFF000F0, InstName.Umull, T.UmullT1, IsaVersion.v80, InstFlags.RdLoRdHi),
+ new(0xFA90F050, 0xFFF0F0F0, InstName.Uqadd16, T.Uqadd16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA80F050, 0xFFF0F0F0, InstName.Uqadd8, T.Uqadd8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAA0F050, 0xFFF0F0F0, InstName.Uqasx, T.UqasxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F050, 0xFFF0F0F0, InstName.Uqsax, T.UqsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAD0F050, 0xFFF0F0F0, InstName.Uqsub16, T.Uqsub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F050, 0xFFF0F0F0, InstName.Uqsub8, T.Uqsub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB70F000, 0xFFF0F0F0, InstName.Usad8, T.Usad8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFB700000, 0xFFF000F0, raConstraints, InstName.Usada8, T.Usada8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3800000, 0xFFD08020, shimm2imm3Constraints, InstName.Usat, T.UsatT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xF3A00000, 0xFFF0F0F0, InstName.Usat16, T.Usat16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAE0F040, 0xFFF0F0F0, InstName.Usax, T.UsaxT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAD0F040, 0xFFF0F0F0, InstName.Usub16, T.Usub16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFAC0F040, 0xFFF0F0F0, InstName.Usub8, T.Usub8T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA50F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtab, T.UxtabT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA30F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtab16, T.Uxtab16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA10F080, 0xFFF0F0C0, rnConstraints, InstName.Uxtah, T.UxtahT1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA5FF080, 0xFFFFF0C0, InstName.Uxtb, T.UxtbT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA3FF080, 0xFFFFF0C0, InstName.Uxtb16, T.Uxtb16T1, IsaVersion.v80, InstFlags.Rd),
+ new(0xFA1FF080, 0xFFFFF0C0, InstName.Uxth, T.UxthT2, IsaVersion.v80, InstFlags.Rd),
+ new(0xEF000710, 0xEF800F10, sizeQvdQvnQvmConstraints, InstName.Vaba, T.VabaT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800500, 0xEF800F50, sizeVdConstraints, InstName.Vabal, T.VabalT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800700, 0xEF800F50, sizeVdConstraints, InstName.VabdlI, T.VabdlIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VabdF, T.VabdFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000700, 0xEF800F10, sizeQvdQvnQvmConstraints, InstName.VabdI, T.VabdIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB10300, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90700, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50700, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vabs, T.VabsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB00AC0, 0xFFBF0ED0, InstName.Vabs, T.VabsT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEB009C0, 0xFFBF0FD0, InstName.Vabs, T.VabsT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF000E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacge, T.VacgeT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF200E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF300E10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vacgt, T.VacgtT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vaddhn, T.VaddhnT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800000, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vaddl, T.VaddlT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800100, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vaddw, T.VaddwT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF100D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VaddF, T.VaddFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE300A00, 0xFFB00E50, InstName.VaddF, T.VaddFT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE300900, 0xFFB00F50, InstName.VaddF, T.VaddFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VaddI, T.VaddIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VandR, T.VandRT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800130, 0xEFB809B0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800930, 0xEFB80DB0, cmodeCmodeQvdConstraints, InstName.VbicI, T.VbicIT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF100110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VbicR, T.VbicRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF300110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbif, T.VbifT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF200110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbit, T.VbitT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100110, 0xFFB00F10, qvdQvnQvmOpConstraints, InstName.Vbsl, T.VbslT1, IsaVersion.v80, InstFlags.None),
+ new(0xFC900800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddT1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0xFC800800, 0xFEB00F10, qvdQvnQvmConstraints, InstName.Vcadd, T.VcaddT1, IsaVersion.v83, IsaFeature.FeatFcma | IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB10100, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90500, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50500, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VceqI, T.VceqIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.VceqR, T.VceqRT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VceqR, T.VceqRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB10080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90480, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50480, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgeI, T.VcgeIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000310, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VcgeR, T.VcgeRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRT2, IsaVersion.v80, InstFlags.None),
+ new(0xFF100E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgeR, T.VcgeRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB10000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90400, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50400, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcgtI, T.VcgtIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000300, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VcgtR, T.VcgtRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF200E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRT2, IsaVersion.v80, InstFlags.None),
+ new(0xFF300E00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VcgtR, T.VcgtRT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB10180, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90580, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50580, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcleI, T.VcleIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB00400, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vcls, T.VclsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB10200, 0xFFB30F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90600, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50600, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.VcltI, T.VcltIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB00480, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vclz, T.VclzT1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200800, 0xFE200F10, qvdQvnQvmConstraints, InstName.Vcmla, T.VcmlaT1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0xFE000800, 0xFF000F10, qvdQvnConstraints, InstName.VcmlaS, T.VcmlaST1, IsaVersion.v83, IsaFeature.FeatFcma, InstFlags.None),
+ new(0xEEB40A40, 0xFFBF0ED0, InstName.Vcmp, T.VcmpT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB40940, 0xFFBF0FD0, InstName.Vcmp, T.VcmpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB50A40, 0xFFBF0EFF, InstName.Vcmp, T.VcmpT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEB50940, 0xFFBF0FFF, InstName.Vcmp, T.VcmpT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB40AC0, 0xFFBF0ED0, InstName.Vcmpe, T.VcmpeT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB409C0, 0xFFBF0FD0, InstName.Vcmpe, T.VcmpeT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB50AC0, 0xFFBF0EFF, InstName.Vcmpe, T.VcmpeT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEB509C0, 0xFFBF0FFF, InstName.Vcmpe, T.VcmpeT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB00500, 0xFFBF0F90, qvdQvmConstraints, InstName.Vcnt, T.VcntT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFBB0000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB70000, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtaAsimd, T.VcvtaAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBC0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBC0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtaVfp, T.VcvtaVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB20A40, 0xFFBE0ED0, InstName.Vcvtb, T.VcvtbT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB30940, 0xFFBF0FD0, InstName.VcvtbBfs, T.VcvtbBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFFBB0300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB70300, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtmAsimd, T.VcvtmAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBF0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBF0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtmVfp, T.VcvtmVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBB0100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB70100, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtnAsimd, T.VcvtnAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBD0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBD0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtnVfp, T.VcvtnVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBB0200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB70200, 0xFFBF0F10, qvdQvmConstraints, InstName.VcvtpAsimd, T.VcvtpAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBE0A40, 0xFFBF0E50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBE0940, 0xFFBF0F50, sizeConstraints, InstName.VcvtpVfp, T.VcvtpVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEBC0A40, 0xFFBE0ED0, InstName.VcvtrIv, T.VcvtrIvT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEBC0940, 0xFFBE0FD0, InstName.VcvtrIv, T.VcvtrIvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB20AC0, 0xFFBE0ED0, InstName.Vcvtt, T.VcvttT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB309C0, 0xFFBF0FD0, InstName.VcvttBfs, T.VcvttBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFFB60640, 0xFFBF0FD0, vmConstraints, InstName.VcvtBfs, T.VcvtBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xEEB70AC0, 0xFFBF0ED0, InstName.VcvtDs, T.VcvtDsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60600, 0xFFBF0ED0, opvdOpvmConstraints, InstName.VcvtHs, T.VcvtHsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFBB0600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB70600, 0xFFBF0E10, qvdQvmConstraints, InstName.VcvtIs, T.VcvtIsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEBC0AC0, 0xFFBE0ED0, InstName.VcvtIv, T.VcvtIvT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEBC09C0, 0xFFBE0FD0, InstName.VcvtIv, T.VcvtIvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB80A40, 0xFFBF0E50, InstName.VcvtVi, T.VcvtViT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB80940, 0xFFBF0F50, InstName.VcvtVi, T.VcvtViT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800E10, 0xEF800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800C10, 0xEF800E90, imm6Opimm6Imm6QvdQvmConstraints, InstName.VcvtXs, T.VcvtXsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEBA0A40, 0xFFBA0E50, InstName.VcvtXv, T.VcvtXvT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEBA0940, 0xFFBA0F50, InstName.VcvtXv, T.VcvtXvT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE800A00, 0xFFB00E50, InstName.Vdiv, T.VdivT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE800900, 0xFFB00F50, InstName.Vdiv, T.VdivT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFC000D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vdot, T.VdotT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFE000D00, 0xFFB00F10, qvdQvnConstraints, InstName.VdotS, T.VdotST1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xEE800B10, 0xFF900F5F, qvdEbConstraints, InstName.VdupR, T.VdupRT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xFFB00C00, 0xFFB00F90, imm4QvdConstraints, InstName.VdupS, T.VdupST1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Veor, T.VeorT1, IsaVersion.v80, InstFlags.None),
+ new(0xEFB00000, 0xFFB00010, qvdQvnQvmQimm4Constraints, InstName.Vext, T.VextT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF100C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfma, T.VfmaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEA00A00, 0xFFB00E50, InstName.Vfma, T.VfmaT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEA00900, 0xFFB00F50, InstName.Vfma, T.VfmaT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFC200810, 0xFFB00F10, qvdConstraints, InstName.Vfmal, T.VfmalT1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFE000810, 0xFFB00F10, qvdConstraints, InstName.VfmalS, T.VfmalST1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFC300810, 0xFFB00F10, vdVnVmConstraints, InstName.VfmaBf, T.VfmaBfT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xFE300810, 0xFFB00F10, vdVnConstraints, InstName.VfmaBfs, T.VfmaBfsT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xEF200C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF300C10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vfms, T.VfmsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEA00A40, 0xFFB00E50, InstName.Vfms, T.VfmsT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEA00940, 0xFFB00F50, InstName.Vfms, T.VfmsT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFCA00810, 0xFFB00F10, qvdConstraints, InstName.Vfmsl, T.VfmslT1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xFE100810, 0xFFB00F10, qvdConstraints, InstName.VfmslS, T.VfmslST1, IsaVersion.v82, IsaFeature.FeatFhm, InstFlags.None),
+ new(0xEE900A40, 0xFFB00E50, InstName.Vfnma, T.VfnmaT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE900940, 0xFFB00F50, InstName.Vfnma, T.VfnmaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE900A00, 0xFFB00E50, InstName.Vfnms, T.VfnmsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE900900, 0xFFB00F50, InstName.Vfnms, T.VfnmsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000000, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vhadd, T.VhaddT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000200, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vhsub, T.VhsubT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB00AC0, 0xFFBF0FD0, InstName.Vins, T.VinsT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB90BC0, 0xFFBF0FD0, InstName.Vjcvt, T.VjcvtT1, IsaVersion.v83, IsaFeature.FeatJscvt, InstFlags.None),
+ new(0xF9A00000, 0xFFB00F10, sizeConstraints2, InstName.Vld11, T.Vld11T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00400, 0xFFB00F20, sizeConstraints2, InstName.Vld11, T.Vld11T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vld11, T.Vld11T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00C00, 0xFFB00F00, sizeSizeaConstraints, InstName.Vld1A, T.Vld1AT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200700, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200A00, 0xFFB00F00, alignConstraints2, InstName.Vld1M, T.Vld1MT2, IsaVersion.v80, InstFlags.None),
+ new(0xF9200600, 0xFFB00F00, alignConstraints, InstName.Vld1M, T.Vld1MT3, IsaVersion.v80, InstFlags.None),
+ new(0xF9200200, 0xFFB00F00, InstName.Vld1M, T.Vld1MT4, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00100, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00500, 0xFFB00F00, sizeConstraints2, InstName.Vld21, T.Vld21T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00900, 0xFFB00F20, sizeConstraints2, InstName.Vld21, T.Vld21T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00D00, 0xFFB00F00, sizeConstraints3, InstName.Vld2A, T.Vld2AT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200800, 0xFFB00E00, alignSizeConstraints, InstName.Vld2M, T.Vld2MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200300, 0xFFB00F00, sizeConstraints3, InstName.Vld2M, T.Vld2MT2, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00200, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00600, 0xFFB00F10, sizeConstraints2, InstName.Vld31, T.Vld31T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00A00, 0xFFB00F30, sizeConstraints2, InstName.Vld31, T.Vld31T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00E00, 0xFFB00F10, sizeAConstraints, InstName.Vld3A, T.Vld3AT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200400, 0xFFB00E00, sizeAlignConstraints, InstName.Vld3M, T.Vld3MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00300, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00700, 0xFFB00F00, sizeConstraints2, InstName.Vld41, T.Vld41T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vld41, T.Vld41T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9A00F00, 0xFFB00F00, sizeaConstraints, InstName.Vld4A, T.Vld4AT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9200000, 0xFFB00E00, sizeConstraints3, InstName.Vld4M, T.Vld4MT1, IsaVersion.v80, InstFlags.None),
+ new(0xEC100B00, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Vldm, T.VldmT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xEC100A00, 0xFE100F00, puwPwPuwPuwConstraints, InstName.Vldm, T.VldmT2, IsaVersion.v80, InstFlags.WBack),
+ new(0xED100A00, 0xFF300E00, rnConstraints, InstName.VldrI, T.VldrIT1, IsaVersion.v80, InstFlags.None),
+ new(0xED100900, 0xFF300F00, rnConstraints, InstName.VldrI, T.VldrIT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xED1F0A00, 0xFF3F0E00, InstName.VldrL, T.VldrLT1, IsaVersion.v80, InstFlags.None),
+ new(0xED1F0900, 0xFF3F0F00, InstName.VldrL, T.VldrLT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vmaxnm, T.VmaxnmT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFE800A00, 0xFFB00E50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmT2, IsaVersion.v80, InstFlags.None),
+ new(0xFE800900, 0xFFB00F50, sizeConstraints, InstName.Vmaxnm, T.VmaxnmT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF100F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmaxF, T.VmaxFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000600, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VmaxI, T.VmaxIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vminnm, T.VminnmT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFE800A40, 0xFFB00E50, sizeConstraints, InstName.Vminnm, T.VminnmT2, IsaVersion.v80, InstFlags.None),
+ new(0xFE800940, 0xFFB00F50, sizeConstraints, InstName.Vminnm, T.VminnmT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF200F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF300F00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VminF, T.VminFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000610, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.VminI, T.VminIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800800, 0xEF800F50, sizeVdConstraints, InstName.VmlalI, T.VmlalIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800240, 0xEF800F50, sizeSizeVdConstraints, InstName.VmlalS, T.VmlalST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlaF, T.VmlaFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE000A00, 0xFFB00E50, InstName.VmlaF, T.VmlaFT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE000900, 0xFFB00F50, InstName.VmlaF, T.VmlaFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlaI, T.VmlaIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEFA00040, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900040, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900140, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlaS, T.VmlaST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800A00, 0xEF800F50, sizeVdConstraints, InstName.VmlslI, T.VmlslIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800640, 0xEF800F50, sizeSizeVdConstraints, InstName.VmlslS, T.VmlslST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF300D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmlsF, T.VmlsFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE000A40, 0xFFB00E50, InstName.VmlsF, T.VmlsFT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE000940, 0xFFB00F50, InstName.VmlsF, T.VmlsFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF000900, 0xFF800F10, sizeQvdQvnQvmConstraints, InstName.VmlsI, T.VmlsIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEFA00440, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900440, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900540, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmlsS, T.VmlsST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFC000C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vmmla, T.VmmlaT1, IsaVersion.v86, IsaFeature.FeatAa32bf16, InstFlags.None),
+ new(0xEF800A10, 0xEF870FD0, imm3hImm3hImm3hImm3hImm3hVdConstraints, InstName.Vmovl, T.VmovlT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB20200, 0xFFB30FD0, sizeVmConstraints, InstName.Vmovn, T.VmovnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB00A40, 0xFFBF0FD0, InstName.Vmovx, T.VmovxT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEC400B10, 0xFFE00FD0, InstName.VmovD, T.VmovDT1, IsaVersion.v80, InstFlags.Rt2Read),
+ new(0xEE000910, 0xFFE00F7F, InstName.VmovH, T.VmovHT1, IsaVersion.v82, IsaFeature.FeatFp16, InstFlags.Rt),
+ new(0xEF800010, 0xEFB809B0, qvdConstraints, InstName.VmovI, T.VmovIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB00A00, 0xFFB00EF0, InstName.VmovI, T.VmovIT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEB00900, 0xFFB00FF0, InstName.VmovI, T.VmovIT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800810, 0xEFB80DB0, qvdConstraints, InstName.VmovI, T.VmovIT3, IsaVersion.v80, InstFlags.None),
+ new(0xEF800C10, 0xEFB80CB0, qvdConstraints, InstName.VmovI, T.VmovIT4, IsaVersion.v80, InstFlags.None),
+ new(0xEF800E30, 0xEFB80FB0, qvdConstraints, InstName.VmovI, T.VmovIT5, IsaVersion.v80, InstFlags.None),
+ new(0xEEB00A40, 0xFFBF0ED0, InstName.VmovR, T.VmovRT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE000B10, 0xFF900F1F, opc1opc2Constraints, InstName.VmovRs, T.VmovRsT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xEE000A10, 0xFFE00F7F, InstName.VmovS, T.VmovST1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xEE100B10, 0xFF100F1F, uopc1opc2Uopc1opc2Constraints, InstName.VmovSr, T.VmovSrT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xEC400A10, 0xFFE00FD0, InstName.VmovSs, T.VmovSsT1, IsaVersion.v80, InstFlags.Rt2Read),
+ new(0xEEF00A10, 0xFFF00FFF, InstName.Vmrs, T.VmrsT1, IsaVersion.v80, InstFlags.Rt),
+ new(0xEEE00A10, 0xFFF00FFF, InstName.Vmsr, T.VmsrT1, IsaVersion.v80, InstFlags.RtRead),
+ new(0xEF800C00, 0xEF800D50, sizeOpuOpsizeVdConstraints, InstName.VmullI, T.VmullIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800A40, 0xEF800F50, sizeSizeVdConstraints, InstName.VmullS, T.VmullST1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VmulF, T.VmulFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE200A00, 0xFFB00E50, InstName.VmulF, T.VmulFT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE200900, 0xFFB00F50, InstName.VmulF, T.VmulFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000910, 0xEF800F10, sizeOpsizeOpsizeQvdQvnQvmConstraints, InstName.VmulI, T.VmulIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEFA00840, 0xEFA00E50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900840, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, InstFlags.None),
+ new(0xEF900940, 0xEFB00F50, sizeQvdQvnConstraints, InstName.VmulS, T.VmulST1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800030, 0xEFB809B0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800830, 0xEFB80DB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF800C30, 0xEFB80EB0, cmodeQvdConstraints, InstName.VmvnI, T.VmvnIT3, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00580, 0xFFBF0F90, qvdQvmConstraints, InstName.VmvnR, T.VmvnRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB10380, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB90780, 0xFFBB0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB50780, 0xFFBF0F90, sizeQvdQvmConstraints, InstName.Vneg, T.VnegT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB10A40, 0xFFBF0ED0, InstName.Vneg, T.VnegT2, IsaVersion.v80, InstFlags.None),
+ new(0xEEB10940, 0xFFBF0FD0, InstName.Vneg, T.VnegT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE100A40, 0xFFB00E50, InstName.Vnmla, T.VnmlaT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE100940, 0xFFB00F50, InstName.Vnmla, T.VnmlaT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE100A00, 0xFFB00E50, InstName.Vnmls, T.VnmlsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE100900, 0xFFB00F50, InstName.Vnmls, T.VnmlsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE200A40, 0xFFB00E50, InstName.Vnmul, T.VnmulT1, IsaVersion.v80, InstFlags.None),
+ new(0xEE200940, 0xFFB00F50, InstName.Vnmul, T.VnmulT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF300110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VornR, T.VornRT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800110, 0xEFB809B0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800910, 0xEFB80DB0, cmodeCmodeQvdConstraints, InstName.VorrI, T.VorrIT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF200110, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VorrR, T.VorrRT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00600, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpadal, T.VpadalT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00200, 0xFFB30F10, sizeQvdQvmConstraints, InstName.Vpaddl, T.VpaddlT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100D00, 0xFFB00F10, qConstraints, InstName.VpaddF, T.VpaddFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000B10, 0xFF800F10, sizeQConstraints, InstName.VpaddI, T.VpaddIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF100F00, 0xFFB00F50, InstName.VpmaxF, T.VpmaxFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000A00, 0xEF800F50, sizeConstraints4, InstName.VpmaxI, T.VpmaxIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF200F00, 0xFFB00F50, InstName.VpminF, T.VpminFT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF300F00, 0xFFB00F50, InstName.VpminF, T.VpminFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000A10, 0xEF800F50, sizeConstraints4, InstName.VpminI, T.VpminIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00700, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqabs, T.VqabsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000010, 0xEF800F10, qvdQvnQvmConstraints, InstName.Vqadd, T.VqaddT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800900, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800340, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlal, T.VqdmlalT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF800B00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800740, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmlsl, T.VqdmlslT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqdmulh, T.VqdmulhT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800C40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqdmulh, T.VqdmulhT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF800D00, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800B40, 0xFF800F50, sizeSizeVdConstraints, InstName.Vqdmull, T.VqdmullT2, IsaVersion.v80, InstFlags.None),
+ new(0xFFB20200, 0xFFB30F10, opSizeVmConstraints, InstName.Vqmovn, T.VqmovnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00780, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vqneg, T.VqnegT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF000B10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlah, T.VqrdmlahT1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xEF800E40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlah, T.VqrdmlahT2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xFF000C10, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmlsh, T.VqrdmlshT1, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xEF800F40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmlsh, T.VqrdmlshT2, IsaVersion.v81, IsaFeature.FeatRdm, InstFlags.None),
+ new(0xFF000B00, 0xFF800F10, qvdQvnQvmSizeSizeConstraints, InstName.Vqrdmulh, T.VqrdmulhT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800D40, 0xEF800F50, sizeSizeQvdQvnConstraints, InstName.Vqrdmulh, T.VqrdmulhT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF000510, 0xEF800F10, qvdQvmQvnConstraints, InstName.Vqrshl, T.VqrshlT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800850, 0xEF800ED0, imm6UopVmConstraints, InstName.Vqrshrn, T.VqrshrnT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800610, 0xEF800E10, imm6lUopQvdQvmConstraints, InstName.VqshlI, T.VqshlIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000410, 0xEF800F10, qvdQvmQvnConstraints, InstName.VqshlR, T.VqshlRT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800810, 0xEF800ED0, imm6UopVmConstraints, InstName.Vqshrn, T.VqshrnT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000210, 0xEF800F10, qvdQvnQvmConstraints, InstName.Vqsub, T.VqsubT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF800400, 0xFF800F50, sizeVnVmConstraints, InstName.Vraddhn, T.VraddhnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB30400, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrecpe, T.VrecpeT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF100F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrecps, T.VrecpsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFB00100, 0xFFB30F90, sizeSizeSizeQvdQvmConstraints, InstName.Vrev16, T.Vrev16T1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00080, 0xFFB30F90, sizeSizeQvdQvmConstraints, InstName.Vrev32, T.Vrev32T1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00000, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vrev64, T.Vrev64T1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000100, 0xEF800F10, qvdQvnQvmSizeConstraints, InstName.Vrhadd, T.VrhaddT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFBA0500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60500, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintaAsimd, T.VrintaAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEB80A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB80940, 0xFFBF0FD0, sizeConstraints, InstName.VrintaVfp, T.VrintaVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBA0680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60680, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintmAsimd, T.VrintmAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBB0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBB0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintmVfp, T.VrintmVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBA0400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60400, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintnAsimd, T.VrintnAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEB90A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEB90940, 0xFFBF0FD0, sizeConstraints, InstName.VrintnVfp, T.VrintnVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBA0780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60780, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintpAsimd, T.VrintpAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFEBA0A40, 0xFFBF0ED0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFEBA0940, 0xFFBF0FD0, sizeConstraints, InstName.VrintpVfp, T.VrintpVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB60A40, 0xFFBF0ED0, InstName.VrintrVfp, T.VrintrVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB60940, 0xFFBF0FD0, InstName.VrintrVfp, T.VrintrVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBA0480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60480, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintxAsimd, T.VrintxAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB70A40, 0xFFBF0ED0, InstName.VrintxVfp, T.VrintxVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB70940, 0xFFBF0FD0, InstName.VrintxVfp, T.VrintxVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFFBA0580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB60580, 0xFFBF0F90, qvdQvmConstraints, InstName.VrintzAsimd, T.VrintzAsimdT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEEB60AC0, 0xFFBF0ED0, InstName.VrintzVfp, T.VrintzVfpT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB609C0, 0xFFBF0FD0, InstName.VrintzVfp, T.VrintzVfpT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF000500, 0xEF800F10, qvdQvmQvnConstraints, InstName.Vrshl, T.VrshlT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800210, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vrshr, T.VrshrT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800850, 0xFF800FD0, imm6VmConstraints, InstName.Vrshrn, T.VrshrnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB30480, 0xFFB30E90, qvdQvmSizeSizeConstraints, InstName.Vrsqrte, T.VrsqrteT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF200F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF300F10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vrsqrts, T.VrsqrtsT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800310, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vrsra, T.VrsraT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vrsubhn, T.VrsubhnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vsdot, T.VsdotT1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE200D00, 0xFFB00F10, qvdQvnConstraints, InstName.VsdotS, T.VsdotST1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE000A00, 0xFF800E50, sizeConstraints, InstName.Vsel, T.VselT1, IsaVersion.v80, InstFlags.None),
+ new(0xFE000900, 0xFF800F50, sizeConstraints, InstName.Vsel, T.VselT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800A10, 0xEF800FD0, imm6VdImm6Imm6Imm6Constraints, InstName.Vshll, T.VshllT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB20300, 0xFFB30FD0, sizeVdConstraints2, InstName.Vshll, T.VshllT2, IsaVersion.v80, InstFlags.None),
+ new(0xEF800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.VshlI, T.VshlIT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000400, 0xEF800F10, qvdQvmQvnConstraints, InstName.VshlR, T.VshlRT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800010, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vshr, T.VshrT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800810, 0xFF800FD0, imm6VmConstraints, InstName.Vshrn, T.VshrnT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF800510, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsli, T.VsliT1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vsmmla, T.VsmmlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xEEB10AC0, 0xFFBF0ED0, InstName.Vsqrt, T.VsqrtT1, IsaVersion.v80, InstFlags.None),
+ new(0xEEB109C0, 0xFFBF0FD0, InstName.Vsqrt, T.VsqrtT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800110, 0xEF800F10, imm6lQvdQvmConstraints, InstName.Vsra, T.VsraT1, IsaVersion.v80, InstFlags.None),
+ new(0xFF800410, 0xFF800F10, imm6lQvdQvmConstraints, InstName.Vsri, T.VsriT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800000, 0xFFB00F10, sizeConstraints2, InstName.Vst11, T.Vst11T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800400, 0xFFB00F20, sizeConstraints2, InstName.Vst11, T.Vst11T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9800800, 0xFFB00F40, sizeIndexAlignIndexAlignConstraints, InstName.Vst11, T.Vst11T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9000700, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9000A00, 0xFFB00F00, alignConstraints2, InstName.Vst1M, T.Vst1MT2, IsaVersion.v80, InstFlags.None),
+ new(0xF9000600, 0xFFB00F00, alignConstraints, InstName.Vst1M, T.Vst1MT3, IsaVersion.v80, InstFlags.None),
+ new(0xF9000200, 0xFFB00F00, InstName.Vst1M, T.Vst1MT4, IsaVersion.v80, InstFlags.None),
+ new(0xF9800100, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800500, 0xFFB00F00, sizeConstraints2, InstName.Vst21, T.Vst21T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9800900, 0xFFB00F20, sizeConstraints2, InstName.Vst21, T.Vst21T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9000800, 0xFFB00E00, alignSizeConstraints, InstName.Vst2M, T.Vst2MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9000300, 0xFFB00F00, sizeConstraints3, InstName.Vst2M, T.Vst2MT2, IsaVersion.v80, InstFlags.None),
+ new(0xF9800200, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800600, 0xFFB00F10, sizeConstraints2, InstName.Vst31, T.Vst31T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9800A00, 0xFFB00F30, sizeConstraints2, InstName.Vst31, T.Vst31T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9000400, 0xFFB00E00, sizeAlignConstraints, InstName.Vst3M, T.Vst3MT1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800300, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41T1, IsaVersion.v80, InstFlags.None),
+ new(0xF9800700, 0xFFB00F00, sizeConstraints2, InstName.Vst41, T.Vst41T2, IsaVersion.v80, InstFlags.None),
+ new(0xF9800B00, 0xFFB00F00, sizeIndexAlignConstraints, InstName.Vst41, T.Vst41T3, IsaVersion.v80, InstFlags.None),
+ new(0xF9000000, 0xFFB00E00, sizeConstraints3, InstName.Vst4M, T.Vst4MT1, IsaVersion.v80, InstFlags.None),
+ new(0xEC000B00, 0xFE100F01, puwPwPuwPuwConstraints, InstName.Vstm, T.VstmT1, IsaVersion.v80, InstFlags.WBack),
+ new(0xEC000A00, 0xFE100F00, puwPwPuwPuwConstraints, InstName.Vstm, T.VstmT2, IsaVersion.v80, InstFlags.WBack),
+ new(0xED000A00, 0xFF300E00, InstName.Vstr, T.VstrT1, IsaVersion.v80, InstFlags.None),
+ new(0xED000900, 0xFF300F00, InstName.Vstr, T.VstrT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEF800600, 0xFF800F50, sizeVnVmConstraints, InstName.Vsubhn, T.VsubhnT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800200, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vsubl, T.VsublT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF800300, 0xEF800F50, sizeVdOpvnConstraints, InstName.Vsubw, T.VsubwT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF200D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF300D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.VsubF, T.VsubFT1, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xEE300A40, 0xFFB00E50, InstName.VsubF, T.VsubFT2, IsaVersion.v80, InstFlags.None),
+ new(0xEE300940, 0xFFB00F50, InstName.VsubF, T.VsubFT2, IsaVersion.v80, IsaFeature.FeatFp16, InstFlags.None),
+ new(0xFF000800, 0xFF800F10, qvdQvnQvmConstraints, InstName.VsubI, T.VsubIT1, IsaVersion.v80, InstFlags.None),
+ new(0xFE800D10, 0xFFB00F10, qvdQvnConstraints, InstName.VsudotS, T.VsudotST1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFFB20000, 0xFFBF0F90, qvdQvmConstraints, InstName.Vswp, T.VswpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB00800, 0xFFB00C10, InstName.Vtbl, T.VtblT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB20080, 0xFFB30F90, sizeQvdQvmConstraints, InstName.Vtrn, T.VtrnT1, IsaVersion.v80, InstFlags.None),
+ new(0xEF000810, 0xFF800F10, qvdQvnQvmSizeConstraints, InstName.Vtst, T.VtstT1, IsaVersion.v80, InstFlags.None),
+ new(0xFC200D10, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vudot, T.VudotT1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFE200D10, 0xFFB00F10, qvdQvnConstraints, InstName.VudotS, T.VudotST1, IsaVersion.v82, IsaFeature.FeatDotprod, InstFlags.None),
+ new(0xFC200C50, 0xFFB00F50, vdVnVmConstraints, InstName.Vummla, T.VummlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFCA00D00, 0xFFB00F10, qvdQvnQvmConstraints, InstName.Vusdot, T.VusdotT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFE800D00, 0xFFB00F10, qvdQvnConstraints, InstName.VusdotS, T.VusdotST1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFCA00C40, 0xFFB00F50, vdVnVmConstraints, InstName.Vusmmla, T.VusmmlaT1, IsaVersion.v82, IsaFeature.FeatAa32i8mm, InstFlags.None),
+ new(0xFFB20100, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vuzp, T.VuzpT1, IsaVersion.v80, InstFlags.None),
+ new(0xFFB20180, 0xFFB30F90, sizeQsizeQvdQvmConstraints, InstName.Vzip, T.VzipT1, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8002, 0xFFFFFFFF, InstName.Wfe, T.WfeT2, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8003, 0xFFFFFFFF, InstName.Wfi, T.WfiT2, IsaVersion.v80, InstFlags.None),
+ new(0xF3AF8001, 0xFFFFFFFF, InstName.Yield, T.YieldT2, IsaVersion.v80, InstFlags.None),
+ };
+
+ _table = new(insts);
+ }
+
+ public static bool TryGetMeta(uint encoding, IsaVersion version, IsaFeature features, out InstMeta meta)
+ {
+ if (_table.TryFind(encoding, version, features, out InstInfoForTable info))
+ {
+ meta = info.Meta;
+
+ return true;
+ }
+
+ meta = new(InstName.Udf, T.UdfA1, IsaVersion.v80, IsaFeature.None, InstFlags.None);
+
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs
new file mode 100644
index 00000000..a213c222
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ class MultiBlock
+ {
+ public readonly List Blocks;
+ public readonly bool HasHostCall;
+ public readonly bool IsTruncated;
+
+ public MultiBlock(List blocks)
+ {
+ Blocks = blocks;
+
+ Block block = blocks[0];
+
+ HasHostCall = block.HasHostCall;
+
+ for (int index = 1; index < blocks.Count; index++)
+ {
+ block = blocks[index];
+
+ HasHostCall |= block.HasHostCall;
+ }
+
+ block = blocks[^1];
+
+ IsTruncated = block.IsTruncated;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs
new file mode 100644
index 00000000..8f48cd07
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct PendingBranch
+ {
+ public readonly BranchType BranchType;
+ public readonly uint TargetAddress;
+ public readonly uint NextAddress;
+ public readonly InstName Name;
+ public readonly int WriterPointer;
+
+ public PendingBranch(BranchType branchType, uint targetAddress, uint nextAddress, InstName name, int writerPointer)
+ {
+ BranchType = branchType;
+ TargetAddress = targetAddress;
+ NextAddress = nextAddress;
+ Name = name;
+ WriterPointer = writerPointer;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs
new file mode 100644
index 00000000..6c705722
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs
@@ -0,0 +1,169 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ class RegisterAllocator
+ {
+ public const int MaxTemps = 1;
+
+ private uint _gprMask;
+ private uint _fpSimdMask;
+
+ public int FixedContextRegister { get; }
+ public int FixedPageTableRegister { get; }
+
+ public uint UsedGprsMask { get; private set; }
+ public uint UsedFpSimdMask { get; private set; }
+
+ public RegisterAllocator()
+ {
+ _gprMask = ushort.MaxValue;
+ _fpSimdMask = ushort.MaxValue;
+
+ FixedContextRegister = AllocateTempRegisterWithPreferencing();
+ FixedPageTableRegister = AllocateTempRegisterWithPreferencing();
+ }
+
+ public void MarkGprAsUsed(int index)
+ {
+ UsedGprsMask |= 1u << index;
+ }
+
+ public void MarkFpSimdAsUsed(int index)
+ {
+ UsedFpSimdMask |= 1u << index;
+ }
+
+ public void MarkFpSimdRangeAsUsed(int index, int count)
+ {
+ UsedFpSimdMask |= (uint.MaxValue >> (32 - count)) << index;
+ }
+
+ public Operand RemapGprRegister(int index)
+ {
+ MarkGprAsUsed(index);
+
+ return new Operand(OperandKind.Register, OperandType.I32, (ulong)index);
+ }
+
+ public Operand RemapFpRegister(int index, bool isFP32)
+ {
+ MarkFpSimdAsUsed(index);
+
+ return new Operand(OperandKind.Register, isFP32 ? OperandType.FP32 : OperandType.FP64, (ulong)index);
+ }
+
+ public Operand RemapSimdRegister(int index)
+ {
+ MarkFpSimdAsUsed(index);
+
+ return new Operand(OperandKind.Register, OperandType.V128, (ulong)index);
+ }
+
+ public Operand RemapSimdRegister(int index, int count)
+ {
+ MarkFpSimdRangeAsUsed(index, count);
+
+ return new Operand(OperandKind.Register, OperandType.V128, (ulong)index);
+ }
+
+ public void EnsureTempGprRegisters(int count)
+ {
+ if (count != 0)
+ {
+ Span registers = stackalloc int[count];
+
+ for (int index = 0; index < count; index++)
+ {
+ registers[index] = AllocateTempGprRegister();
+ }
+
+ for (int index = 0; index < count; index++)
+ {
+ FreeTempGprRegister(registers[index]);
+ }
+ }
+ }
+
+ public int AllocateTempGprRegister()
+ {
+ int index = AllocateTempRegister(ref _gprMask, AbiConstants.ReservedRegsMask);
+
+ MarkGprAsUsed(index);
+
+ return index;
+ }
+
+ private int AllocateTempRegisterWithPreferencing()
+ {
+ int firstCalleeSaved = BitOperations.TrailingZeroCount(~_gprMask & AbiConstants.GprCalleeSavedRegsMask);
+ if (firstCalleeSaved < 32)
+ {
+ uint regMask = 1u << firstCalleeSaved;
+ if ((regMask & AbiConstants.ReservedRegsMask) == 0)
+ {
+ _gprMask |= regMask;
+
+ return firstCalleeSaved;
+ }
+ }
+
+ return AllocateTempRegister(ref _gprMask, AbiConstants.ReservedRegsMask);
+ }
+
+ public int AllocateTempFpSimdRegister()
+ {
+ int index = AllocateTempRegister(ref _fpSimdMask, 0);
+
+ MarkFpSimdAsUsed(index);
+
+ return index;
+ }
+
+ public ScopedRegister AllocateTempGprRegisterScoped()
+ {
+ return new(this, new(OperandKind.Register, OperandType.I32, (ulong)AllocateTempGprRegister()));
+ }
+
+ public ScopedRegister AllocateTempFpRegisterScoped(bool isFP32)
+ {
+ return new(this, new(OperandKind.Register, isFP32 ? OperandType.FP32 : OperandType.FP64, (ulong)AllocateTempFpSimdRegister()));
+ }
+
+ public ScopedRegister AllocateTempSimdRegisterScoped()
+ {
+ return new(this, new(OperandKind.Register, OperandType.V128, (ulong)AllocateTempFpSimdRegister()));
+ }
+
+ public void FreeTempGprRegister(int index)
+ {
+ FreeTempRegister(ref _gprMask, index);
+ }
+
+ public void FreeTempFpSimdRegister(int index)
+ {
+ FreeTempRegister(ref _fpSimdMask, index);
+ }
+
+ private static int AllocateTempRegister(ref uint mask, uint reservedMask)
+ {
+ int index = BitOperations.TrailingZeroCount(~(mask | reservedMask));
+ if (index == sizeof(uint) * 8)
+ {
+ throw new InvalidOperationException("No free registers.");
+ }
+
+ mask |= 1u << index;
+
+ return index;
+ }
+
+ private static void FreeTempRegister(ref uint mask, int index)
+ {
+ mask &= ~(1u << index);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs
new file mode 100644
index 00000000..8fbdeb73
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs
@@ -0,0 +1,109 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ static class RegisterUtils
+ {
+ public const int SpRegister = 13;
+ public const int LrRegister = 14;
+ public const int PcRegister = 15;
+
+ private const int RmBit = 0;
+ private const int RdRtBit = 12;
+ private const int RdHiRnBit = 16;
+
+ private const int RdRtT16Bit = 16;
+ private const int RdRtT16AltBit = 24;
+
+ private const int RdRt2RdHiT32Bit = 8;
+ private const int RdT32AltBit = 0;
+ private const int RtRdLoT32Bit = 12;
+
+ public static int ExtractRt(uint encoding)
+ {
+ return (int)(encoding >> RdRtBit) & 0xf;
+ }
+
+ public static int ExtractRt2(uint encoding)
+ {
+ return (int)GetRt2((uint)ExtractRt(encoding));
+ }
+
+ public static int ExtractRd(InstFlags flags, uint encoding)
+ {
+ return flags.HasFlag(InstFlags.Rd16) ? ExtractRn(encoding) : ExtractRd(encoding);
+ }
+
+ public static int ExtractRd(uint encoding)
+ {
+ return (int)(encoding >> RdRtBit) & 0xf;
+ }
+
+ public static int ExtractRdHi(uint encoding)
+ {
+ return (int)(encoding >> RdHiRnBit) & 0xf;
+ }
+
+ public static int ExtractRn(uint encoding)
+ {
+ return (int)(encoding >> RdHiRnBit) & 0xf;
+ }
+
+ public static int ExtractRm(uint encoding)
+ {
+ return (int)(encoding >> RmBit) & 0xf;
+ }
+
+ public static uint GetRt2(uint rt)
+ {
+ return Math.Min(rt + 1, PcRegister);
+ }
+
+ public static int ExtractRdn(InstFlags flags, uint encoding)
+ {
+ if (flags.HasFlag(InstFlags.Dn))
+ {
+ return ((int)(encoding >> RdRtT16Bit) & 7) | (int)((encoding >> 4) & 8);
+ }
+ else
+ {
+ return ExtractRdT16(flags, encoding);
+ }
+ }
+
+ public static int ExtractRdT16(InstFlags flags, uint encoding)
+ {
+ return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdRtT16AltBit) & 7 : (int)(encoding >> RdRtT16Bit) & 7;
+ }
+
+ public static int ExtractRtT16(InstFlags flags, uint encoding)
+ {
+ return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdRtT16AltBit) & 7 : (int)(encoding >> RdRtT16Bit) & 7;
+ }
+
+ public static int ExtractRdT32(InstFlags flags, uint encoding)
+ {
+ return flags.HasFlag(InstFlags.Rd16) ? (int)(encoding >> RdT32AltBit) & 0xf : (int)(encoding >> RdRt2RdHiT32Bit) & 0xf;
+ }
+
+ public static int ExtractRdLoT32(uint encoding)
+ {
+ return (int)(encoding >> RtRdLoT32Bit) & 0xf;
+ }
+
+ public static int ExtractRdHiT32(uint encoding)
+ {
+ return (int)(encoding >> RdRt2RdHiT32Bit) & 0xf;
+ }
+
+ public static int ExtractRtT32(uint encoding)
+ {
+ return (int)(encoding >> RtRdLoT32Bit) & 0xf;
+ }
+
+ public static int ExtractRt2T32(uint encoding)
+ {
+ return (int)(encoding >> RdRt2RdHiT32Bit) & 0xf;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs
new file mode 100644
index 00000000..18b1416e
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs
@@ -0,0 +1,39 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32
+{
+ readonly struct ScopedRegister : IDisposable
+ {
+ private readonly RegisterAllocator _registerAllocator;
+ private readonly Operand _operand;
+ private readonly bool _isAllocated;
+
+ public readonly Operand Operand => _operand;
+ public readonly bool IsAllocated => _isAllocated;
+
+ public ScopedRegister(RegisterAllocator registerAllocator, Operand operand, bool isAllocated = true)
+ {
+ _registerAllocator = registerAllocator;
+ _operand = operand;
+ _isAllocated = isAllocated;
+ }
+
+ public readonly void Dispose()
+ {
+ if (!_isAllocated)
+ {
+ return;
+ }
+
+ if (_operand.Type.IsInteger())
+ {
+ _registerAllocator.FreeTempGprRegister(_operand.AsInt32());
+ }
+ else
+ {
+ _registerAllocator.FreeTempFpSimdRegister(_operand.AsInt32());
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs
new file mode 100644
index 00000000..1e8a8915
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs
@@ -0,0 +1,789 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class Compiler
+ {
+ public const uint UsableGprsMask = 0x7fff;
+ public const uint UsableFpSimdMask = 0xffff;
+ public const uint UsablePStateMask = 0xf0000000;
+
+ private const int Encodable26BitsOffsetLimit = 0x2000000;
+
+ private readonly struct Context
+ {
+ public readonly CodeWriter Writer;
+ public readonly RegisterAllocator RegisterAllocator;
+ public readonly MemoryManagerType MemoryManagerType;
+ public readonly TailMerger TailMerger;
+ public readonly AddressTable FuncTable;
+ public readonly IntPtr DispatchStubPointer;
+
+ private readonly RegisterSaveRestore _registerSaveRestore;
+ private readonly IntPtr _pageTablePointer;
+
+ public Context(
+ CodeWriter writer,
+ RegisterAllocator registerAllocator,
+ MemoryManagerType mmType,
+ TailMerger tailMerger,
+ AddressTable funcTable,
+ RegisterSaveRestore registerSaveRestore,
+ IntPtr dispatchStubPointer,
+ IntPtr pageTablePointer)
+ {
+ Writer = writer;
+ RegisterAllocator = registerAllocator;
+ MemoryManagerType = mmType;
+ TailMerger = tailMerger;
+ FuncTable = funcTable;
+ _registerSaveRestore = registerSaveRestore;
+ DispatchStubPointer = dispatchStubPointer;
+ _pageTablePointer = pageTablePointer;
+ }
+
+ public readonly int GetReservedStackOffset()
+ {
+ return _registerSaveRestore.GetReservedStackOffset();
+ }
+
+ public readonly void WritePrologueAt(int instructionPointer)
+ {
+ CodeWriter writer = new();
+ Assembler asm = new(writer);
+
+ _registerSaveRestore.WritePrologue(ref asm);
+
+ // If needed, set up the fixed registers with the pointers we will use.
+ // First one is the context pointer (passed as first argument),
+ // second one is the page table or address space base, it is at a fixed memory location and considered constant.
+
+ if (RegisterAllocator.FixedContextRegister != 0)
+ {
+ asm.Mov(Register(RegisterAllocator.FixedContextRegister), Register(0));
+ }
+
+ asm.Mov(Register(RegisterAllocator.FixedPageTableRegister), (ulong)_pageTablePointer);
+
+ LoadFromContext(ref asm);
+
+ // Write the prologue at the specified position in our writer.
+ Writer.WriteInstructionsAt(instructionPointer, writer);
+ }
+
+ public readonly void WriteEpilogueWithoutContext()
+ {
+ Assembler asm = new(Writer);
+
+ _registerSaveRestore.WriteEpilogue(ref asm);
+ }
+
+ public void LoadFromContext()
+ {
+ Assembler asm = new(Writer);
+
+ LoadFromContext(ref asm);
+ }
+
+ private void LoadFromContext(ref Assembler asm)
+ {
+ LoadGprFromContext(ref asm, RegisterAllocator.UsedGprsMask & UsableGprsMask, NativeContextOffsets.GprBaseOffset);
+ LoadFpSimdFromContext(ref asm, RegisterAllocator.UsedFpSimdMask & UsableFpSimdMask, NativeContextOffsets.FpSimdBaseOffset);
+ LoadPStateFromContext(ref asm, UsablePStateMask, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public void StoreToContext()
+ {
+ Assembler asm = new(Writer);
+
+ StoreToContext(ref asm);
+ }
+
+ private void StoreToContext(ref Assembler asm)
+ {
+ StoreGprToContext(ref asm, RegisterAllocator.UsedGprsMask & UsableGprsMask, NativeContextOffsets.GprBaseOffset);
+ StoreFpSimdToContext(ref asm, RegisterAllocator.UsedFpSimdMask & UsableFpSimdMask, NativeContextOffsets.FpSimdBaseOffset);
+ StorePStateToContext(ref asm, UsablePStateMask, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ private void LoadGprFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 8;
+
+ if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ mask &= ~(3u << reg);
+
+ asm.LdpRiUn(Register(reg), Register(reg + 1), contextPtr, offset);
+ }
+ else
+ {
+ mask &= ~(1u << reg);
+
+ asm.LdrRiUn(Register(reg), contextPtr, offset);
+ }
+ }
+ }
+
+ private void LoadFpSimdFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 16;
+
+ mask &= ~(1u << reg);
+
+ asm.LdrRiUn(Register(reg, OperandType.V128), contextPtr, offset);
+ }
+ }
+
+ private void LoadPStateFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ if (mask == 0)
+ {
+ return;
+ }
+
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ asm.LdrRiUn(tempRegister.Operand, contextPtr, baseOffset);
+ asm.MsrNzcv(tempRegister.Operand);
+ }
+
+ private void StoreGprToContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 8;
+
+ if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ mask &= ~(3u << reg);
+
+ asm.StpRiUn(Register(reg), Register(reg + 1), contextPtr, offset);
+ }
+ else
+ {
+ mask &= ~(1u << reg);
+
+ asm.StrRiUn(Register(reg), contextPtr, offset);
+ }
+ }
+ }
+
+ private void StoreFpSimdToContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 16;
+
+ mask &= ~(1u << reg);
+
+ asm.StrRiUn(Register(reg, OperandType.V128), contextPtr, offset);
+ }
+ }
+
+ private void StorePStateToContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ if (mask == 0)
+ {
+ return;
+ }
+
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister2 = RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ asm.LdrRiUn(tempRegister.Operand, contextPtr, baseOffset);
+ asm.MrsNzcv(tempRegister2.Operand);
+ asm.And(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(0xfffffff));
+ asm.Orr(tempRegister.Operand, tempRegister.Operand, tempRegister2.Operand);
+ asm.StrRiUn(tempRegister.Operand, contextPtr, baseOffset);
+ }
+ }
+
+ public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, AddressTable funcTable, IntPtr dispatchStubPtr, bool isThumb)
+ {
+ MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address, isThumb);
+
+ Dictionary targets = new();
+
+ CodeWriter writer = new();
+ RegisterAllocator regAlloc = new();
+ Assembler asm = new(writer);
+ CodeGenContext cgContext = new(writer, asm, regAlloc, memoryManager.Type, isThumb);
+ ArmCondition lastCondition = ArmCondition.Al;
+ int lastConditionIp = 0;
+
+ // Required for load/store to context.
+ regAlloc.EnsureTempGprRegisters(2);
+
+ ulong pc = address;
+
+ for (int blockIndex = 0; blockIndex < multiBlock.Blocks.Count; blockIndex++)
+ {
+ Block block = multiBlock.Blocks[blockIndex];
+
+ Debug.Assert(block.Address == pc);
+
+ targets.Add(pc, writer.InstructionPointer);
+
+ for (int index = 0; index < block.Instructions.Count; index++)
+ {
+ InstInfo instInfo = block.Instructions[index];
+
+ if (index < block.Instructions.Count - 1)
+ {
+ cgContext.SetNextInstruction(block.Instructions[index + 1]);
+ }
+ else
+ {
+ cgContext.SetNextInstruction(default);
+ }
+
+ SetConditionalStart(cgContext, ref lastCondition, ref lastConditionIp, instInfo.Name, instInfo.Flags, instInfo.Encoding);
+
+ if (block.IsLoopEnd && index == block.Instructions.Count - 1)
+ {
+ // If this is a loop, the code might run for a long time uninterrupted.
+ // We insert a "sync point" here to ensure the loop can be interrupted if needed.
+
+ cgContext.AddPendingSyncPoint();
+
+ asm.B(0);
+ }
+
+ cgContext.SetPc((uint)pc);
+
+ instInfo.EmitFunc(cgContext, instInfo.Encoding);
+
+ if (cgContext.ConsumeNzcvModified())
+ {
+ ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp);
+ }
+
+ cgContext.UpdateItState();
+
+ pc += instInfo.Flags.HasFlag(InstFlags.Thumb16) ? 2UL : 4UL;
+ }
+
+ if (Decoder.WritesToPC(block.Instructions[^1].Encoding, block.Instructions[^1].Name, block.Instructions[^1].Flags, block.IsThumb))
+ {
+ // If the block ends with a PC register write, then we have a branch from register.
+
+ InstEmitCommon.SetThumbFlag(cgContext, regAlloc.RemapGprRegister(RegisterUtils.PcRegister));
+
+ cgContext.AddPendingIndirectBranch(block.Instructions[^1].Name, RegisterUtils.PcRegister);
+
+ asm.B(0);
+ }
+
+ ForceConditionalEnd(cgContext, ref lastCondition, lastConditionIp);
+ }
+
+ RegisterSaveRestore rsr = new(
+ regAlloc.UsedGprsMask & AbiConstants.GprCalleeSavedRegsMask,
+ regAlloc.UsedFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask,
+ OperandType.FP64,
+ multiBlock.HasHostCall,
+ multiBlock.HasHostCall ? CalculateStackSizeForCallSpill(regAlloc.UsedGprsMask, regAlloc.UsedFpSimdMask, UsablePStateMask) : 0);
+
+ TailMerger tailMerger = new();
+
+ Context context = new(writer, regAlloc, memoryManager.Type, tailMerger, funcTable, rsr, dispatchStubPtr, memoryManager.PageTablePointer);
+
+ InstInfo lastInstruction = multiBlock.Blocks[^1].Instructions[^1];
+ bool lastInstIsConditional = GetCondition(lastInstruction, isThumb) != ArmCondition.Al;
+
+ if (multiBlock.IsTruncated || lastInstIsConditional || lastInstruction.Name.IsCall() || IsConditionalBranch(lastInstruction))
+ {
+ WriteTailCallConstant(context, ref asm, (uint)pc);
+ }
+
+ IEnumerable pendingBranches = cgContext.GetPendingBranches();
+
+ foreach (PendingBranch pendingBranch in pendingBranches)
+ {
+ RewriteBranchInstructionWithTarget(context, pendingBranch, targets);
+ }
+
+ tailMerger.WriteReturn(writer, context.WriteEpilogueWithoutContext);
+
+ context.WritePrologueAt(0);
+
+ return new(writer.AsByteSpan(), (int)(pc - address));
+ }
+
+ private static int CalculateStackSizeForCallSpill(uint gprUseMask, uint fpSimdUseMask, uint pStateUseMask)
+ {
+ // Note that we don't discard callee saved FP/SIMD register because only the lower 64 bits is callee saved,
+ // so if the function is using the full register, that won't be enough.
+ // We could do better, but it's likely not worth it since this case happens very rarely in practice.
+
+ return BitOperations.PopCount(gprUseMask & ~AbiConstants.GprCalleeSavedRegsMask) * 8 +
+ BitOperations.PopCount(fpSimdUseMask) * 16 +
+ (pStateUseMask != 0 ? 8 : 0);
+ }
+
+ private static void SetConditionalStart(
+ CodeGenContext context,
+ ref ArmCondition condition,
+ ref int instructionPointer,
+ InstName name,
+ InstFlags flags,
+ uint encoding)
+ {
+ if (!context.ConsumeItCondition(out ArmCondition currentCond))
+ {
+ currentCond = GetCondition(name, flags, encoding, context.IsThumb);
+ }
+
+ if (currentCond != condition)
+ {
+ WriteConditionalEnd(context, condition, instructionPointer);
+
+ condition = currentCond;
+
+ if (currentCond != ArmCondition.Al)
+ {
+ instructionPointer = context.CodeWriter.InstructionPointer;
+ context.Arm64Assembler.B(currentCond.Invert(), 0);
+ }
+ }
+ }
+
+ private static bool IsConditionalBranch(in InstInfo instInfo)
+ {
+ return instInfo.Name == InstName.B && (ArmCondition)(instInfo.Encoding >> 28) != ArmCondition.Al;
+ }
+
+ private static ArmCondition GetCondition(in InstInfo instInfo, bool isThumb)
+ {
+ return GetCondition(instInfo.Name, instInfo.Flags, instInfo.Encoding, isThumb);
+ }
+
+ private static ArmCondition GetCondition(InstName name, InstFlags flags, uint encoding, bool isThumb)
+ {
+ // For branch, we handle conditional execution on the instruction itself.
+ bool hasCond = flags.HasFlag(InstFlags.Cond) && !CanHandleConditionalInstruction(name, encoding, isThumb);
+
+ return hasCond ? (ArmCondition)(encoding >> 28) : ArmCondition.Al;
+ }
+
+ private static bool CanHandleConditionalInstruction(InstName name, uint encoding, bool isThumb)
+ {
+ if (name == InstName.B)
+ {
+ return true;
+ }
+
+ // We can use CSEL for conditional MOV from registers, as long the instruction is not setting flags.
+ // We don't handle thumb right now because the condition comes from the IT block which would be more complicated to handle.
+ if (name == InstName.MovR && !isThumb && (encoding & (1u << 20)) == 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void ForceConditionalEnd(CodeGenContext context, ref ArmCondition condition, int instructionPointer)
+ {
+ WriteConditionalEnd(context, condition, instructionPointer);
+
+ condition = ArmCondition.Al;
+ }
+
+ private static void WriteConditionalEnd(CodeGenContext context, ArmCondition condition, int instructionPointer)
+ {
+ if (condition != ArmCondition.Al)
+ {
+ int delta = context.CodeWriter.InstructionPointer - instructionPointer;
+ uint branchInst = context.CodeWriter.ReadInstructionAt(instructionPointer) | (((uint)delta & 0x7ffff) << 5);
+ Debug.Assert((int)((branchInst & ~0x1fu) << 8) >> 11 == delta * 4);
+
+ context.CodeWriter.WriteInstructionAt(instructionPointer, branchInst);
+ }
+ }
+
+ private static void RewriteBranchInstructionWithTarget(in Context context, in PendingBranch pendingBranch, Dictionary targets)
+ {
+ switch (pendingBranch.BranchType)
+ {
+ case BranchType.Branch:
+ RewriteBranchInstructionWithTarget(context, pendingBranch.Name, pendingBranch.TargetAddress, pendingBranch.WriterPointer, targets);
+ break;
+ case BranchType.Call:
+ RewriteCallInstructionWithTarget(context, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer);
+ break;
+ case BranchType.IndirectBranch:
+ RewriteIndirectBranchInstructionWithTarget(context, pendingBranch.Name, pendingBranch.TargetAddress, pendingBranch.WriterPointer);
+ break;
+ case BranchType.TableBranchByte:
+ case BranchType.TableBranchHalfword:
+ RewriteTableBranchInstructionWithTarget(
+ context,
+ pendingBranch.BranchType == BranchType.TableBranchHalfword,
+ pendingBranch.TargetAddress,
+ pendingBranch.NextAddress,
+ pendingBranch.WriterPointer);
+ break;
+ case BranchType.IndirectCall:
+ RewriteIndirectCallInstructionWithTarget(context, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer);
+ break;
+ case BranchType.SyncPoint:
+ case BranchType.SoftwareInterrupt:
+ case BranchType.ReadCntpct:
+ RewriteHostCall(context, pendingBranch.Name, pendingBranch.BranchType, pendingBranch.TargetAddress, pendingBranch.NextAddress, pendingBranch.WriterPointer);
+ break;
+ default:
+ Debug.Fail($"Invalid branch type '{pendingBranch.BranchType}'");
+ break;
+ }
+ }
+
+ private static void RewriteBranchInstructionWithTarget(in Context context, InstName name, uint targetAddress, int branchIndex, Dictionary targets)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ int delta;
+ int targetIndex;
+ uint encoding = writer.ReadInstructionAt(branchIndex);
+
+ if (encoding == 0x14000000)
+ {
+ // Unconditional branch.
+
+ if (targets.TryGetValue(targetAddress, out targetIndex))
+ {
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -Encodable26BitsOffsetLimit && delta < Encodable26BitsOffsetLimit)
+ {
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff));
+
+ return;
+ }
+ }
+
+ targetIndex = writer.InstructionPointer;
+ delta = targetIndex - branchIndex;
+
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff));
+ WriteTailCallConstant(context, ref asm, targetAddress);
+ }
+ else
+ {
+ // Conditional branch.
+
+ uint branchMask = 0x7ffff;
+ int branchMax = (int)(branchMask + 1) / 2;
+
+ if (targets.TryGetValue(targetAddress, out targetIndex))
+ {
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -branchMax && delta < branchMax)
+ {
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)((delta & branchMask) << 5));
+
+ return;
+ }
+ }
+
+ targetIndex = writer.InstructionPointer;
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -branchMax && delta < branchMax)
+ {
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)((delta & branchMask) << 5));
+ WriteTailCallConstant(context, ref asm, targetAddress);
+ }
+ else
+ {
+ // If the branch target is too far away, we use a regular unconditional branch
+ // instruction instead which has a much higher range.
+ // We branch directly to the end of the function, where we put the conditional branch,
+ // and then branch back to the next instruction or return the branch target depending
+ // on the branch being taken or not.
+
+ uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff);
+ Debug.Assert((int)(branchInst << 6) >> 4 == delta * 4);
+
+ writer.WriteInstructionAt(branchIndex, branchInst);
+
+ int movedBranchIndex = writer.InstructionPointer;
+
+ writer.WriteInstruction(0u); // Placeholder
+ asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+
+ delta = writer.InstructionPointer - movedBranchIndex;
+
+ writer.WriteInstructionAt(movedBranchIndex, encoding | (uint)((delta & branchMask) << 5));
+ WriteTailCallConstant(context, ref asm, targetAddress);
+ }
+ }
+
+ Debug.Assert(name == InstName.B || name == InstName.Cbnz, $"Unknown branch instruction \"{name}\".");
+ }
+
+ private static void RewriteCallInstructionWithTarget(in Context context, uint targetAddress, uint nextAddress, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ WriteBranchToCurrentPosition(context, branchIndex);
+
+ asm.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.LrRegister), nextAddress);
+
+ context.StoreToContext();
+ InstEmitFlow.WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ nextAddress,
+ InstEmitCommon.Const((int)targetAddress));
+ context.LoadFromContext();
+
+ // Branch back to the next instruction (after the call).
+ asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+ }
+
+ private static void RewriteIndirectBranchInstructionWithTarget(in Context context, InstName name, uint targetRegister, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ WriteBranchToCurrentPosition(context, branchIndex);
+
+ using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ asm.And(target.Operand, context.RegisterAllocator.RemapGprRegister((int)targetRegister), InstEmitCommon.Const(~1));
+
+ context.StoreToContext();
+
+ if ((name == InstName.Bx && targetRegister == RegisterUtils.LrRegister) ||
+ name == InstName.Ldm ||
+ name == InstName.Ldmda ||
+ name == InstName.Ldmdb ||
+ name == InstName.Ldmib)
+ {
+ // Arm32 does not have a return instruction, instead returns are implemented
+ // either using BX LR (for leaf functions), or POP { ... PC }.
+
+ asm.Mov(Register(0), target.Operand);
+
+ context.TailMerger.AddUnconditionalReturn(writer, asm);
+ }
+ else
+ {
+ InstEmitFlow.WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ 0u,
+ target.Operand,
+ isTail: true);
+ }
+ }
+
+ private static void RewriteTableBranchInstructionWithTarget(in Context context, bool halfword, uint rn, uint rm, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ WriteBranchToCurrentPosition(context, branchIndex);
+
+ using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ asm.Add(
+ target.Operand,
+ context.RegisterAllocator.RemapGprRegister((int)rn),
+ context.RegisterAllocator.RemapGprRegister((int)rm),
+ ArmShiftType.Lsl,
+ halfword ? 1 : 0);
+
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, asm, target.Operand, target.Operand);
+
+ if (halfword)
+ {
+ asm.LdrhRiUn(target.Operand, target.Operand, 0);
+ }
+ else
+ {
+ asm.LdrbRiUn(target.Operand, target.Operand, 0);
+ }
+
+ asm.Add(target.Operand, context.RegisterAllocator.RemapGprRegister(RegisterUtils.PcRegister), target.Operand, ArmShiftType.Lsl, 1);
+
+ context.StoreToContext();
+
+ InstEmitFlow.WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ 0u,
+ target.Operand,
+ isTail: true);
+ }
+
+ private static void RewriteIndirectCallInstructionWithTarget(in Context context, uint targetRegister, uint nextAddress, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ WriteBranchToCurrentPosition(context, branchIndex);
+
+ using ScopedRegister target = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ asm.And(target.Operand, context.RegisterAllocator.RemapGprRegister((int)targetRegister), InstEmitCommon.Const(~1));
+ asm.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.LrRegister), nextAddress);
+
+ context.StoreToContext();
+ InstEmitFlow.WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ nextAddress & ~1u,
+ target.Operand);
+ context.LoadFromContext();
+
+ // Branch back to the next instruction (after the call).
+ asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+ }
+
+ private static void RewriteHostCall(in Context context, InstName name, BranchType type, uint imm, uint pc, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ uint encoding = writer.ReadInstructionAt(branchIndex);
+ int targetIndex = writer.InstructionPointer;
+ int delta = targetIndex - branchIndex;
+
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff));
+
+ switch (type)
+ {
+ case BranchType.SyncPoint:
+ InstEmitSystem.WriteSyncPoint(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset());
+ break;
+ case BranchType.SoftwareInterrupt:
+ context.StoreToContext();
+ switch (name)
+ {
+ case InstName.Bkpt:
+ InstEmitSystem.WriteBkpt(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm);
+ break;
+ case InstName.Svc:
+ InstEmitSystem.WriteSvc(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm);
+ break;
+ case InstName.Udf:
+ InstEmitSystem.WriteUdf(context.Writer, context.RegisterAllocator, context.TailMerger, context.GetReservedStackOffset(), pc, imm);
+ break;
+ }
+ context.LoadFromContext();
+ break;
+ case BranchType.ReadCntpct:
+ InstEmitSystem.WriteReadCntpct(context.Writer, context.RegisterAllocator, context.GetReservedStackOffset(), (int)imm, (int)pc);
+ break;
+ default:
+ Debug.Fail($"Invalid branch type '{type}'");
+ break;
+ }
+
+ // Branch back to the next instruction.
+ asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+ }
+
+ private static void WriteBranchToCurrentPosition(in Context context, int branchIndex)
+ {
+ CodeWriter writer = context.Writer;
+
+ int targetIndex = writer.InstructionPointer;
+
+ if (branchIndex + 1 == targetIndex)
+ {
+ writer.RemoveLastInstruction();
+ }
+ else
+ {
+ uint encoding = writer.ReadInstructionAt(branchIndex);
+ int delta = targetIndex - branchIndex;
+
+ writer.WriteInstructionAt(branchIndex, encoding | (uint)(delta & 0x3ffffff));
+ }
+ }
+
+ private static void WriteTailCallConstant(in Context context, ref Assembler asm, uint address)
+ {
+ context.StoreToContext();
+ InstEmitFlow.WriteCallWithGuestAddress(
+ context.Writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ 0u,
+ InstEmitCommon.Const((int)address),
+ isTail: true);
+ }
+
+ private static Operand Register(int register, OperandType type = OperandType.I64)
+ {
+ return new Operand(register, RegisterType.Integer, type);
+ }
+
+ public static void PrintStats()
+ {
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs
new file mode 100644
index 00000000..48891932
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs
@@ -0,0 +1,8502 @@
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ class InstEmit : IInstEmit
+ {
+ public static void AdcIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.AdcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void AdcIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AdcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void AdcRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AdcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void AdcRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.AdcR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void AdcRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AdcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void AdcRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AdcRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void AddIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void AddIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm3b22w3Rnb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, inst.Rn, inst.Imm3, !context.InITBlock);
+ }
+
+ public static void AddIT2(CodeGenContext context, uint encoding)
+ {
+ InstRdnb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rdn, inst.Rdn, inst.Imm8, !context.InITBlock);
+ }
+
+ public static void AddIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void AddIT4(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false);
+ }
+
+ public static void AddRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void AddRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void AddRT2(CodeGenContext context, uint encoding)
+ {
+ InstDnb23w1Rmb19w4Rdnb16w3 inst = new(encoding);
+
+ uint rdn = (inst.Dn << 3) | inst.Rdn;
+
+ InstEmitAlu.AddR(context, rdn, rdn, inst.Rm, 0, 0, false);
+ }
+
+ public static void AddRT3(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void AddRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AddRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void AddSpIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void AddSpIT1(CodeGenContext context, uint encoding)
+ {
+ InstRdb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, inst.Imm8 << 2, false);
+ }
+
+ public static void AddSpIT2(CodeGenContext context, uint encoding)
+ {
+ InstImm7b16w7 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Imm7 << 2, false);
+ }
+
+ public static void AddSpIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void AddSpIT4(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AddI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false);
+ }
+
+ public static void AddSpRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void AddSpRT1(CodeGenContext context, uint encoding)
+ {
+ InstDmb23w1Rdmb16w3 inst = new(encoding);
+
+ uint rdm = inst.Rdm | (inst.Dm << 3);
+
+ InstEmitAlu.AddR(context, rdm, RegisterUtils.SpRegister, rdm, 0, 0, false);
+ }
+
+ public static void AddSpRT2(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w4 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Rm, 0, 0, false);
+ }
+
+ public static void AddSpRT3(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AddR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void AdrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.Adr(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), true);
+ }
+
+ public static void AdrA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.Adr(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), false);
+ }
+
+ public static void AdrT1(CodeGenContext context, uint encoding)
+ {
+ InstRdb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitAlu.Adr(context, inst.Rd, inst.Imm8 << 2, true);
+ }
+
+ public static void AdrT2(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.Adr(context, inst.Rd, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false);
+ }
+
+ public static void AdrT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.Adr(context, inst.Rd, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), true);
+ }
+
+ public static void AesdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AesdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AeseA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aese(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AeseT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aese(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AesimcA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesimc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AesimcT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesimc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AesmcA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesmc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AesmcT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCrypto.Aesmc(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void AndIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.AndI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void AndIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.AndI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void AndRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AndR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void AndRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.AndR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void AndRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AndR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void AndRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.AndRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void BA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm24b0w24 inst = new(encoding);
+
+ InstEmitFlow.B(context, ImmUtils.ExtractSImm24Times4(inst.Imm24), (ArmCondition)inst.Cond);
+ }
+
+ public static void BT1(CodeGenContext context, uint encoding)
+ {
+ InstCondb24w4Imm8b16w8 inst = new(encoding);
+
+ InstEmitFlow.B(context, ImmUtils.ExtractT16SImm8Times2(inst.Imm8), (ArmCondition)inst.Cond);
+ }
+
+ public static void BT2(CodeGenContext context, uint encoding)
+ {
+ InstImm11b16w11 inst = new(encoding);
+
+ InstEmitFlow.B(context, ImmUtils.ExtractT16SImm11Times2(inst.Imm11), ArmCondition.Al);
+ }
+
+ public static void BT3(CodeGenContext context, uint encoding)
+ {
+ InstSb26w1Condb22w4Imm6b16w6J1b13w1J2b11w1Imm11b0w11 inst = new(encoding);
+
+ InstEmitFlow.B(context, ImmUtils.CombineSImm20Times2(inst.Imm11, inst.Imm6, inst.J1, inst.J2, inst.S), (ArmCondition)inst.Cond);
+ }
+
+ public static void BT4(CodeGenContext context, uint encoding)
+ {
+ InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding);
+
+ InstEmitFlow.B(context, ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S), ArmCondition.Al);
+ }
+
+ public static void BfcA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5 inst = new(encoding);
+
+ InstEmitBit.Bfc(context, inst.Rd, inst.Lsb, inst.Msb);
+ }
+
+ public static void BfcT1(CodeGenContext context, uint encoding)
+ {
+ InstImm3b12w3Rdb8w4Imm2b6w2Msbb0w5 inst = new(encoding);
+
+ InstEmitBit.Bfc(context, inst.Rd, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Msb);
+ }
+
+ public static void BfiA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Msbb16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding);
+
+ InstEmitBit.Bfi(context, inst.Rd, inst.Rn, inst.Lsb, inst.Msb);
+ }
+
+ public static void BfiT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Msbb0w5 inst = new(encoding);
+
+ InstEmitBit.Bfi(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Msb);
+ }
+
+ public static void BicIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.BicI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void BicIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.BicI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void BicRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.BicR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void BicRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.BicR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void BicRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.BicR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void BicRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.BicRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void BkptA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm12b8w12Imm4b0w4 inst = new(encoding);
+
+ InstEmitSystem.Bkpt(context, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4));
+ }
+
+ public static void BkptT1(CodeGenContext context, uint encoding)
+ {
+ InstImm8b16w8 inst = new(encoding);
+
+ InstEmitSystem.Bkpt(context, inst.Imm8);
+ }
+
+ public static void BlxRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rmb0w4 inst = new(encoding);
+
+ InstEmitFlow.Blx(context, inst.Rm, false);
+ }
+
+ public static void BlxRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w4 inst = new(encoding);
+
+ InstEmitFlow.Blx(context, inst.Rm, true);
+ }
+
+ public static void BlIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm24b0w24 inst = new(encoding);
+
+ InstEmitFlow.Bl(context, ImmUtils.ExtractSImm24Times4(inst.Imm24), false, false);
+ }
+
+ public static void BlIA2(CodeGenContext context, uint encoding)
+ {
+ InstHb24w1Imm24b0w24 inst = new(encoding);
+
+ InstEmitFlow.Bl(context, ImmUtils.ExtractSImm24Times4(inst.Imm24) | ((int)inst.H << 1), false, true);
+ }
+
+ public static void BlIT1(CodeGenContext context, uint encoding)
+ {
+ InstSb26w1Imm10b16w10J1b13w1J2b11w1Imm11b0w11 inst = new(encoding);
+
+ InstEmitFlow.Bl(context, ImmUtils.CombineSImm24Times2(inst.Imm11, inst.Imm10, inst.J1, inst.J2, inst.S), true, true);
+ }
+
+ public static void BlIT2(CodeGenContext context, uint encoding)
+ {
+ InstSb26w1Imm10hb16w10J1b13w1J2b11w1Imm10lb1w10Hb0w1 inst = new(encoding);
+
+ InstEmitFlow.Bl(context, ImmUtils.CombineSImm24Times4(inst.Imm10l, inst.Imm10h, inst.J1, inst.J2, inst.S), true, false);
+ }
+
+ public static void BxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rmb0w4 inst = new(encoding);
+
+ InstEmitFlow.Bx(context, inst.Rm);
+ }
+
+ public static void BxT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w4 inst = new(encoding);
+
+ InstEmitFlow.Bx(context, inst.Rm);
+ }
+
+ public static void BxjA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rmb0w4 inst = new(encoding);
+
+ InstEmitFlow.Bx(context, inst.Rm);
+ }
+
+ public static void BxjT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb16w4 inst = new(encoding);
+
+ InstEmitFlow.Bx(context, inst.Rm);
+ }
+
+ public static void CbnzT1(CodeGenContext context, uint encoding)
+ {
+ InstOpb27w1Ib25w1Imm5b19w5Rnb16w3 inst = new(encoding);
+
+ InstEmitFlow.Cbnz(context, inst.Rn, (int)((inst.Imm5 << 1) | (inst.I << 6)), inst.Op != 0);
+ }
+
+ public static void ClrbhbA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstCondb28w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void ClrbhbT1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void ClrexA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Clrex();
+ }
+
+ public static void ClrexT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Clrex();
+ }
+
+ public static void ClzA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Clz(context, inst.Rd, inst.Rm);
+ }
+
+ public static void ClzT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Clz(context, inst.Rd, inst.Rm);
+ }
+
+ public static void CmnIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.CmnI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12));
+ }
+
+ public static void CmnIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.CmnI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I));
+ }
+
+ public static void CmnRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5);
+ }
+
+ public static void CmnRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rnb16w3 inst = new(encoding);
+
+ InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, 0, 0);
+ }
+
+ public static void CmnRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmnR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void CmnRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmnRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs);
+ }
+
+ public static void CmpIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.CmpI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12));
+ }
+
+ public static void CmpIT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitAlu.CmpI(context, inst.Rn, inst.Imm8);
+ }
+
+ public static void CmpIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.CmpI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I));
+ }
+
+ public static void CmpRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5);
+ }
+
+ public static void CmpRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rnb16w3 inst = new(encoding);
+
+ InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, 0, 0);
+ }
+
+ public static void CmpRT2(CodeGenContext context, uint encoding)
+ {
+ InstNb23w1Rmb19w4Rnb16w3 inst = new(encoding);
+
+ InstEmitAlu.CmpR(context, inst.Rn | (inst.N << 3), inst.Rm, 0, 0);
+ }
+
+ public static void CmpRT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmpR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void CmpRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.CmpRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs);
+ }
+
+ public static void CpsA1(CodeGenContext context, uint encoding)
+ {
+ InstImodb18w2Mb17w1Ab8w1Ib7w1Fb6w1Modeb0w5 inst = new(encoding);
+
+ InstEmitSystem.Cps(context, inst.Imod, inst.M, inst.A, inst.I, inst.F, inst.Mode);
+ }
+
+ public static void CpsT1(CodeGenContext context, uint encoding)
+ {
+ InstImb20w1Ab18w1Ib17w1Fb16w1 inst = new(encoding);
+
+ InstEmitSystem.Cps(context, inst.Im, 0, inst.A, inst.I, inst.F, 0);
+ }
+
+ public static void CpsT2(CodeGenContext context, uint encoding)
+ {
+ InstImodb9w2Mb8w1Ab7w1Ib6w1Fb5w1Modeb0w5 inst = new(encoding);
+
+ InstEmitSystem.Cps(context, inst.Imod, inst.M, inst.A, inst.I, inst.F, inst.Mode);
+ }
+
+ public static void Crc32A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitCrc32.Crc32(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz);
+ }
+
+ public static void Crc32T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Szb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitCrc32.Crc32(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz);
+ }
+
+ public static void Crc32cA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Szb21w2Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitCrc32.Crc32c(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz);
+ }
+
+ public static void Crc32cT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Szb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitCrc32.Crc32c(context, inst.Rd, inst.Rn, inst.Rm, inst.Sz);
+ }
+
+ public static void CsdbA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Csdb();
+ }
+
+ public static void CsdbT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Csdb();
+ }
+
+ public static void DbgA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Optionb0w4 inst = new(encoding);
+
+ InstEmitSystem.Dbg(context, inst.Option);
+ }
+
+ public static void DbgT1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ InstEmitSystem.Dbg(context, inst.Option);
+ }
+
+ public static void Dcps1T1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void Dcps2T1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void Dcps3T1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void DmbA1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Dmb(inst.Option);
+ }
+
+ public static void DmbT1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Dmb(inst.Option);
+ }
+
+ public static void DsbA1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Dsb(inst.Option);
+ }
+
+ public static void DsbT1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Dsb(inst.Option);
+ }
+
+ public static void EorIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.EorI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void EorIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.EorI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void EorRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.EorR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void EorRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.EorR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void EorRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.EorR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void EorRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.EorRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void EretA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void EretT1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void EsbA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Esb();
+ }
+
+ public static void EsbT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Esb();
+ }
+
+ public static void FldmxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void FldmxT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void FstmxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void FstmxT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void HltA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm12b8w12Imm4b0w4 inst = new(encoding);
+
+ InstEmitSystem.Hlt(context, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4));
+ }
+
+ public static void HltT1(CodeGenContext context, uint encoding)
+ {
+ InstImm6b16w6 inst = new(encoding);
+
+ InstEmitSystem.Hlt(context, inst.Imm6);
+ }
+
+ public static void HvcA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void HvcT1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void IsbA1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Isb(inst.Option);
+ }
+
+ public static void IsbT1(CodeGenContext context, uint encoding)
+ {
+ InstOptionb0w4 inst = new(encoding);
+
+ context.Arm64Assembler.Isb(inst.Option);
+ }
+
+ public static void ItT1(CodeGenContext context, uint encoding)
+ {
+ InstFirstcondb20w4Maskb16w4 inst = new(encoding);
+
+ InstEmitFlow.It(context, inst.Firstcond, inst.Mask);
+ }
+
+ public static void LdaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Lda(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Lda(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdabA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldab(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdabT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldab(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaex(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaex(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexd(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn);
+ }
+
+ public static void LdaexdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rt2b8w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexd(context, inst.Rt, inst.Rt2, inst.Rn);
+ }
+
+ public static void LdaexhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdaexhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldaexh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdahA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldah(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdahT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldah(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdcIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdcI(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdcIT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdcI(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdcLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdcL(context, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdcLT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdcL(context, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdmA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Ldm(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void LdmT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb24w3RegisterListb16w8 inst = new(encoding);
+
+ InstEmitMemory.Ldm(context, inst.Rn, inst.RegisterList, false);
+ }
+
+ public static void LdmT2(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14 inst = new(encoding);
+
+ InstEmitMemory.Ldm(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M, inst.P), inst.W != 0);
+ }
+
+ public static void LdmdaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Ldmda(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void LdmdbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Ldmdb(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void LdmdbT1(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Pb15w1Mb14w1RegisterListb0w14 inst = new(encoding);
+
+ InstEmitMemory.Ldmdb(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M, inst.P), inst.W != 0);
+ }
+
+ public static void LdmibA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Ldmib(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void LdmEA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void LdmUA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void LdrbtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrbtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrbtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrbtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void LdrbIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrbIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm5, true, true, false);
+ }
+
+ public static void LdrbIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void LdrbIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrbLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrbL(context, inst.Rt, inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrbLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrbL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false);
+ }
+
+ public static void LdrbRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrbRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void LdrbRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void LdrdIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrdI(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrdIT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrdI(context, inst.Rt, inst.Rt2, inst.Rn, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrdLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrdL(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), true, inst.U != 0, false);
+ }
+
+ public static void LdrdLT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrdL(context, inst.Rt, inst.Rt2, inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrdRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrdR(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, inst.Rm, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrexA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrex(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrexT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.Ldrex(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrexbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrexbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrexdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexd(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn);
+ }
+
+ public static void LdrexdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rt2b8w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexd(context, inst.Rt, inst.Rt2, inst.Rn);
+ }
+
+ public static void LdrexhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrexhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Ldrexh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void LdrhtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrhtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrhtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrhtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void LdrhIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrhIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 1, true, true, false);
+ }
+
+ public static void LdrhIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void LdrhIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrhI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrhLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrhLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrhL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false);
+ }
+
+ public static void LdrhRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrhRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void LdrhRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void LdrsbtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrsbtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrsbtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrsbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void LdrsbIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrsbIT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void LdrsbIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrsbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrsbLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrsbLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrsbL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false);
+ }
+
+ public static void LdrsbRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrsbRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void LdrsbRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrsbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void LdrshtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrshtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrshtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrshtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void LdrshIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrshIT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void LdrshIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrshI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrshLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshL(context, inst.Rt, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrshLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrshL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false);
+ }
+
+ public static void LdrshRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrshRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void LdrshRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrshR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void LdrtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0);
+ }
+
+ public static void LdrtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void LdrIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 2, true, true, false);
+ }
+
+ public static void LdrIT2(CodeGenContext context, uint encoding)
+ {
+ InstRtb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitMemory.LdrI(context, inst.Rt, RegisterUtils.SpRegister, (int)inst.Imm8 << 2, true, true, false);
+ }
+
+ public static void LdrIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void LdrIT4(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.LdrI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrL(context, inst.Rt, inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrLT1(CodeGenContext context, uint encoding)
+ {
+ InstRtb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitMemory.LdrL(context, inst.Rt, inst.Imm8 << 2, true, true, false);
+ }
+
+ public static void LdrLT2(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.LdrL(context, inst.Rt, inst.Imm12, true, inst.U != 0, false);
+ }
+
+ public static void LdrRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void LdrRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void LdrRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.LdrR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void McrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mcr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2);
+ }
+
+ public static void McrT1(CodeGenContext context, uint encoding)
+ {
+ InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mcr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2);
+ }
+
+ public static void McrrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mcrr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crm);
+ }
+
+ public static void McrrT1(CodeGenContext context, uint encoding)
+ {
+ InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mcrr(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crm);
+ }
+
+ public static void MlaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void MlaT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void MlsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void MlsT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void MovtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMove.Movt(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4));
+ }
+
+ public static void MovtT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMove.Movt(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm8, inst.Imm3, inst.I, inst.Imm4));
+ }
+
+ public static void MovIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMove.MovI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void MovIA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm4b16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMove.MovI(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4), false, false);
+ }
+
+ public static void MovIT1(CodeGenContext context, uint encoding)
+ {
+ InstRdb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitMove.MovI(context, inst.Rd, inst.Imm8, false, !context.InITBlock);
+ }
+
+ public static void MovIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMove.MovI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void MovIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm4b16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMove.MovI(context, inst.Rd, ImmUtils.CombineImmU16(inst.Imm8, inst.Imm3, inst.I, inst.Imm4), false, false);
+ }
+
+ public static void MovRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MovR(context, inst.Cond, inst.Rd, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void MovRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb23w1Rmb19w4Rdb16w3 inst = new(encoding);
+
+ InstEmitMove.MovR(context, inst.Rd | (inst.D << 3), inst.Rm, 0, 0, false);
+ }
+
+ public static void MovRT2(CodeGenContext context, uint encoding)
+ {
+ InstOpb27w2Imm5b22w5Rmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitMove.MovR(context, inst.Rd, inst.Rm, inst.Op, inst.Imm5, !context.InITBlock);
+ }
+
+ public static void MovRT3(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MovR(context, inst.Rd, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void MovRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MovRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void MovRrT1(CodeGenContext context, uint encoding)
+ {
+ InstRsb19w3Rdmb16w3 inst = new(encoding);
+
+ InstEmitMove.MovRr(context, inst.Rdm, inst.Rdm, ((encoding >> 7) & 2) | ((encoding >> 6) & 1), inst.Rs, !context.InITBlock);
+ }
+
+ public static void MovRrT2(CodeGenContext context, uint encoding)
+ {
+ InstStypeb21w2Sb20w1Rmb16w4Rdb8w4Rsb0w4 inst = new(encoding);
+
+ InstEmitMove.MovRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void MrcA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2);
+ }
+
+ public static void MrcT1(CodeGenContext context, uint encoding)
+ {
+ InstOpc1b21w3Crnb16w4Rtb12w4Coproc0b8w1Opc2b5w3Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Crn, inst.Crm, inst.Opc2);
+ }
+
+ public static void MrrcA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mrrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Rt2, inst.Crm);
+ }
+
+ public static void MrrcT1(CodeGenContext context, uint encoding)
+ {
+ InstRt2b16w4Rtb12w4Coproc0b8w1Opc1b4w4Crmb0w4 inst = new(encoding);
+
+ InstEmitSystem.Mrrc(context, encoding, inst.Coproc0 | 0xe, inst.Opc1, inst.Rt, inst.Rt2, inst.Crm);
+ }
+
+ public static void MrsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rb22w1Rdb12w4 inst = new(encoding);
+
+ InstEmitSystem.Mrs(context, inst.Rd, inst.R != 0);
+ }
+
+ public static void MrsT1(CodeGenContext context, uint encoding)
+ {
+ InstRb20w1Rdb8w4 inst = new(encoding);
+
+ InstEmitSystem.Mrs(context, inst.Rd, inst.R != 0);
+ }
+
+ public static void MrsBrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rb22w1M1b16w4Rdb12w4Mb8w1 inst = new(encoding);
+
+ InstEmitSystem.MrsBr(context, inst.Rd, inst.M1 | (inst.M << 4), inst.R != 0);
+ }
+
+ public static void MrsBrT1(CodeGenContext context, uint encoding)
+ {
+ InstRb20w1M1b16w4Rdb8w4Mb4w1 inst = new(encoding);
+
+ InstEmitSystem.MrsBr(context, inst.Rd, inst.M1 | (inst.M << 4), inst.R != 0);
+ }
+
+ public static void MsrBrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rb22w1M1b16w4Mb8w1Rnb0w4 inst = new(encoding);
+
+ InstEmitSystem.MsrBr(context, inst.Rn, inst.M1 | (inst.M << 4), inst.R != 0);
+ }
+
+ public static void MsrBrT1(CodeGenContext context, uint encoding)
+ {
+ InstRb20w1Rnb16w4M1b8w4Mb4w1 inst = new(encoding);
+
+ InstEmitSystem.MsrBr(context, inst.Rn, inst.M1 | (inst.M << 4), inst.R != 0);
+ }
+
+ public static void MsrIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rb22w1Maskb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitSystem.MsrI(context, inst.Imm12, inst.Mask, inst.R != 0);
+ }
+
+ public static void MsrRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rb22w1Maskb16w4Rnb0w4 inst = new(encoding);
+
+ InstEmitSystem.MsrR(context, inst.Rn, inst.Mask, inst.R != 0);
+ }
+
+ public static void MsrRT1(CodeGenContext context, uint encoding)
+ {
+ InstRb20w1Rnb16w4Maskb8w4 inst = new(encoding);
+
+ InstEmitSystem.MsrR(context, inst.Rn, inst.Mask, inst.R != 0);
+ }
+
+ public static void MulA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mul(context, inst.Rd, inst.Rn, inst.Rm, inst.S != 0);
+ }
+
+ public static void MulT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb19w3Rdmb16w3 inst = new(encoding);
+
+ InstEmitMultiply.Mul(context, inst.Rdm, inst.Rn, inst.Rdm, !context.InITBlock);
+ }
+
+ public static void MulT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Mul(context, inst.Rd, inst.Rn, inst.Rm, false);
+ }
+
+ public static void MvnIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMove.MvnI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void MvnIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMove.MvnI(context, inst.Rd, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void MvnRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MvnR(context, inst.Rd, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void MvnRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitMove.MvnR(context, inst.Rd, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void MvnRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MvnR(context, inst.Rd, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void MvnRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.MvnRr(context, inst.Rd, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void NopA1(CodeGenContext context, uint encoding)
+ {
+ }
+
+ public static void NopT1(CodeGenContext context, uint encoding)
+ {
+ }
+
+ public static void NopT2(CodeGenContext context, uint encoding)
+ {
+ }
+
+ public static void OrnIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.OrnI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void OrnRT1(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.OrnR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void OrrIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.OrrI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12), inst.S != 0);
+ }
+
+ public static void OrrIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.OrrI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void OrrRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.OrrR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void OrrRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.OrrR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void OrrRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.OrrR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void OrrRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.OrrRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void PkhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Imm5b7w5Tbb6w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.Pkh(context, inst.Rd, inst.Rn, inst.Rm, inst.Tb != 0, inst.Imm5);
+ }
+
+ public static void PkhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Tbb5w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMove.Pkh(context, inst.Rd, inst.Rn, inst.Rm, inst.Tb != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void PldIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rb22w1Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PldI(context, inst.Rn, inst.Imm12, inst.U != 0, inst.R != 0);
+ }
+
+ public static void PldIT1(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PldI(context, inst.Rn, inst.Imm12, true, inst.W == 0);
+ }
+
+ public static void PldIT2(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.PldI(context, inst.Rn, inst.Imm8, false, inst.W == 0);
+ }
+
+ public static void PldLA1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PldL(context, inst.Imm12, inst.U != 0);
+ }
+
+ public static void PldLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PldL(context, inst.Imm12, inst.U != 0);
+ }
+
+ public static void PldRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rb22w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.PldR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.U != 0, inst.R != 0);
+ }
+
+ public static void PldRT1(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.PldR(context, inst.Rn, inst.Rm, 0, inst.Imm2, true, inst.W == 0);
+ }
+
+ public static void PliIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PliI(context, inst.Rn, inst.Imm12, inst.U != 0);
+ }
+
+ public static void PliIT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PliI(context, inst.Rn, inst.Imm12, true);
+ }
+
+ public static void PliIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.PliI(context, inst.Rn, inst.Imm8, false);
+ }
+
+ public static void PliIT3(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.PliL(context, inst.Imm12, inst.U != 0);
+ }
+
+ public static void PliRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.PliR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.U != 0);
+ }
+
+ public static void PliRT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.PliR(context, inst.Rn, inst.Rm, 0, inst.Imm2, true);
+ }
+
+ public static void PopT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1RegisterListb16w8 inst = new(encoding);
+
+ InstEmitMemory.Ldm(context, RegisterUtils.SpRegister, inst.RegisterList | (inst.P << RegisterUtils.PcRegister), true);
+ }
+
+ public static void PssbbA1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void PssbbT1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void PushT1(CodeGenContext context, uint encoding)
+ {
+ InstMb24w1RegisterListb16w8 inst = new(encoding);
+
+ InstEmitMemory.Stmdb(context, RegisterUtils.SpRegister, inst.RegisterList | (inst.M << RegisterUtils.LrRegister), true);
+ }
+
+ public static void QaddA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QaddT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QdaddA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qdadd(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QdaddT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qdadd(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QdsubA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qdsub(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QdsubT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qdsub(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QsubA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void QsubT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qsub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qsub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qsub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Qsub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Qsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void RbitA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rbit(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RbitT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rbit(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rev(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitBit.Rev(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rev(context, inst.Rd, inst.Rm);
+ }
+
+ public static void Rev16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rev16(context, inst.Rd, inst.Rm);
+ }
+
+ public static void Rev16T1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitBit.Rev16(context, inst.Rd, inst.Rm);
+ }
+
+ public static void Rev16T2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Rev16(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevshA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Revsh(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevshT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitBit.Revsh(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RevshT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitBit.Revsh(context, inst.Rd, inst.Rm);
+ }
+
+ public static void RfeA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void RfeT1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void RfeT2(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void RsbIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void RsbIT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, 0, !context.InITBlock);
+ }
+
+ public static void RsbIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.RsbI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void RsbRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.RsbR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void RsbRT1(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.RsbR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void RsbRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.RsbRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void RscIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.RscI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void RscRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.RscR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void RscRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.RscRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void Sadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Sadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Sadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Sadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SbA1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void SbT1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void SbcIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.SbcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void SbcIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SbcI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void SbcRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SbcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void SbcRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdnb16w3 inst = new(encoding);
+
+ InstEmitAlu.SbcR(context, inst.Rdn, inst.Rdn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void SbcRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SbcR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void SbcRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SbcRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void SbfxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding);
+
+ InstEmitBit.Sbfx(context, inst.Rd, inst.Rn, inst.Lsb, inst.Widthm1);
+ }
+
+ public static void SbfxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5 inst = new(encoding);
+
+ InstEmitBit.Sbfx(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Widthm1);
+ }
+
+ public static void SdivA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitDivide.Sdiv(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SdivT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitDivide.Sdiv(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SelA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sel(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SelT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Sel(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SetendA1(CodeGenContext context, uint encoding)
+ {
+ InstEb9w1 inst = new(encoding);
+
+ InstEmitSystem.Setend(context, inst.E != 0);
+ }
+
+ public static void SetendT1(CodeGenContext context, uint encoding)
+ {
+ InstEb19w1 inst = new(encoding);
+
+ InstEmitSystem.Setend(context, inst.E != 0);
+ }
+
+ public static void SetpanA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstImm1b9w1(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void SetpanT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstImm1b19w1(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void SevA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sev();
+ }
+
+ public static void SevT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sev();
+ }
+
+ public static void SevT2(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sev();
+ }
+
+ public static void SevlA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sevl();
+ }
+
+ public static void SevlT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sevl();
+ }
+
+ public static void SevlT2(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Sevl();
+ }
+
+ public static void Sha1cA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1c(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1cT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1c(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1hA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha1hT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha1mA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1m(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1mT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1m(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1pA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1p(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1pT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1p(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1su0A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1su0T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha1su1A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha1su1T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha1su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha256hA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha256hT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256h(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha256h2A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256h2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha256h2T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256h2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha256su0A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha256su0T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256su0(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void Sha256su1A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Sha256su1T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonHash.Sha256su1(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void Shadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void ShasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void ShasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void ShsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void ShsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shsub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shsub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shsub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Shsub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Shsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SmcA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void SmcT1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void SmlabbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlabb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmlabbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlabb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmladA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlad(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmladT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlad(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmlalA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0);
+ }
+
+ public static void SmlalT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false);
+ }
+
+ public static void SmlalbbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlalbb(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmlalbbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlalbb(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmlaldA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlald(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmlaldT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlald(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmlawbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb6w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlawb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmlawbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlawb(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmlsdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlsd(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmlsdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlsd(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.M != 0);
+ }
+
+ public static void SmlsldA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlsld(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmlsldT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smlsld(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmmlaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0);
+ }
+
+ public static void SmmlaT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmla(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0);
+ }
+
+ public static void SmmlsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0);
+ }
+
+ public static void SmmlsT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmls(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra, inst.R != 0);
+ }
+
+ public static void SmmulA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Rb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmul(context, inst.Rd, inst.Rn, inst.Rm, inst.R != 0);
+ }
+
+ public static void SmmulT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smmul(context, inst.Rd, inst.Rn, inst.Rm, inst.R != 0);
+ }
+
+ public static void SmuadA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smuad(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmuadT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smuad(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmulbbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Mb6w1Nb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smulbb(context, inst.Rd, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmulbbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Nb5w1Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smulbb(context, inst.Rd, inst.Rn, inst.Rm, inst.N != 0, inst.M != 0);
+ }
+
+ public static void SmullA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0);
+ }
+
+ public static void SmullT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false);
+ }
+
+ public static void SmulwbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Mb6w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smulwb(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmulwbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smulwb(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmusdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Mb5w1Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smusd(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SmusdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Mb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Smusd(context, inst.Rd, inst.Rn, inst.Rm, inst.M != 0);
+ }
+
+ public static void SrsA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void SrsT1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void SrsT2(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void SsatA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Ssat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, inst.Imm5);
+ }
+
+ public static void SsatT1(CodeGenContext context, uint encoding)
+ {
+ InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5 inst = new(encoding);
+
+ InstEmitSaturate.Ssat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void Ssat16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Ssat16(context, inst.Rd, inst.SatImm, inst.Rn);
+ }
+
+ public static void Ssat16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4SatImmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Ssat16(context, inst.Rd, inst.SatImm, inst.Rn);
+ }
+
+ public static void SsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void SsbbA1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void SsbbT1(CodeGenContext context, uint encoding)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static void Ssub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Ssub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Ssub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Ssub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Ssub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void StcA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.Stc(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StcT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Rnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.Stc(context, inst.Rn, (int)inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StlA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stl(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StlT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Stl(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StlbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StlbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Stlb(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlex(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlex(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexb(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexb(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexd(context, inst.Rd, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn);
+ }
+
+ public static void StlexdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexd(context, inst.Rd, inst.Rt, inst.Rt2, inst.Rn);
+ }
+
+ public static void StlexhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexh(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlexhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlexh(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StlhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Stlh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StlhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitMemory.Stlh(context, inst.Rt, inst.Rn);
+ }
+
+ public static void StmA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Stm(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void StmT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb24w3RegisterListb16w8 inst = new(encoding);
+
+ InstEmitMemory.Stm(context, inst.Rn, inst.RegisterList, false);
+ }
+
+ public static void StmT2(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Mb14w1RegisterListb0w14 inst = new(encoding);
+
+ InstEmitMemory.Stm(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M), inst.W != 0);
+ }
+
+ public static void StmdaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Stmda(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void StmdbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Stmdb(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void StmdbT1(CodeGenContext context, uint encoding)
+ {
+ InstWb21w1Rnb16w4Mb14w1RegisterListb0w14 inst = new(encoding);
+
+ InstEmitMemory.Stmdb(context, inst.Rn, ImmUtils.CombineRegisterList(inst.RegisterList, inst.M), inst.W != 0);
+ }
+
+ public static void StmibA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Wb21w1Rnb16w4RegisterListb0w16 inst = new(encoding);
+
+ InstEmitMemory.Stmib(context, inst.Rn, inst.RegisterList, inst.W != 0);
+ }
+
+ public static void StmUA1(CodeGenContext context, uint encoding)
+ {
+ InstEmitSystem.PrivilegedInstruction(context, encoding);
+ }
+
+ public static void StrbtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0);
+ }
+
+ public static void StrbtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrbtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0);
+ }
+
+ public static void StrbtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrbtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void StrbIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrbIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm5, true, true, false);
+ }
+
+ public static void StrbIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void StrbIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrbI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrbRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrbRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void StrbRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrbR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void StrdIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrdI(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrdIT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rt2b8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrdI(context, inst.Rt, inst.Rt2, inst.Rn, inst.Imm8 << 2, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrdRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrdR(context, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn, inst.Rm, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrexA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strex(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrexT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.Strex(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrexbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexb(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrexbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexb(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrexdA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexd(context, inst.Rd, inst.Rt, RegisterUtils.GetRt2(inst.Rt), inst.Rn);
+ }
+
+ public static void StrexdT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rt2b8w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexd(context, inst.Rd, inst.Rt, inst.Rt2, inst.Rn);
+ }
+
+ public static void StrexhA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rtb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexh(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrexhT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Rdb0w4 inst = new(encoding);
+
+ InstEmitMemory.Strexh(context, inst.Rd, inst.Rt, inst.Rn);
+ }
+
+ public static void StrhtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrhtI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), postIndex: true, inst.U != 0);
+ }
+
+ public static void StrhtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrhtR(context, inst.Rt, inst.Rn, inst.Rm, postIndex: true, inst.U != 0);
+ }
+
+ public static void StrhtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrhtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void StrhIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm4hb8w4Imm4lb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrhIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 1, true, true, false);
+ }
+
+ public static void StrhIT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void StrhIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrhI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrhRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrhRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void StrhRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrhR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void StrtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrtI(context, inst.Rt, inst.Rn, (int)inst.Imm12, postIndex: true, inst.U != 0);
+ }
+
+ public static void StrtA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrtR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, postIndex: true, inst.U != 0);
+ }
+
+ public static void StrtT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrtI(context, inst.Rt, inst.Rn, (int)inst.Imm8, postIndex: false, true);
+ }
+
+ public static void StrIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm5b22w5Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm5 << 2, true, true, false);
+ }
+
+ public static void StrIT2(CodeGenContext context, uint encoding)
+ {
+ InstRtb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitMemory.StrI(context, inst.Rt, RegisterUtils.SpRegister, (int)inst.Imm8 << 2, true, true, false);
+ }
+
+ public static void StrIT3(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm12, true, true, false);
+ }
+
+ public static void StrIT4(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Pb10w1Ub9w1Wb8w1Imm8b0w8 inst = new(encoding);
+
+ InstEmitMemory.StrI(context, inst.Rt, inst.Rn, (int)inst.Imm8, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Wb21w1Rnb16w4Rtb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.P != 0, inst.U != 0, inst.W != 0);
+ }
+
+ public static void StrRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rtb16w3 inst = new(encoding);
+
+ InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, 0, 0, true, true, false);
+ }
+
+ public static void StrRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rtb12w4Imm2b4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitMemory.StrR(context, inst.Rt, inst.Rn, inst.Rm, 0, inst.Imm2, true, true, false);
+ }
+
+ public static void SubIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void SubIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm3b22w3Rnb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, inst.Rn, inst.Imm3, !context.InITBlock);
+ }
+
+ public static void SubIT2(CodeGenContext context, uint encoding)
+ {
+ InstRdnb24w3Imm8b16w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rdn, inst.Rdn, inst.Imm8, !context.InITBlock);
+ }
+
+ public static void SubIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void SubIT4(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false);
+ }
+
+ public static void SubIT5(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, RegisterUtils.PcRegister, inst.Rn, inst.Imm8, true);
+ }
+
+ public static void SubRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void SubRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb22w3Rnb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, 0, 0, !context.InITBlock);
+ }
+
+ public static void SubRT2(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SubR(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), !context.InITBlock);
+ }
+
+ public static void SubRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rnb16w4Rdb12w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SubRr(context, inst.Rd, inst.Rn, inst.Rm, inst.Stype, inst.Rs, inst.S != 0);
+ }
+
+ public static void SubSpIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm12), inst.S != 0);
+ }
+
+ public static void SubSpIT1(CodeGenContext context, uint encoding)
+ {
+ InstImm7b16w7 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, RegisterUtils.SpRegister, RegisterUtils.SpRegister, inst.Imm7 << 2, false);
+ }
+
+ public static void SubSpIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Sb20w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), inst.S != 0);
+ }
+
+ public static void SubSpIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Imm3b12w3Rdb8w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.SubI(context, inst.Rd, RegisterUtils.SpRegister, ImmUtils.CombineImmU12(inst.Imm8, inst.Imm3, inst.I), false);
+ }
+
+ public static void SubSpRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SubR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, inst.Imm5, inst.S != 0);
+ }
+
+ public static void SubSpRT1(CodeGenContext context, uint encoding)
+ {
+ InstSb20w1Imm3b12w3Rdb8w4Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.SubR(context, inst.Rd, RegisterUtils.SpRegister, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.S != 0);
+ }
+
+ public static void SvcA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Imm24b0w24 inst = new(encoding);
+
+ InstEmitSystem.Svc(context, inst.Imm24);
+ }
+
+ public static void SvcT1(CodeGenContext context, uint encoding)
+ {
+ InstImm8b16w8 inst = new(encoding);
+
+ InstEmitSystem.Svc(context, inst.Imm8);
+ }
+
+ public static void SxtabA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxtabT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void Sxtab16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void Sxtab16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxtahA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxtahT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxtbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxtbT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, 0);
+ }
+
+ public static void SxtbT2(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtb(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void Sxtb16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtb16(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void Sxtb16T1(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxtb16(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxthA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void SxthT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, 0);
+ }
+
+ public static void SxthT2(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Sxth(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void TbbT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Hb4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitFlow.Tbb(context, inst.Rn, inst.Rm, inst.H != 0);
+ }
+
+ public static void TeqIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.TeqI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12));
+ }
+
+ public static void TeqIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.TeqI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I));
+ }
+
+ public static void TeqRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TeqR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5);
+ }
+
+ public static void TeqRT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TeqR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void TeqRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TeqRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs);
+ }
+
+ public static void TsbA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Tsb();
+ }
+
+ public static void TsbT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Tsb();
+ }
+
+ public static void TstIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitAlu.TstI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm12), ImmUtils.ExpandedImmRotated(inst.Imm12));
+ }
+
+ public static void TstIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb26w1Rnb16w4Imm3b12w3Imm8b0w8 inst = new(encoding);
+
+ InstEmitAlu.TstI(context, inst.Rn, ImmUtils.ExpandImm(inst.Imm8, inst.Imm3, inst.I), ImmUtils.ExpandedImmRotated(inst.Imm8, inst.Imm3, inst.I));
+ }
+
+ public static void TstRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Imm5b7w5Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TstR(context, inst.Rn, inst.Rm, inst.Stype, inst.Imm5);
+ }
+
+ public static void TstRT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rnb16w3 inst = new(encoding);
+
+ InstEmitAlu.TstR(context, inst.Rn, inst.Rm, 0, 0);
+ }
+
+ public static void TstRT2(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Imm2b6w2Stypeb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TstR(context, inst.Rn, inst.Rm, inst.Stype, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void TstRrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rsb8w4Stypeb5w2Rmb0w4 inst = new(encoding);
+
+ InstEmitAlu.TstRr(context, inst.Rn, inst.Rm, inst.Stype, inst.Rs);
+ }
+
+ public static void Uadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Uasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UbfxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Widthm1b16w5Rdb12w4Lsbb7w5Rnb0w4 inst = new(encoding);
+
+ InstEmitBit.Ubfx(context, inst.Rd, inst.Rn, inst.Lsb, inst.Widthm1);
+ }
+
+ public static void UbfxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Imm3b12w3Rdb8w4Imm2b6w2Widthm1b0w5 inst = new(encoding);
+
+ InstEmitBit.Ubfx(context, inst.Rd, inst.Rn, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3), inst.Widthm1);
+ }
+
+ public static void UdfA1(CodeGenContext context, uint encoding)
+ {
+ InstImm12b8w12Imm4b0w4 inst = new(encoding);
+
+ InstEmitSystem.Udf(context, encoding, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4));
+ }
+
+ public static void UdfT1(CodeGenContext context, uint encoding)
+ {
+ InstImm8b16w8 inst = new(encoding);
+
+ InstEmitSystem.Udf(context, encoding, inst.Imm8);
+ }
+
+ public static void UdfT2(CodeGenContext context, uint encoding)
+ {
+ InstImm4b16w4Imm12b0w12 inst = new(encoding);
+
+ InstEmitSystem.Udf(context, encoding, ImmUtils.CombineImmU16(inst.Imm12, inst.Imm4));
+ }
+
+ public static void UdivA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitDivide.Udiv(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UdivT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitDivide.Udiv(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UhasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UhasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UhsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UhsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhsub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhsub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhsub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uhsub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitHalve.Uhsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UmaalA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umaal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm);
+ }
+
+ public static void UmaalT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umaal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm);
+ }
+
+ public static void UmlalA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0);
+ }
+
+ public static void UmlalT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umlal(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false);
+ }
+
+ public static void UmullA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Sb20w1Rdhib16w4Rdlob12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, inst.S != 0);
+ }
+
+ public static void UmullT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdlob12w4Rdhib8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitMultiply.Umull(context, inst.Rdlo, inst.Rdhi, inst.Rn, inst.Rm, false);
+ }
+
+ public static void Uqadd16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqadd16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqadd16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqadd8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqadd8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqadd8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UqasxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UqasxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqasx(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UqsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UqsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqsub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqsub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqsub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Uqsub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Uqsub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usad8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitAbsDiff.Usad8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usad8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitAbsDiff.Usad8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usada8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb16w4Rab12w4Rmb8w4Rnb0w4 inst = new(encoding);
+
+ InstEmitAbsDiff.Usada8(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void Usada8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rab12w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitAbsDiff.Usada8(context, inst.Rd, inst.Rn, inst.Rm, inst.Ra);
+ }
+
+ public static void UsatA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4SatImmb16w5Rdb12w4Imm5b7w5Shb6w1Rnb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Usat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, inst.Imm5);
+ }
+
+ public static void UsatT1(CodeGenContext context, uint encoding)
+ {
+ InstShb21w1Rnb16w4Imm3b12w3Rdb8w4Imm2b6w2SatImmb0w5 inst = new(encoding);
+
+ InstEmitSaturate.Usat(context, inst.Rd, inst.SatImm, inst.Rn, inst.Sh != 0, ImmUtils.CombineImmU5(inst.Imm2, inst.Imm3));
+ }
+
+ public static void Usat16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4SatImmb16w4Rdb12w4Rnb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Usat16(context, inst.Rd, inst.SatImm, inst.Rn);
+ }
+
+ public static void Usat16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4SatImmb0w4 inst = new(encoding);
+
+ InstEmitSaturate.Usat16(context, inst.Rd, inst.SatImm, inst.Rn);
+ }
+
+ public static void UsaxA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UsaxT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usax(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usub16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usub16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usub16(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usub8A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void Usub8T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rmb0w4 inst = new(encoding);
+
+ InstEmitGE.Usub8(context, inst.Rd, inst.Rn, inst.Rm);
+ }
+
+ public static void UxtabA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxtabT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtab(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void Uxtab16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void Uxtab16T1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtab16(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxtahA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rnb16w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxtahT1(CodeGenContext context, uint encoding)
+ {
+ InstRnb16w4Rdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtah(context, inst.Rd, inst.Rn, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxtbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxtbT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, 0);
+ }
+
+ public static void UxtbT2(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtb(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void Uxtb16A1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtb16(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void Uxtb16T1(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxtb16(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxthA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Rdb12w4Rotateb10w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void UxthT1(CodeGenContext context, uint encoding)
+ {
+ InstRmb19w3Rdb16w3 inst = new(encoding);
+
+ InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, 0);
+ }
+
+ public static void UxthT2(CodeGenContext context, uint encoding)
+ {
+ InstRdb8w4Rotateb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitExtension.Uxth(context, inst.Rd, inst.Rm, inst.Rotate);
+ }
+
+ public static void VabaA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaba(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabaT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaba(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabalA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VabalT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VabdlIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabdl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VabdlIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabdl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VabdFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VabdF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VabdFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VabdF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VabdIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VabdI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabdIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VabdI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabsA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VabsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VabsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VabsT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VabsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VacgeA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vacge(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VacgeT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vacge(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VacgtA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vacgt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VacgtT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vacgt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VaddhnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VaddhnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VaddlA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VaddlT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VaddwA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VaddwT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vaddw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VaddFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VaddFA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VaddFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VaddFT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VaddIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VaddIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VandRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VandR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VandRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VandR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbicIA1(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VbicIA2(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VbicIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VbicIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VbicRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbicRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbicR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbifA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbifR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbifT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbifR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbitA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbitR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbitT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbitR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbslA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbslR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VbslT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VbslR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VcaddA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcaddT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstRotb24w1Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VceqIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VceqIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VceqRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VceqRA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VceqRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VceqRT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VceqFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VcgeIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgeIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgeRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgeRA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VcgeRT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgeRT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgeFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VcgtIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgtIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgtRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgtRA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VcgtRT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcgtRT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcgtFR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VcleIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcleI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcleIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcleI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VclsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vcls(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VclsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vcls(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VcltIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcltI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcltIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.VcltI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VclzA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vclz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VclzT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vclz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VcmlaA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcmlaT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstRotb23w2Db22w1Sb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcmlaSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcmlaST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstSb23w1Db22w1Rotb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcmpA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpR(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VcmpA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpI(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size);
+ }
+
+ public static void VcmpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpR(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VcmpT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpI(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size);
+ }
+
+ public static void VcmpeA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpeR(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VcmpeA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpeI(context, inst.Cond, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size);
+ }
+
+ public static void VcmpeT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpeR(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VcmpeT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2 inst = new(encoding);
+
+ InstEmitVfpCompare.VcmpeI(context, 0xe, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Size);
+ }
+
+ public static void VcntA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vcnt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VcntT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vcnt(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VcvtaAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtaAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtaVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvta(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtaVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvta(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtbA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u;
+ uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u;
+
+ InstEmitVfpConvert.Vcvtb(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op);
+ }
+
+ public static void VcvtbT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u;
+ uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u;
+
+ InstEmitVfpConvert.Vcvtb(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op);
+ }
+
+ public static void VcvtbBfsA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvtbBfsT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvtmAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtmAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtmVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtmVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtnAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtnAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtnVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtn(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtnVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtn(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtpAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtpAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.Vcvtp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VcvtpVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtp(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtpVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.Vcvtp(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Op != 0, inst.Size);
+ }
+
+ public static void VcvtrIvA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtrIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding >> 16) & 7, inst.Size);
+ }
+
+ public static void VcvtrIvT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtrIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding >> 16) & 7, inst.Size);
+ }
+
+ public static void VcvttA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u;
+ uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u;
+
+ InstEmitVfpConvert.Vcvtt(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op);
+ }
+
+ public static void VcvttT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Opb16w1Vdb12w4Szb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint dSize = inst.Sz == 1 && inst.Op == 0 ? 3u : 2u;
+ uint mSize = inst.Sz == 1 && inst.Op == 1 ? 3u : 2u;
+
+ InstEmitVfpConvert.Vcvtt(context, InstEmitCommon.CombineV(inst.Vd, inst.D, dSize), InstEmitCommon.CombineV(inst.Vm, inst.M, mSize), inst.Sz, inst.Op);
+ }
+
+ public static void VcvttBfsA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvttBfsT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvtBfsA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvtBfsT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VcvtDsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint size = (encoding >> 8) & 3;
+
+ InstEmitVfpConvert.VcvtDs(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size ^ 1u), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size);
+ }
+
+ public static void VcvtDsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint size = (encoding >> 8) & 3;
+
+ InstEmitVfpConvert.VcvtDs(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size ^ 1u), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size);
+ }
+
+ public static void VcvtHsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtHs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0);
+ }
+
+ public static void VcvtHsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtHs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0);
+ }
+
+ public static void VcvtIsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtIs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size, inst.Q);
+ }
+
+ public static void VcvtIsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtIs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size, inst.Q);
+ }
+
+ public static void VcvtIvA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding & (1u << 16)) == 0, inst.Size);
+ }
+
+ public static void VcvtIvT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtIv(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), (encoding & (1u << 16)) == 0, inst.Size);
+ }
+
+ public static void VcvtViA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtVi(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op == 0, inst.Size);
+ }
+
+ public static void VcvtViT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Opb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtVi(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op == 0, inst.Size);
+ }
+
+ public static void VcvtXsA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtXs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.Op, inst.U != 0, inst.Q);
+ }
+
+ public static void VcvtXsT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w2Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonConvert.VcvtXs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.Op, inst.U != 0, inst.Q);
+ }
+
+ public static void VcvtXvA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtXv(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Sf), ImmUtils.CombineImmU5IImm4(inst.I, inst.Imm4), inst.Sx != 0, inst.Sf, inst.Op, inst.U != 0);
+ }
+
+ public static void VcvtXvT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Opb18w1Ub16w1Vdb12w4Sfb8w2Sxb7w1Ib5w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitVfpConvert.VcvtXv(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Sf), ImmUtils.CombineImmU5IImm4(inst.I, inst.Imm4), inst.Sx != 0, inst.Sf, inst.Op, inst.U != 0);
+ }
+
+ public static void VdivA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VdivF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VdivT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VdivF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VdotA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VdotT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VdotSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VdotST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VdupRA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Bb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 inst = new(encoding);
+
+ InstEmitNeonMove.VdupR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.B, inst.E, inst.Q);
+ }
+
+ public static void VdupRT1(CodeGenContext context, uint encoding)
+ {
+ InstBb22w1Qb21w1Vdb16w4Rtb12w4Db7w1Eb5w1 inst = new(encoding);
+
+ InstEmitNeonMove.VdupR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.B, inst.E, inst.Q);
+ }
+
+ public static void VdupSA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VdupS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q);
+ }
+
+ public static void VdupST1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm4b16w4Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VdupS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q);
+ }
+
+ public static void VeorA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VeorR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VeorT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VeorR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VextA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vext(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q);
+ }
+
+ public static void VextT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Imm4b8w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vext(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm4, inst.Q);
+ }
+
+ public static void VfmaA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VfmaA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfmaT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VfmaT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfmalA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmalT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmalSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmalST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmaBfA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmaBfT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmaBfsA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmaBfsT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VfmsA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfmsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VfmsT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfmslA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmslT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmslSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfmslST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VfnmaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfnmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfnmaT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfnmaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfnmsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfnmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VfnmsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VfnmsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VhaddA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VhaddT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VhsubA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vhsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VhsubT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vhsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VinsA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VinsT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VjcvtA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VjcvtT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vdb12w4Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void Vld11A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld11A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld11A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld11T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld11T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld11T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld1AA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld1AT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld1MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MA3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MA4(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MT3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size);
+ }
+
+ public static void Vld1MT4(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size);
+ }
+
+ public static void Vld21A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld21A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld21A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld21T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld21T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld21T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld2AA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld2AT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld2MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vld2MA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size);
+ }
+
+ public static void Vld2MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vld2MT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size);
+ }
+
+ public static void Vld31A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld31A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld31A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld31T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld31T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld31T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld3AA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld3A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 0, inst.T, inst.Size);
+ }
+
+ public static void Vld3AT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld3A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 0, inst.T, inst.Size);
+ }
+
+ public static void Vld3MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vld3MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vld41A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld41A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld41A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld41T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vld41T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vld41T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vld4AA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld4A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld4AT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Tb5w1Ab4w1Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld4A(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.A, inst.T, inst.Size);
+ }
+
+ public static void Vld4MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vld4MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vld4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void VldmA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void VldmA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true);
+ }
+
+ public static void VldmT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void VldmT2(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true);
+ }
+
+ public static void VldrIA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VldrIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VldrLA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), RegisterUtils.PcRegister, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VldrLT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Db22w1Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vldr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), RegisterUtils.PcRegister, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VmaxnmA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmaxnmA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmaxnmT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmaxnmT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.Vmaxnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmaxFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmaxFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmaxIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmaxIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VminnmA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VminnmA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VminnmT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VminnmT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.Vminnm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VminFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VminFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VminIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VminIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmlalIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlalI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlalIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlalI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlalSA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlalST1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlaFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmlaFA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmlaFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmlaFT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmlaIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VmlaIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VmlaSA1(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmlaST1(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlaS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmlslIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlslI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlslIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlslI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlslSA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlslST1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmlsFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmlsFA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmlsFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmlsFT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmlsIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VmlsIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VmlsSA1(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmlsST1(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmlsS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmmlaA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VmmlaT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VmovlA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Imm3h);
+ }
+
+ public static void VmovlT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm3hb19w3Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Imm3h);
+ }
+
+ public static void VmovnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VmovnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VmovxA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M));
+ }
+
+ public static void VmovxT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vmovx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M));
+ }
+
+ public static void VmovDA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovD(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0);
+ }
+
+ public static void VmovDT1(CodeGenContext context, uint encoding)
+ {
+ InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovD(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0);
+ }
+
+ public static void VmovHA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding);
+
+ InstEmitNeonMove.VmovH(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0);
+ }
+
+ public static void VmovHT1(CodeGenContext context, uint encoding)
+ {
+ InstOpb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding);
+
+ InstEmitNeonMove.VmovH(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0);
+ }
+
+ public static void VmovIA1(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovFI(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.Size);
+ }
+
+ public static void VmovIA3(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIA4(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIA5(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 1, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm4hb16w4Vdb12w4Sizeb8w2Imm4lb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovFI(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), ImmUtils.CombineImmU8(inst.Imm4l, inst.Imm4h), inst.Size);
+ }
+
+ public static void VmovIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIT4(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 0, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovIT5(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), 1, (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmovRA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint size = (encoding >> 8) & 3;
+
+ InstEmitNeonMove.VmovR(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size);
+ }
+
+ public static void VmovRT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ uint size = (encoding >> 8) & 3;
+
+ InstEmitNeonMove.VmovR(context, InstEmitCommon.CombineV(inst.Vd, inst.D, size), InstEmitCommon.CombineV(inst.Vm, inst.M, size), size);
+ }
+
+ public static void VmovRsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 inst = new(encoding);
+
+ InstEmitNeonMove.VmovRs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.Opc1, inst.Opc2);
+ }
+
+ public static void VmovRsT1(CodeGenContext context, uint encoding)
+ {
+ InstOpc1b21w2Vdb16w4Rtb12w4Db7w1Opc2b5w2 inst = new(encoding);
+
+ InstEmitNeonMove.VmovRs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rt, inst.Opc1, inst.Opc2);
+ }
+
+ public static void VmovSA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding);
+
+ InstEmitNeonMove.VmovS(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0);
+ }
+
+ public static void VmovST1(CodeGenContext context, uint encoding)
+ {
+ InstOpb20w1Vnb16w4Rtb12w4Nb7w1 inst = new(encoding);
+
+ InstEmitNeonMove.VmovS(context, inst.Rt, InstEmitCommon.CombineVF(inst.N, inst.Vn), inst.Op != 0);
+ }
+
+ public static void VmovSrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 inst = new(encoding);
+
+ InstEmitNeonMove.VmovSr(context, inst.Rt, InstEmitCommon.CombineV(inst.Vn, inst.N), inst.U != 0, inst.Opc1, inst.Opc2);
+ }
+
+ public static void VmovSrT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Opc1b21w2Vnb16w4Rtb12w4Nb7w1Opc2b5w2 inst = new(encoding);
+
+ InstEmitNeonMove.VmovSr(context, inst.Rt, InstEmitCommon.CombineV(inst.Vn, inst.N), inst.U != 0, inst.Opc1, inst.Opc2);
+ }
+
+ public static void VmovSsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Opb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovSs(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op != 0);
+ }
+
+ public static void VmovSsT1(CodeGenContext context, uint encoding)
+ {
+ InstOpb20w1Rt2b16w4Rtb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmovSs(context, inst.Rt, inst.Rt2, InstEmitCommon.CombineVF(inst.M, inst.Vm), inst.Op != 0);
+ }
+
+ public static void VmrsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Regb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitNeonSystem.Vmrs(context, inst.Rt, inst.Reg);
+ }
+
+ public static void VmrsT1(CodeGenContext context, uint encoding)
+ {
+ InstRegb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitNeonSystem.Vmrs(context, inst.Rt, inst.Reg);
+ }
+
+ public static void VmsrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Regb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitNeonSystem.Vmsr(context, inst.Rt, inst.Reg);
+ }
+
+ public static void VmsrT1(CodeGenContext context, uint encoding)
+ {
+ InstRegb16w4Rtb12w4 inst = new(encoding);
+
+ InstEmitNeonSystem.Vmsr(context, inst.Rt, inst.Reg);
+ }
+
+ public static void VmullIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmullI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.U != 0, inst.Size);
+ }
+
+ public static void VmullIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Opb9w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmullI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.U != 0, inst.Size);
+ }
+
+ public static void VmullSA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmullST1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VmulFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmulFA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmulFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VmulFT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VmulIA1(CodeGenContext context, uint encoding)
+ {
+ InstOpb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmulIT1(CodeGenContext context, uint encoding)
+ {
+ InstOpb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmulSA1(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmulST1(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Fb8w1Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VmulS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VmvnIA1(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnIA2(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnIA3(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnIT3(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VmvnRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VmvnRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.VmvnR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VnegA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VnegA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnegF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnegT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb10w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VnegT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnegF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmlaA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmlaT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmlaF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmlsA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmlsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmlsF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmulA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VnmulT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VnmulF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VornRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VornR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VornRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VornR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VorrIA1(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VorrIA2(CodeGenContext context, uint encoding)
+ {
+ InstIb24w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VorrIT1(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VorrIT2(CodeGenContext context, uint encoding)
+ {
+ InstIb28w1Db22w1Imm3b16w3Vdb12w4Qb6w1Imm4b0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), (encoding >> 8) & 0xf, ImmUtils.CombineImmU8(inst.Imm4, inst.Imm3, inst.I), inst.Q);
+ }
+
+ public static void VorrRA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VorrRT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonLogical.VorrR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VpadalA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vpadal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VpadalT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vpadal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VpaddlA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vpaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VpaddlT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vpaddl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Size, inst.Q);
+ }
+
+ public static void VpaddFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VpaddFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpaddF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VpaddIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VpaddIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpaddI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VpmaxFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0);
+ }
+
+ public static void VpmaxFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpmaxF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0);
+ }
+
+ public static void VpmaxIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0);
+ }
+
+ public static void VpmaxIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpmaxI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0);
+ }
+
+ public static void VpminFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0);
+ }
+
+ public static void VpminFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpminF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, 0);
+ }
+
+ public static void VpminIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0);
+ }
+
+ public static void VpminIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VpminI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, 0);
+ }
+
+ public static void VqabsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqabsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqabs(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqaddA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VqaddT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VqdmlalA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmlal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlalA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlalT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmlal(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlalT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmlalS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlslA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmlsl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlslA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlslT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmlsl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmlslT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmlslS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmulhA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqdmulhA2(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqdmulhT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqdmulhT2(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqdmullA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmull(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmullA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmullT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqdmull(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqdmullT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqdmullS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VqmovnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size);
+ }
+
+ public static void VqmovnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Opb6w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqmovn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op, inst.Size);
+ }
+
+ public static void VqnegA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqnegT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqneg(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlahA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmlah(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlahA2(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmlahS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlahT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmlah(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlahT2(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmlahS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlshA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmlsh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlshA2(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmlshS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlshT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmlsh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmlshT2(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmlshS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmulhA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmulhA2(CodeGenContext context, uint encoding)
+ {
+ InstQb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmulhT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrdmulh(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrdmulhT2(CodeGenContext context, uint encoding)
+ {
+ InstQb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqrdmulhS(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrshlA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrshlT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VqrshrnA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6);
+ }
+
+ public static void VqrshrnT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6);
+ }
+
+ public static void VqshlIA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VqshlIT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VqshlRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VqshlRT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.VqshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VqshrnA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6);
+ }
+
+ public static void VqshrnT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Opb8w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Op, inst.Imm6);
+ }
+
+ public static void VqsubA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VqsubT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonSaturate.Vqsub(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VraddhnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vraddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VraddhnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vraddhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VrecpeA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrecpe(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrecpeT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrecpe(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrecpsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrecps(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VrecpsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrecps(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void Vrev16A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev16(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void Vrev16T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev16(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void Vrev32A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev32(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void Vrev32T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev32(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void Vrev64A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev64(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void Vrev64T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonBit.Vrev64(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrhaddA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrhaddT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrhadd(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrintaAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintaAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintaVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintaVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrinta(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintmAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintmAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintmVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintmVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintm(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintnAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintnAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintnVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintnVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintn(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintpAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintpAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintpVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintpVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintp(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintrVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintrVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintxAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintxAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintxVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintxVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintx(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintzAsimdA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintzAsimdT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VrintzVfpA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrintzVfpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpRound.Vrintz(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VrshlA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrshlT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrshrA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VrshrT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VrshrnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6);
+ }
+
+ public static void VrshrnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6);
+ }
+
+ public static void VrsqrteA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrsqrte(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrsqrteT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Fb8w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrsqrte(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.F != 0, inst.Size, inst.Q);
+ }
+
+ public static void VrsqrtsA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrsqrts(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VrsqrtsT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vrsqrts(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VrsraA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VrsraT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VrsubhnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VrsubhnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonRound.Vrsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VsdotA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsdotT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsdotSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsdotST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VselA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpMove.Vsel(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Cc, inst.Size);
+ }
+
+ public static void VselT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Ccb20w2Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpMove.Vsel(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Cc, inst.Size);
+ }
+
+ public static void VshllA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshll(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.U != 0);
+ }
+
+ public static void VshllA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshll2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VshllT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshll(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6, inst.U != 0);
+ }
+
+ public static void VshllT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshll2(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VshlIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.VshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VshlIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.VshlI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VshlRA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.VshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VshlRT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.VshlR(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size, inst.Q);
+ }
+
+ public static void VshrA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VshrT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshr(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VshrnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6);
+ }
+
+ public static void VshrnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vshrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Imm6);
+ }
+
+ public static void VsliA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsli(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VsliT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsli(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VsmmlaA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsmmlaT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsqrtA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VsqrtF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VsqrtT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Sizeb8w2Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VsqrtF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VsraA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VsraT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsra(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VsriA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsri(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void VsriT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Imm6b16w6Vdb12w4Lb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonShift.Vsri(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.L, inst.Imm6, inst.Q);
+ }
+
+ public static void Vst11A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst11A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst11A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst11T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst11T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst11T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst11(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst1MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MA3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MA4(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 1, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 2, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MT3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 3, inst.Align, inst.Size);
+ }
+
+ public static void Vst1MT4(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst1M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, 4, inst.Align, inst.Size);
+ }
+
+ public static void Vst21A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst21A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst21A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst21T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst21T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst21T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst21(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst2MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vst2MA2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size);
+ }
+
+ public static void Vst2MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vst2MT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst2M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.Align, inst.Size);
+ }
+
+ public static void Vst31A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst31A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst31A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst31T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst31T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst31T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst31(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst3MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vst3MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst3M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vst41A1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst41A2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst41A3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst41T1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 0);
+ }
+
+ public static void Vst41T2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 1);
+ }
+
+ public static void Vst41T3(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4IndexAlignb4w4Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst41(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, inst.IndexAlign, 2);
+ }
+
+ public static void Vst4MA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void Vst4MT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Rnb16w4Vdb12w4Sizeb6w2Alignb4w2Rmb0w4 inst = new(encoding);
+
+ InstEmitNeonMemory.Vst4M(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Rm, (encoding >> 8) & 0xf, inst.Align, inst.Size);
+ }
+
+ public static void VstmA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void VstmA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Pb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true);
+ }
+
+ public static void VstmT1(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm871b1w7 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineV(inst.Vd, inst.D), inst.Rn, inst.Imm871, inst.U != 0, inst.W != 0, singleRegs: false);
+ }
+
+ public static void VstmT2(CodeGenContext context, uint encoding)
+ {
+ InstPb24w1Ub23w1Db22w1Wb21w1Rnb16w4Vdb12w4Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstm(context, InstEmitCommon.CombineVF(inst.D, inst.Vd), inst.Rn, inst.Imm8, inst.U != 0, inst.W != 0, singleRegs: true);
+ }
+
+ public static void VstrA1(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Ub23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VstrT1(CodeGenContext context, uint encoding)
+ {
+ InstUb23w1Db22w1Rnb16w4Vdb12w4Sizeb8w2Imm8b0w8 inst = new(encoding);
+
+ InstEmitNeonMemory.Vstr(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), inst.Rn, inst.Imm8, inst.U != 0, inst.Size);
+ }
+
+ public static void VsubhnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VsubhnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubhn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size);
+ }
+
+ public static void VsublA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VsublT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VsubwA1(CodeGenContext context, uint encoding)
+ {
+ InstUb24w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VsubwT1(CodeGenContext context, uint encoding)
+ {
+ InstUb28w1Db22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.Vsubw(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.U != 0, inst.Size);
+ }
+
+ public static void VsubFA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VsubFA2(CodeGenContext context, uint encoding)
+ {
+ InstCondb28w4Db22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VsubFT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Szb20w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Sz, inst.Q);
+ }
+
+ public static void VsubFT2(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Sizeb8w2Nb7w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitVfpArithmetic.VsubF(context, InstEmitCommon.CombineV(inst.Vd, inst.D, inst.Size), InstEmitCommon.CombineV(inst.Vn, inst.N, inst.Size), InstEmitCommon.CombineV(inst.Vm, inst.M, inst.Size), inst.Size);
+ }
+
+ public static void VsubIA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VsubI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VsubIT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonArithmetic.VsubI(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VsudotSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VsudotST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VswpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vswp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VswpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vswp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Q);
+ }
+
+ public static void VtblA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vtbl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Len);
+ }
+
+ public static void VtblT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Vnb16w4Vdb12w4Lenb8w2Nb7w1Opb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vtbl(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Op != 0, inst.Len);
+ }
+
+ public static void VtrnA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vtrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VtrnT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vtrn(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VtstA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vtst(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VtstT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb20w2Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonCompare.Vtst(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vn, inst.N), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VudotA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VudotT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VudotSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VudotST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VummlaA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VummlaT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusdotA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusdotT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusdotSA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusdotST1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Qb6w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusmmlaA1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VusmmlaT1(CodeGenContext context, uint encoding)
+ {
+ _ = new InstDb22w1Vnb16w4Vdb12w4Nb7w1Mb5w1Vmb0w4(encoding);
+
+ throw new NotImplementedException();
+ }
+
+ public static void VuzpA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vuzp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VuzpT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vuzp(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VzipA1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vzip(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void VzipT1(CodeGenContext context, uint encoding)
+ {
+ InstDb22w1Sizeb18w2Vdb12w4Qb6w1Mb5w1Vmb0w4 inst = new(encoding);
+
+ InstEmitNeonMove.Vzip(context, InstEmitCommon.CombineV(inst.Vd, inst.D), InstEmitCommon.CombineV(inst.Vm, inst.M), inst.Size, inst.Q);
+ }
+
+ public static void WfeA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfe();
+ }
+
+ public static void WfeT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfe();
+ }
+
+ public static void WfeT2(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfe();
+ }
+
+ public static void WfiA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfi();
+ }
+
+ public static void WfiT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfi();
+ }
+
+ public static void WfiT2(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Wfi();
+ }
+
+ public static void YieldA1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Yield();
+ }
+
+ public static void YieldT1(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Yield();
+ }
+
+ public static void YieldT2(CodeGenContext context, uint encoding)
+ {
+ context.Arm64Assembler.Yield();
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs
new file mode 100644
index 00000000..f8100503
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs
@@ -0,0 +1,87 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitAbsDiff
+ {
+ public static void Usad8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ for (int b = 0; b < 4; b++)
+ {
+ context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8);
+ context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8);
+
+ Operand dest = b == 0 ? tempD.Operand : tempD2.Operand;
+
+ context.Arm64Assembler.Sub(dest, tempN.Operand, tempM.Operand);
+
+ EmitAbs(context, dest);
+
+ if (b > 0)
+ {
+ if (b < 3)
+ {
+ context.Arm64Assembler.Add(tempD.Operand, tempD.Operand, dest);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(rdOperand, tempD.Operand, dest);
+ }
+ }
+ }
+ }
+
+ public static void Usada8(CodeGenContext context, uint rd, uint rn, uint rm, uint ra)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ for (int b = 0; b < 4; b++)
+ {
+ context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8);
+ context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8);
+
+ Operand dest = b == 0 ? tempD.Operand : tempD2.Operand;
+
+ context.Arm64Assembler.Sub(dest, tempN.Operand, tempM.Operand);
+
+ EmitAbs(context, dest);
+
+ if (b > 0)
+ {
+ context.Arm64Assembler.Add(tempD.Operand, tempD.Operand, dest);
+ }
+ }
+
+ context.Arm64Assembler.Add(rdOperand, tempD.Operand, raOperand);
+ }
+
+ private static void EmitAbs(CodeGenContext context, Operand value)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ // r = (value + ((int)value >> 31)) ^ ((int)value >> 31).
+ // Subtracts 1 and then inverts the value if the sign bit is set, same as a conditional negation.
+
+ context.Arm64Assembler.Add(tempRegister.Operand, value, value, ArmShiftType.Asr, 31);
+ context.Arm64Assembler.Eor(value, tempRegister.Operand, value, ArmShiftType.Asr, 31);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs
new file mode 100644
index 00000000..c0762819
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs
@@ -0,0 +1,1105 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitAlu
+ {
+ private const uint Imm12Limit = 0x1000;
+
+ public static void AdcI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ EmitI(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, imm, s);
+ }
+
+ public static void AdcR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitR(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void AdcRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Adcs : context.Arm64Assembler.Adc, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void AddI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ EmitArithmeticI(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, imm, s);
+ }
+
+ public static void AddR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitArithmeticR(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void AddRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Adds : context.Arm64Assembler.Add, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void Adr(CodeGenContext context, uint rd, uint imm, bool add)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ uint pc = context.Pc & ~3u;
+
+ if (add)
+ {
+ pc += imm;
+ }
+ else
+ {
+ pc -= imm;
+ }
+
+ context.Arm64Assembler.Mov(rdOperand, pc);
+ }
+
+ public static void AndI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s)
+ {
+ EmitLogicalI(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, imm, immRotated, s);
+ }
+
+ public static void AndR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitLogicalR(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void AndRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitLogicalRr(context, s ? context.Arm64Assembler.Ands : context.Arm64Assembler.And, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void BicI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s)
+ {
+ if (!s && CodeGenCommon.TryEncodeBitMask(OperandType.I32, ~imm, out _, out _, out _))
+ {
+ AndI(context, rd, rn, ~imm, immRotated, s);
+ }
+ else
+ {
+ EmitLogicalI(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, imm, immRotated, s, immForm: false);
+ }
+ }
+
+ public static void BicR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitLogicalR(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void BicRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitLogicalRr(context, s ? context.Arm64Assembler.Bics : context.Arm64Assembler.Bic, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void CmnI(CodeGenContext context, uint rn, uint imm)
+ {
+ EmitCompareI(context, context.Arm64Assembler.Cmn, rn, imm);
+ }
+
+ public static void CmnR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5)
+ {
+ EmitCompareR(context, context.Arm64Assembler.Cmn, rn, rm, sType, imm5);
+ }
+
+ public static void CmnRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs)
+ {
+ EmitCompareRr(context, context.Arm64Assembler.Cmn, rn, rm, sType, rs);
+ }
+
+ public static void CmpI(CodeGenContext context, uint rn, uint imm)
+ {
+ EmitCompareI(context, context.Arm64Assembler.Cmp, rn, imm);
+ }
+
+ public static void CmpR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5)
+ {
+ EmitCompareR(context, context.Arm64Assembler.Cmp, rn, rm, sType, imm5);
+ }
+
+ public static void CmpRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs)
+ {
+ EmitCompareRr(context, context.Arm64Assembler.Cmp, rn, rm, sType, rs);
+ }
+
+ public static void EorI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s)
+ {
+ EmitLogicalI(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, imm, immRotated, s);
+ }
+
+ public static void EorR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitLogicalR(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void EorRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitLogicalRr(context, s ? context.Arm64Assembler.Eors : context.Arm64Assembler.Eor, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void OrnI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s)
+ {
+ if (!s && CodeGenCommon.TryEncodeBitMask(OperandType.I32, ~imm, out _, out _, out _))
+ {
+ OrrI(context, rd, rn, ~imm, immRotated, s);
+ }
+ else
+ {
+ EmitLogicalI(context, s ? context.Arm64Assembler.Orns : context.Arm64Assembler.Orn, rd, rn, imm, immRotated, s, immForm: false);
+ }
+ }
+
+ public static void OrnR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitLogicalR(context, s ? context.Arm64Assembler.Orns : context.Arm64Assembler.Orn, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void OrrI(CodeGenContext context, uint rd, uint rn, uint imm, bool immRotated, bool s)
+ {
+ EmitLogicalI(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, imm, immRotated, s);
+ }
+
+ public static void OrrR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitLogicalR(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void OrrRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitLogicalRr(context, s ? context.Arm64Assembler.Orrs : context.Arm64Assembler.Orr, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void RsbI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ if (imm == 0)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ if (s)
+ {
+ context.Arm64Assembler.Negs(rdOperand, rnOperand);
+ context.SetNzcvModified();
+ }
+ else
+ {
+ context.Arm64Assembler.Neg(rdOperand, rnOperand);
+ }
+ }
+ else
+ {
+ EmitI(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, imm, s, reverse: true);
+ }
+ }
+
+ public static void RsbR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitR(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, imm5, s, reverse: true);
+ }
+
+ public static void RsbRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, rs, s, reverse: true);
+ }
+
+ public static void RscI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ EmitI(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, imm, s, reverse: true);
+ }
+
+ public static void RscR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitR(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, imm5, s, reverse: true);
+ }
+
+ public static void RscRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, rs, s, reverse: true);
+ }
+
+ public static void SbcI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ EmitI(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, imm, s);
+ }
+
+ public static void SbcR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitR(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void SbcRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Sbcs : context.Arm64Assembler.Sbc, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void SubI(CodeGenContext context, uint rd, uint rn, uint imm, bool s)
+ {
+ EmitArithmeticI(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, imm, s);
+ }
+
+ public static void SubR(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ EmitArithmeticR(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, imm5, s);
+ }
+
+ public static void SubRr(CodeGenContext context, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ EmitRr(context, s ? context.Arm64Assembler.Subs : context.Arm64Assembler.Sub, rd, rn, rm, sType, rs, s);
+ }
+
+ public static void TeqI(CodeGenContext context, uint rn, uint imm, bool immRotated)
+ {
+ EmitLogicalI(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, imm, immRotated);
+ }
+
+ public static void TeqR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5)
+ {
+ EmitLogicalR(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, rm, sType, imm5);
+ }
+
+ public static void TeqRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs)
+ {
+ EmitLogicalRr(context, (rnOperand, rmOperand) => EmitTeq(context, rnOperand, rmOperand), rn, rm, sType, rs);
+ }
+
+ public static void TstI(CodeGenContext context, uint rn, uint imm, bool immRotated)
+ {
+ EmitLogicalI(context, context.Arm64Assembler.Tst, rn, imm, immRotated);
+ }
+
+ public static void TstR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5)
+ {
+ EmitLogicalR(context, context.Arm64Assembler.Tst, rn, rm, sType, imm5);
+ }
+
+ public static void TstRr(CodeGenContext context, uint rn, uint rm, uint sType, uint rs)
+ {
+ EmitLogicalRr(context, context.Arm64Assembler.Tst, rn, rm, sType, rs);
+ }
+
+ private static void EmitArithmeticI(CodeGenContext context, Action action, uint rd, uint rn, uint imm, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ if (imm < Imm12Limit)
+ {
+ Operand rmOperand = new(OperandKind.Constant, OperandType.I32, imm);
+
+ action(rdOperand, rnOperand, rmOperand);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, imm);
+
+ action(rdOperand, rnOperand, tempRegister.Operand);
+ }
+
+ if (s)
+ {
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitArithmeticR(
+ CodeGenContext context,
+ Action action,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint sType,
+ uint imm5,
+ bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (CanShiftArithmetic(sType, imm5))
+ {
+ action(rdOperand, rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType);
+
+ action(rdOperand, rnOperand, rmOperand, ArmShiftType.Lsl, 0);
+ }
+
+ if (s)
+ {
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitCompareI(CodeGenContext context, Action action, uint rn, uint imm)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ if (imm < Imm12Limit)
+ {
+ Operand rmOperand = new(OperandKind.Constant, OperandType.I32, imm);
+
+ action(rnOperand, rmOperand);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, imm);
+
+ action(rnOperand, tempRegister.Operand);
+ }
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitCompareR(
+ CodeGenContext context,
+ Action action,
+ uint rn,
+ uint rm,
+ uint sType,
+ uint imm5)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (CanShiftArithmetic(sType, imm5))
+ {
+ action(rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType);
+
+ action(rnOperand, rmOperand, ArmShiftType.Lsl, 0);
+ }
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitCompareRr(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint rs)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType);
+
+ action(rnOperand, rmOperand);
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitI(CodeGenContext context, Action action, uint rd, uint rn, uint imm, bool s, bool reverse = false)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, imm);
+
+ if (reverse)
+ {
+ action(rdOperand, tempRegister.Operand, rnOperand);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, tempRegister.Operand);
+ }
+
+ if (s)
+ {
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitR(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s, bool reverse = false)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType);
+
+ if (reverse)
+ {
+ action(rdOperand, rmOperand, rnOperand);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, rmOperand);
+ }
+
+ if (s)
+ {
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitRr(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint rs, bool s, bool reverse = false)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType);
+
+ if (reverse)
+ {
+ action(rdOperand, rmOperand, rnOperand);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, rmOperand);
+ }
+
+ if (s)
+ {
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitLogicalI(CodeGenContext context, Action action, uint rn, uint imm, bool immRotated)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ if (immRotated)
+ {
+ if ((imm & (1u << 31)) != 0)
+ {
+ context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2));
+ }
+ else
+ {
+ context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1);
+ }
+ }
+
+ if (CodeGenCommon.TryEncodeBitMask(OperandType.I32, imm, out _, out _, out _))
+ {
+ action(rnOperand, InstEmitCommon.Const((int)imm));
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, imm);
+
+ action(rnOperand, tempRegister.Operand);
+ }
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitLogicalI(
+ CodeGenContext context,
+ Action action,
+ uint rd,
+ uint rn,
+ uint imm,
+ bool immRotated,
+ bool s,
+ bool immForm = true)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ ScopedRegister flagsRegister = default;
+
+ if (s)
+ {
+ flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ if (immRotated)
+ {
+ if ((imm & (1u << 31)) != 0)
+ {
+ context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2));
+ }
+ else
+ {
+ context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1);
+ }
+ }
+ }
+
+ if (imm == 0 || (immForm && CodeGenCommon.TryEncodeBitMask(OperandType.I32, imm, out _, out _, out _)))
+ {
+ action(rdOperand, rnOperand, InstEmitCommon.Const((int)imm));
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, imm);
+
+ action(rdOperand, rnOperand, tempRegister.Operand);
+ }
+
+ if (s)
+ {
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ flagsRegister.Dispose();
+
+ context.SetNzcvModified();
+ }
+ }
+
+ private static void EmitLogicalR(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint imm5)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand);
+
+ action(rnOperand, rmOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitLogicalR(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint imm5, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (CanShift(sType, imm5) && !s)
+ {
+ action(rdOperand, rnOperand, rmOperand, (ArmShiftType)sType, (int)imm5);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister flagsRegister = default;
+
+ if (s)
+ {
+ flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand);
+ }
+ else
+ {
+ rmOperand = GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null);
+ }
+
+ action(rdOperand, rnOperand, rmOperand, ArmShiftType.Lsl, 0);
+
+ if (s)
+ {
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ flagsRegister.Dispose();
+
+ context.SetNzcvModified();
+ }
+ }
+ }
+
+ private static void EmitLogicalRr(CodeGenContext context, Action action, uint rn, uint rm, uint sType, uint rs)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand);
+
+ action(rnOperand, rmOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+
+ private static void EmitLogicalRr(CodeGenContext context, Action action, uint rd, uint rn, uint rm, uint sType, uint rs, bool s)
+ {
+ if (s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand);
+
+ action(rdOperand, rnOperand, rmOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ EmitRr(context, action, rd, rn, rm, sType, rs, s);
+ }
+ }
+
+ public static bool CanShiftArithmetic(uint sType, uint imm5)
+ {
+ // We can't encode ROR or RRX.
+
+ return sType != 3 && (sType == 0 || imm5 != 0);
+ }
+
+ public static bool CanShift(uint sType, uint imm5)
+ {
+ // We can encode all shift types directly, except RRX.
+
+ return imm5 != 0 || sType == 0;
+ }
+
+ public static Operand GetMShiftedByImmediate(CodeGenContext context, Operand dest, Operand m, uint imm, uint sType, Operand? carryOut = null)
+ {
+ int shift = (int)imm;
+
+ if (shift == 0)
+ {
+ switch ((ArmShiftType)sType)
+ {
+ case ArmShiftType.Lsr:
+ shift = 32;
+ break;
+ case ArmShiftType.Asr:
+ shift = 32;
+ break;
+ case ArmShiftType.Ror:
+ shift = 1;
+ break;
+ }
+ }
+
+ if (shift != 0)
+ {
+ switch ((ArmShiftType)sType)
+ {
+ case ArmShiftType.Lsl:
+ m = GetLslC(context, dest, m, carryOut, shift);
+ break;
+ case ArmShiftType.Lsr:
+ m = GetLsrC(context, dest, m, carryOut, shift);
+ break;
+ case ArmShiftType.Asr:
+ m = GetAsrC(context, dest, m, carryOut, shift);
+ break;
+ case ArmShiftType.Ror:
+ if (imm != 0)
+ {
+ m = GetRorC(context, dest, m, carryOut, shift);
+ }
+ else
+ {
+ m = GetRrxC(context, dest, m, carryOut);
+ }
+ break;
+ }
+ }
+
+ return m;
+ }
+
+ public static Operand GetMShiftedByReg(CodeGenContext context, Operand dest, Operand m, Operand s, uint sType, Operand? carryOut = null)
+ {
+ Operand shiftResult = m;
+
+ switch ((ArmShiftType)sType)
+ {
+ case ArmShiftType.Lsl:
+ shiftResult = EmitLslC(context, dest, m, carryOut, s);
+ break;
+ case ArmShiftType.Lsr:
+ shiftResult = EmitLsrC(context, dest, m, carryOut, s);
+ break;
+ case ArmShiftType.Asr:
+ shiftResult = EmitAsrC(context, dest, m, carryOut, s);
+ break;
+ case ArmShiftType.Ror:
+ shiftResult = EmitRorC(context, dest, m, carryOut, s);
+ break;
+ }
+
+ return shiftResult;
+ }
+
+ private static void EmitIfHelper(CodeGenContext context, Operand boolValue, Action action, bool expected = true)
+ {
+ Debug.Assert(boolValue.Type == OperandType.I32);
+
+ int branchInstructionPointer = context.CodeWriter.InstructionPointer;
+
+ if (expected)
+ {
+ context.Arm64Assembler.Cbnz(boolValue, 0);
+ }
+ else
+ {
+ context.Arm64Assembler.Cbz(boolValue, 0);
+ }
+
+ action();
+
+ int offset = context.CodeWriter.InstructionPointer - branchInstructionPointer;
+ Debug.Assert(offset >= 0);
+ Debug.Assert((offset << 13) >> 13 == offset);
+ uint branchInst = context.CodeWriter.ReadInstructionAt(branchInstructionPointer);
+ context.CodeWriter.WriteInstructionAt(branchInstructionPointer, branchInst | (uint)(offset << 5));
+ }
+
+ private static Operand EmitLslC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand mask = tempRegister.Operand;
+ context.Arm64Assembler.Uxtb(mask, shift);
+ context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Asr(mask, mask, InstEmitCommon.Const(31));
+
+ Operand dest64 = new(OperandKind.Register, OperandType.I64, dest.Value);
+
+ if (carryOut.HasValue)
+ {
+ context.Arm64Assembler.Lslv(dest64, m, shift);
+ }
+ else
+ {
+ context.Arm64Assembler.Lslv(dest, m, shift);
+ }
+
+ // If shift >= 32, force the result to 0.
+ context.Arm64Assembler.And(dest, dest, mask);
+
+ if (carryOut.HasValue)
+ {
+ EmitIfHelper(context, shift, () =>
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Uxtb(mask, shift);
+ context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(33));
+ context.Arm64Assembler.Lsr(mask, mask, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Lsr(tempRegister.Operand, dest64, InstEmitCommon.Const(32));
+ context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, mask);
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value);
+ }, false);
+ }
+
+ return dest;
+ }
+
+ private static Operand GetLslC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ if ((uint)shift > 32)
+ {
+ return GetShiftByMoreThan32(context, carryOut);
+ }
+ else if (shift == 32)
+ {
+ if (carryOut.HasValue)
+ {
+ SetCarryMLsb(context, m, carryOut.Value);
+ }
+
+ return InstEmitCommon.Const(0);
+ }
+ else
+ {
+ if (carryOut.HasValue)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(32 - shift));
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value);
+ }
+
+ context.Arm64Assembler.Lsl(dest, m, InstEmitCommon.Const(shift));
+
+ return dest;
+ }
+ }
+
+ private static Operand EmitLsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand mask = tempRegister.Operand;
+ context.Arm64Assembler.Uxtb(mask, shift);
+ context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Asr(mask, mask, InstEmitCommon.Const(31));
+
+ context.Arm64Assembler.Lsrv(dest, m, shift);
+
+ // If shift >= 32, force the result to 0.
+ context.Arm64Assembler.And(dest, dest, mask);
+
+ if (carryOut.HasValue)
+ {
+ EmitIfHelper(context, shift, () =>
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Uxtb(mask, shift);
+ context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(33));
+ context.Arm64Assembler.Lsr(mask, mask, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Sub(tempRegister.Operand, shift, InstEmitCommon.Const(1));
+ context.Arm64Assembler.Lsrv(tempRegister.Operand, m, tempRegister.Operand);
+ context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, mask);
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value);
+ }, false);
+ }
+
+ return dest;
+ }
+
+ public static Operand GetLsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ if ((uint)shift > 32)
+ {
+ return GetShiftByMoreThan32(context, carryOut);
+ }
+ else if (shift == 32)
+ {
+ if (carryOut.HasValue)
+ {
+ SetCarryMMsb(context, m, carryOut.Value);
+ }
+
+ return InstEmitCommon.Const(0);
+ }
+ else
+ {
+ if (carryOut.HasValue)
+ {
+ SetCarryMShrOut(context, m, shift, carryOut.Value);
+ }
+
+ context.Arm64Assembler.Lsr(dest, m, InstEmitCommon.Const(shift));
+
+ return dest;
+ }
+ }
+
+ private static Operand GetShiftByMoreThan32(CodeGenContext context, Operand? carryOut)
+ {
+ if (carryOut.HasValue)
+ {
+ // Clear carry flag.
+
+ context.Arm64Assembler.Bfc(carryOut.Value, 1, 1);
+ }
+
+ return InstEmitCommon.Const(0);
+ }
+
+ private static Operand EmitAsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand mask = tempRegister.Operand;
+ context.Arm64Assembler.Uxtb(mask, shift);
+ context.Arm64Assembler.Sub(mask, mask, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Orn(mask, shift, mask, ArmShiftType.Asr, 31);
+
+ context.Arm64Assembler.Asrv(dest, m, mask);
+
+ if (carryOut.HasValue)
+ {
+ EmitIfHelper(context, shift, () =>
+ {
+ // If shift >= 32, carry should be equal to the MSB of Rm.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Sub(tempRegister.Operand, mask, InstEmitCommon.Const(1));
+ context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, mask, ArmShiftType.Asr, 31);
+ context.Arm64Assembler.Lsrv(tempRegister.Operand, m, tempRegister.Operand);
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut.Value);
+ }, false);
+ }
+
+ return dest;
+ }
+
+ private static Operand GetAsrC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ if ((uint)shift >= 32)
+ {
+ context.Arm64Assembler.Asr(dest, m, InstEmitCommon.Const(31));
+
+ if (carryOut.HasValue)
+ {
+ SetCarryMLsb(context, dest, carryOut.Value);
+ }
+
+ return dest;
+ }
+ else
+ {
+ if (carryOut.HasValue)
+ {
+ SetCarryMShrOut(context, m, shift, carryOut.Value);
+ }
+
+ context.Arm64Assembler.Asr(dest, m, InstEmitCommon.Const(shift));
+
+ return dest;
+ }
+ }
+
+ private static Operand EmitRorC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, Operand shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32);
+
+ context.Arm64Assembler.Rorv(dest, m, shift);
+
+ if (carryOut.HasValue)
+ {
+ EmitIfHelper(context, shift, () =>
+ {
+ SetCarryMMsb(context, m, carryOut.Value);
+ }, false);
+ }
+
+ return dest;
+ }
+
+ private static Operand GetRorC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut, int shift)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ shift &= 0x1f;
+
+ context.Arm64Assembler.Ror(dest, m, InstEmitCommon.Const(shift));
+
+ if (carryOut.HasValue)
+ {
+ SetCarryMMsb(context, dest, carryOut.Value);
+ }
+
+ return dest;
+ }
+
+ private static Operand GetRrxC(CodeGenContext context, Operand dest, Operand m, Operand? carryOut)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ // Rotate right by 1 with carry.
+
+ if (carryOut.HasValue)
+ {
+ SetCarryMLsb(context, m, carryOut.Value);
+ }
+
+ context.Arm64Assembler.Mov(dest, m);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.MrsNzcv(tempRegister.Operand);
+ context.Arm64Assembler.Bfxil(dest, tempRegister.Operand, 29, 1);
+ context.Arm64Assembler.Ror(dest, dest, InstEmitCommon.Const(1));
+
+ return dest;
+ }
+
+ private static void SetCarryMLsb(CodeGenContext context, Operand m, Operand carryOut)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ UpdateCarryFlag(context, m, carryOut);
+ }
+
+ private static void SetCarryMMsb(CodeGenContext context, Operand m, Operand carryOut)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(31));
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut);
+ }
+
+ private static void SetCarryMShrOut(CodeGenContext context, Operand m, int shift, Operand carryOut)
+ {
+ Debug.Assert(m.Type == OperandType.I32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, m, InstEmitCommon.Const(shift - 1));
+
+ UpdateCarryFlag(context, tempRegister.Operand, carryOut);
+ }
+
+ private static void UpdateCarryFlag(CodeGenContext context, Operand value, Operand carryOut)
+ {
+ context.Arm64Assembler.Bfi(carryOut, value, 1, 1);
+ }
+
+ private static void EmitTeq(CodeGenContext context, Operand rnOperand, Operand rmOperand)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Eors(tempRegister.Operand, rnOperand, rmOperand);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs
new file mode 100644
index 00000000..3f91d45f
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs
@@ -0,0 +1,103 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitBit
+ {
+ public static void Bfc(CodeGenContext context, uint rd, uint lsb, uint msb)
+ {
+ // This is documented as "unpredictable".
+ if (msb < lsb)
+ {
+ return;
+ }
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ context.Arm64Assembler.Bfc(rdOperand, (int)lsb, (int)(msb - lsb + 1));
+ }
+
+ public static void Bfi(CodeGenContext context, uint rd, uint rn, uint lsb, uint msb)
+ {
+ // This is documented as "unpredictable".
+ if (msb < lsb)
+ {
+ return;
+ }
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ context.Arm64Assembler.Bfi(rdOperand, rnOperand, (int)lsb, (int)(msb - lsb + 1));
+ }
+
+ public static void Clz(CodeGenContext context, uint rd, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Clz(rdOperand, rmOperand);
+ }
+
+ public static void Rbit(CodeGenContext context, uint rd, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Rbit(rdOperand, rmOperand);
+ }
+
+ public static void Rev(CodeGenContext context, uint rd, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Rev(rdOperand, rmOperand);
+ }
+
+ public static void Rev16(CodeGenContext context, uint rd, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Rev16(rdOperand, rmOperand);
+ }
+
+ public static void Revsh(CodeGenContext context, uint rd, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Rev16(rdOperand, rmOperand);
+ context.Arm64Assembler.Sxth(rdOperand, rdOperand);
+ }
+
+ public static void Sbfx(CodeGenContext context, uint rd, uint rn, uint lsb, uint widthMinus1)
+ {
+ // This is documented as "unpredictable".
+ if (lsb + widthMinus1 > 31)
+ {
+ return;
+ }
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ context.Arm64Assembler.Sbfx(rdOperand, rnOperand, (int)lsb, (int)widthMinus1 + 1);
+ }
+
+ public static void Ubfx(CodeGenContext context, uint rd, uint rn, uint lsb, uint widthMinus1)
+ {
+ // This is documented as "unpredictable".
+ if (lsb + widthMinus1 > 31)
+ {
+ return;
+ }
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ context.Arm64Assembler.Ubfx(rdOperand, rnOperand, (int)lsb, (int)widthMinus1 + 1);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs
new file mode 100644
index 00000000..1ec4c807
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs
@@ -0,0 +1,263 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitCommon
+ {
+ public static Operand Const(int value)
+ {
+ return new(OperandKind.Constant, OperandType.I32, (uint)value);
+ }
+
+ public static Operand GetInputGpr(CodeGenContext context, uint register)
+ {
+ Operand operand = context.RegisterAllocator.RemapGprRegister((int)register);
+
+ if (register == RegisterUtils.PcRegister)
+ {
+ context.Arm64Assembler.Mov(operand, context.Pc);
+ }
+
+ return operand;
+ }
+
+ public static Operand GetOutputGpr(CodeGenContext context, uint register)
+ {
+ return context.RegisterAllocator.RemapGprRegister((int)register);
+ }
+
+ public static void GetCurrentFlags(CodeGenContext context, Operand flagsOut)
+ {
+ context.Arm64Assembler.MrsNzcv(flagsOut);
+ context.Arm64Assembler.Lsr(flagsOut, flagsOut, Const(28));
+ }
+
+ public static void RestoreNzcvFlags(CodeGenContext context, Operand nzcvFlags)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsl(tempRegister.Operand, nzcvFlags, Const(28));
+ context.Arm64Assembler.MsrNzcv(tempRegister.Operand);
+ }
+
+ public static void RestoreCvFlags(CodeGenContext context, Operand cvFlags)
+ {
+ // Arm64 zeros the carry and overflow flags for logical operations, but Arm32 keeps them unchanged.
+ // This will restore carry and overflow after a operation has zeroed them.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.MrsNzcv(tempRegister.Operand);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, cvFlags, 28, 2);
+ context.Arm64Assembler.MsrNzcv(tempRegister.Operand);
+ }
+
+ public static void SetThumbFlag(CodeGenContext context)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, Const(1 << 5));
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public static void SetThumbFlag(CodeGenContext context, Operand value)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, value, 5, 1);
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public static void ClearThumbFlag(CodeGenContext context)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Bfc(tempRegister.Operand, 5, 1);
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public static void EmitSigned16BitPair(CodeGenContext context, uint rd, uint rn, Action elementAction)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+
+ context.Arm64Assembler.Sxth(tempN.Operand, rnOperand);
+ elementAction(tempD.Operand, tempN.Operand);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16));
+ elementAction(tempD.Operand, tempN.Operand);
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+
+ public static void EmitSigned16BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+ Operand rmOperand = GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Sxth(tempN.Operand, rnOperand);
+ context.Arm64Assembler.Sxth(tempM.Operand, rmOperand);
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16));
+ context.Arm64Assembler.Asr(tempM.Operand, rmOperand, Const(16));
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand);
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+
+ public static void EmitSigned16BitXPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+ Operand rmOperand = GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Sxth(tempN.Operand, rnOperand);
+ context.Arm64Assembler.Asr(tempM.Operand, rmOperand, Const(16));
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 0);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, Const(16));
+ context.Arm64Assembler.Sxth(tempM.Operand, rmOperand);
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 1);
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+
+ public static void EmitSigned8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: false);
+ }
+
+ public static void EmitUnsigned16BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+ Operand rmOperand = GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Uxth(tempN.Operand, rnOperand);
+ context.Arm64Assembler.Uxth(tempM.Operand, rmOperand);
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ context.Arm64Assembler.Lsr(tempN.Operand, rnOperand, Const(16));
+ context.Arm64Assembler.Lsr(tempM.Operand, rmOperand, Const(16));
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand);
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+
+ public static void EmitUnsigned16BitXPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+ Operand rmOperand = GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Uxth(tempN.Operand, rnOperand);
+ context.Arm64Assembler.Lsr(tempM.Operand, rmOperand, Const(16));
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 0);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ context.Arm64Assembler.Lsr(tempN.Operand, rnOperand, Const(16));
+ context.Arm64Assembler.Uxth(tempM.Operand, rmOperand);
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand, 1);
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+
+ public static void EmitUnsigned8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction)
+ {
+ Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: true);
+ }
+
+ private static void Emit8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action elementAction, bool unsigned)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = GetOutputGpr(context, rd);
+ Operand rnOperand = GetInputGpr(context, rn);
+ Operand rmOperand = GetInputGpr(context, rm);
+
+ for (int b = 0; b < 4; b++)
+ {
+ if (unsigned)
+ {
+ context.Arm64Assembler.Ubfx(tempN.Operand, rnOperand, b * 8, 8);
+ context.Arm64Assembler.Ubfx(tempM.Operand, rmOperand, b * 8, 8);
+ }
+ else
+ {
+ context.Arm64Assembler.Sbfx(tempN.Operand, rnOperand, b * 8, 8);
+ context.Arm64Assembler.Sbfx(tempM.Operand, rmOperand, b * 8, 8);
+ }
+
+ elementAction(tempD.Operand, tempN.Operand, tempM.Operand);
+
+ if (b == 0)
+ {
+ context.Arm64Assembler.Uxtb(tempD2.Operand, tempD.Operand);
+ }
+ else if (b < 3)
+ {
+ context.Arm64Assembler.Uxtb(tempD.Operand, tempD.Operand);
+ context.Arm64Assembler.Orr(tempD2.Operand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, b * 8);
+ }
+ else
+ {
+ context.Arm64Assembler.Orr(rdOperand, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 24);
+ }
+ }
+ }
+
+ public static uint CombineV(uint low4, uint high1, uint size)
+ {
+ return size == 3 ? CombineV(low4, high1) : CombineVF(high1, low4);
+ }
+
+ public static uint CombineV(uint low4, uint high1)
+ {
+ return low4 | (high1 << 4);
+ }
+
+ public static uint CombineVF(uint low1, uint high4)
+ {
+ return low1 | (high4 << 1);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs
new file mode 100644
index 00000000..ee634188
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs
@@ -0,0 +1,26 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitCrc32
+ {
+ public static void Crc32(CodeGenContext context, uint rd, uint rn, uint rm, uint sz)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Crc32(rdOperand, rnOperand, rmOperand, Math.Min(2, sz));
+ }
+
+ public static void Crc32c(CodeGenContext context, uint rd, uint rn, uint rm, uint sz)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Crc32c(rdOperand, rnOperand, rmOperand, Math.Min(2, sz));
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs
new file mode 100644
index 00000000..31c96dc8
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs
@@ -0,0 +1,25 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitDivide
+ {
+ public static void Sdiv(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Sdiv(rdOperand, rnOperand, rmOperand);
+ }
+
+ public static void Udiv(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Udiv(rdOperand, rnOperand, rmOperand);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs
new file mode 100644
index 00000000..dafe2974
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs
@@ -0,0 +1,191 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitExtension
+ {
+ public static void Sxtab(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitRotated(context, ArmExtensionType.Sxtb, rd, rn, rm, rotate);
+ }
+
+ public static void Sxtab16(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitExtendAccumulate8(context, rd, rn, rm, rotate, unsigned: false);
+ }
+
+ public static void Sxtah(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitRotated(context, ArmExtensionType.Sxth, rd, rn, rm, rotate);
+ }
+
+ public static void Sxtb(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ EmitRotated(context, context.Arm64Assembler.Sxtb, rd, rm, rotate);
+ }
+
+ public static void Sxtb16(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (rotate != 0)
+ {
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8));
+ context.Arm64Assembler.And(rdOperand, tempRegister.Operand, InstEmitCommon.Const(0xff00ff));
+ }
+ else
+ {
+ context.Arm64Assembler.And(rdOperand, rmOperand, InstEmitCommon.Const(0xff00ff));
+ }
+
+ // Sign-extend by broadcasting sign bits.
+ context.Arm64Assembler.And(tempRegister.Operand, rdOperand, InstEmitCommon.Const(0x800080));
+ context.Arm64Assembler.Lsl(tempRegister2.Operand, tempRegister.Operand, InstEmitCommon.Const(9));
+ context.Arm64Assembler.Sub(tempRegister.Operand, tempRegister2.Operand, tempRegister.Operand);
+ context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand);
+ }
+
+ public static void Sxth(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ EmitRotated(context, context.Arm64Assembler.Sxth, rd, rm, rotate);
+ }
+
+ public static void Uxtab(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitRotated(context, ArmExtensionType.Uxtb, rd, rn, rm, rotate);
+ }
+
+ public static void Uxtab16(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitExtendAccumulate8(context, rd, rn, rm, rotate, unsigned: true);
+ }
+
+ public static void Uxtah(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate)
+ {
+ EmitRotated(context, ArmExtensionType.Uxth, rd, rn, rm, rotate);
+ }
+
+ public static void Uxtb(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ EmitRotated(context, context.Arm64Assembler.Uxtb, rd, rm, rotate);
+ }
+
+ public static void Uxtb16(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (rotate != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8));
+ context.Arm64Assembler.And(rdOperand, tempRegister.Operand, InstEmitCommon.Const(0xff00ff));
+ }
+ else
+ {
+ context.Arm64Assembler.And(rdOperand, rmOperand, InstEmitCommon.Const(0xff00ff));
+ }
+ }
+
+ public static void Uxth(CodeGenContext context, uint rd, uint rm, uint rotate)
+ {
+ EmitRotated(context, context.Arm64Assembler.Uxth, rd, rm, rotate);
+ }
+
+ private static void EmitRotated(CodeGenContext context, Action action, uint rd, uint rm, uint rotate)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (rotate != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8));
+ action(rdOperand, tempRegister.Operand);
+ }
+ else
+ {
+ action(rdOperand, rmOperand);
+ }
+ }
+
+ private static void EmitRotated(CodeGenContext context, ArmExtensionType extensionType, uint rd, uint rn, uint rm, uint rotate)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (rotate != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8));
+ context.Arm64Assembler.Add(rdOperand, rnOperand, tempRegister.Operand, extensionType);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(rdOperand, rnOperand, rmOperand, extensionType);
+ }
+ }
+
+ private static void EmitExtendAccumulate8(CodeGenContext context, uint rd, uint rn, uint rm, uint rotate, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (rotate != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)rotate * 8));
+
+ EmitExtendAccumulate8Core(context, rdOperand, rnOperand, tempRegister.Operand, unsigned);
+ }
+ else
+ {
+ EmitExtendAccumulate8Core(context, rdOperand, rnOperand, rmOperand, unsigned);
+ }
+ }
+
+ private static void EmitExtendAccumulate8Core(CodeGenContext context, Operand rd, Operand rn, Operand rm, bool unsigned)
+ {
+ using ScopedRegister tempD = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempD2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (unsigned)
+ {
+ context.Arm64Assembler.Uxth(tempN.Operand, rn);
+ }
+ else
+ {
+ context.Arm64Assembler.Sxth(tempN.Operand, rn);
+ }
+
+ context.Arm64Assembler.Add(tempD.Operand, tempN.Operand, rm, unsigned ? ArmExtensionType.Uxtb : ArmExtensionType.Sxtb);
+ context.Arm64Assembler.Uxth(tempD2.Operand, tempD.Operand);
+
+ if (unsigned)
+ {
+ context.Arm64Assembler.Lsr(tempN.Operand, rn, InstEmitCommon.Const(16));
+ }
+ else
+ {
+ context.Arm64Assembler.Asr(tempN.Operand, rn, InstEmitCommon.Const(16));
+ }
+
+ context.Arm64Assembler.Lsr(tempD.Operand, rm, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Add(tempD.Operand, tempN.Operand, tempD.Operand, unsigned ? ArmExtensionType.Uxtb : ArmExtensionType.Sxtb);
+ context.Arm64Assembler.Orr(rd, tempD2.Operand, tempD.Operand, ArmShiftType.Lsl, 16);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
new file mode 100644
index 00000000..81e44ba0
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
@@ -0,0 +1,256 @@
+using ARMeilleure.Common;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitFlow
+ {
+ private const int SpIndex = 31;
+
+ public static void B(CodeGenContext context, int imm, ArmCondition condition)
+ {
+ context.AddPendingBranch(InstName.B, imm);
+
+ if (condition == ArmCondition.Al)
+ {
+ context.Arm64Assembler.B(0);
+ }
+ else
+ {
+ context.Arm64Assembler.B(condition, 0);
+ }
+ }
+
+ public static void Bl(CodeGenContext context, int imm, bool sourceIsThumb, bool targetIsThumb)
+ {
+ uint nextAddress = sourceIsThumb ? context.Pc | 1u : context.Pc - 4;
+ uint targetAddress = targetIsThumb ? context.Pc + (uint)imm : (context.Pc & ~3u) + (uint)imm;
+
+ if (sourceIsThumb != targetIsThumb)
+ {
+ if (targetIsThumb)
+ {
+ InstEmitCommon.SetThumbFlag(context);
+ }
+ else
+ {
+ InstEmitCommon.ClearThumbFlag(context);
+ }
+ }
+
+ context.AddPendingCall(targetAddress, nextAddress);
+
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void Blx(CodeGenContext context, uint rm, bool sourceIsThumb)
+ {
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ InstEmitCommon.SetThumbFlag(context, rmOperand);
+
+ uint nextAddress = sourceIsThumb ? (context.Pc - 2) | 1u : context.Pc - 4;
+
+ context.AddPendingIndirectCall(rm, nextAddress);
+
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void Bx(CodeGenContext context, uint rm)
+ {
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ InstEmitCommon.SetThumbFlag(context, rmOperand);
+
+ context.AddPendingIndirectBranch(InstName.Bx, rm);
+
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void Cbnz(CodeGenContext context, uint rn, int imm, bool op)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ context.AddPendingBranch(InstName.Cbnz, imm);
+
+ if (op)
+ {
+ context.Arm64Assembler.Cbnz(rnOperand, 0);
+ }
+ else
+ {
+ context.Arm64Assembler.Cbz(rnOperand, 0);
+ }
+ }
+
+ public static void It(CodeGenContext context, uint firstCond, uint mask)
+ {
+ Debug.Assert(mask != 0);
+
+ int instCount = 4 - BitOperations.TrailingZeroCount(mask);
+
+ Span conditions = stackalloc ArmCondition[instCount];
+
+ int i = 0;
+
+ for (int index = 5 - instCount; index < 4; index++)
+ {
+ bool invert = (mask & (1u << index)) != 0;
+
+ if (invert)
+ {
+ conditions[i++] = ((ArmCondition)firstCond).Invert();
+ }
+ else
+ {
+ conditions[i++] = (ArmCondition)firstCond;
+ }
+ }
+
+ conditions[i] = (ArmCondition)firstCond;
+
+ context.SetItBlockStart(conditions);
+ }
+
+ public static void Tbb(CodeGenContext context, uint rn, uint rm, bool h)
+ {
+ context.Arm64Assembler.Mov(context.RegisterAllocator.RemapGprRegister(RegisterUtils.PcRegister), context.Pc);
+
+ context.AddPendingTableBranch(rn, rm, h);
+
+ context.Arm64Assembler.B(0);
+ }
+
+ public unsafe static void WriteCallWithGuestAddress(
+ CodeWriter writer,
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ TailMerger tailMerger,
+ Action writeEpilogue,
+ AddressTable funcTable,
+ IntPtr funcPtr,
+ int spillBaseOffset,
+ uint nextAddress,
+ Operand guestAddress,
+ bool isTail = false)
+ {
+ int tempRegister;
+
+ if (guestAddress.Kind == OperandKind.Constant)
+ {
+ tempRegister = regAlloc.AllocateTempGprRegister();
+
+ asm.Mov(Register(tempRegister), guestAddress.Value);
+ asm.StrRiUn(Register(tempRegister), Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+ else
+ {
+ asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+ }
+
+ tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
+
+ if (!isTail)
+ {
+ WriteSpillSkipContext(ref asm, regAlloc, spillBaseOffset);
+ }
+
+ Operand rn = Register(tempRegister);
+
+ if (regAlloc.FixedContextRegister != 0)
+ {
+ asm.Mov(Register(0), Register(regAlloc.FixedContextRegister));
+ }
+
+ if (guestAddress.Kind == OperandKind.Constant && funcTable != null)
+ {
+ ulong funcPtrLoc = (ulong)Unsafe.AsPointer(ref funcTable.GetValue(guestAddress.Value));
+
+ asm.Mov(rn, funcPtrLoc & ~0xfffUL);
+ asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL));
+ }
+ else
+ {
+ asm.Mov(rn, (ulong)funcPtr);
+ }
+
+ if (isTail)
+ {
+ writeEpilogue();
+ asm.Br(rn);
+ }
+ else
+ {
+ asm.Blr(rn);
+
+ asm.Mov(rn, nextAddress);
+ asm.Cmp(Register(0), rn);
+
+ tailMerger.AddConditionalReturn(writer, asm, ArmCondition.Ne);
+
+ WriteFillSkipContext(ref asm, regAlloc, spillBaseOffset);
+ }
+ }
+
+ private static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
+ {
+ WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true);
+ }
+
+ private static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
+ {
+ WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false);
+ }
+
+ private static void WriteSpillOrFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset, bool spill)
+ {
+ uint gprMask = regAlloc.UsedGprsMask & ((1u << regAlloc.FixedContextRegister) | (1u << regAlloc.FixedPageTableRegister));
+
+ while (gprMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(gprMask);
+
+ if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(3u << reg);
+ spillOffset += 16;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(reg), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(reg), Register(SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(1u << reg);
+ spillOffset += 8;
+ }
+ }
+ }
+
+ private static Operand Register(int register, OperandType type = OperandType.I64)
+ {
+ return new Operand(register, RegisterType.Integer, type);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs
new file mode 100644
index 00000000..dffcc511
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs
@@ -0,0 +1,265 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitGE
+ {
+ public static void Sadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: true, add: true, unsigned: false);
+ }
+
+ public static void Sadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: false, add: true, unsigned: false);
+ }
+
+ public static void Sasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAsxSax(context, rd, rn, rm, isAsx: true, unsigned: false);
+ }
+
+ public static void Sel(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ ExtractGEFlags(context, geFlags.Operand);
+
+ // Broadcast compact GE flags (one bit to one byte, 0b1111 -> 0x1010101).
+ context.Arm64Assembler.Mov(tempRegister.Operand, 0x204081u);
+ context.Arm64Assembler.Mul(geFlags.Operand, geFlags.Operand, tempRegister.Operand);
+ context.Arm64Assembler.And(geFlags.Operand, geFlags.Operand, InstEmitCommon.Const(0x1010101));
+
+ // Build mask from expanded flags (0x1010101 -> 0xFFFFFFFF).
+ context.Arm64Assembler.Lsl(tempRegister.Operand, geFlags.Operand, InstEmitCommon.Const(8));
+ context.Arm64Assembler.Sub(geFlags.Operand, tempRegister.Operand, geFlags.Operand);
+
+ // Result = (n & mask) | (m & ~mask).
+ context.Arm64Assembler.And(tempRegister.Operand, geFlags.Operand, rnOperand);
+ context.Arm64Assembler.Bic(rdOperand, rmOperand, geFlags.Operand);
+ context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand);
+ }
+
+ public static void Ssax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAsxSax(context, rd, rn, rm, isAsx: false, unsigned: false);
+ }
+
+ public static void Ssub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: true, add: false, unsigned: false);
+ }
+
+ public static void Ssub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: false, add: false, unsigned: false);
+ }
+
+ public static void Uadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: true, add: true, unsigned: true);
+ }
+
+ public static void Uadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: false, add: true, unsigned: true);
+ }
+
+ public static void Uasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAsxSax(context, rd, rn, rm, isAsx: true, unsigned: true);
+ }
+
+ public static void Usax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAsxSax(context, rd, rn, rm, isAsx: false, unsigned: true);
+ }
+
+ public static void Usub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: true, add: false, unsigned: true);
+ }
+
+ public static void Usub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSub(context, rd, rn, rm, is16Bit: false, add: false, unsigned: true);
+ }
+
+ private static void EmitAddSub(CodeGenContext context, uint rd, uint rn, uint rm, bool is16Bit, bool add, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ int e = 0;
+
+ void Emit(Operand d, Operand n, Operand m)
+ {
+ if (add)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ if (unsigned && add)
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Lsr(geFlags.Operand, d, InstEmitCommon.Const(is16Bit ? 16 : 8));
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, d, InstEmitCommon.Const(is16Bit ? 16 : 8));
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e);
+ }
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mvn(tempRegister.Operand, d);
+
+ if (e == 0)
+ {
+ context.Arm64Assembler.Lsr(geFlags.Operand, tempRegister.Operand, InstEmitCommon.Const(31));
+ }
+ else
+ {
+ context.Arm64Assembler.Lsr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e);
+ }
+ }
+
+ e += is16Bit ? 2 : 1;
+ }
+
+ if (is16Bit)
+ {
+ if (unsigned)
+ {
+ InstEmitCommon.EmitUnsigned16BitPair(context, rd, rn, rm, Emit);
+ }
+ else
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, Emit);
+ }
+
+ // Duplicate bits.
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, geFlags.Operand, ArmShiftType.Lsl, 1);
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitCommon.EmitUnsigned8BitPair(context, rd, rn, rm, Emit);
+ }
+ else
+ {
+ InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, Emit);
+ }
+ }
+
+ UpdateGEFlags(context, geFlags.Operand);
+ }
+
+ private static void EmitAsxSax(CodeGenContext context, uint rd, uint rn, uint rm, bool isAsx, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister geFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ void Emit(Operand d, Operand n, Operand m, int e)
+ {
+ bool add = e == (isAsx ? 1 : 0);
+
+ if (add)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ if (unsigned && add)
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Lsr(geFlags.Operand, d, InstEmitCommon.Const(16));
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, d, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e * 2);
+ }
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mvn(tempRegister.Operand, d);
+
+ if (e == 0)
+ {
+ context.Arm64Assembler.Lsr(geFlags.Operand, tempRegister.Operand, InstEmitCommon.Const(31));
+ }
+ else
+ {
+ context.Arm64Assembler.Lsr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, tempRegister.Operand, ArmShiftType.Lsl, e * 2);
+ }
+ }
+ }
+
+ if (unsigned)
+ {
+ InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, Emit);
+ }
+ else
+ {
+ InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, Emit);
+ }
+
+ // Duplicate bits.
+ context.Arm64Assembler.Orr(geFlags.Operand, geFlags.Operand, geFlags.Operand, ArmShiftType.Lsl, 1);
+
+ UpdateGEFlags(context, geFlags.Operand);
+ }
+
+ public static void UpdateGEFlags(CodeGenContext context, Operand flags)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, flags, 16, 4);
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public static void ExtractGEFlags(CodeGenContext context, Operand flags)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ context.Arm64Assembler.LdrRiUn(flags, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Ubfx(flags, flags, 16, 4);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs
new file mode 100644
index 00000000..567acfbf
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs
@@ -0,0 +1,178 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitHalve
+ {
+ public static void Shadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHadd(context, rd, rn, rm, 0x7fff7fff, unsigned: false);
+ }
+
+ public static void Shadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHadd(context, rd, rn, rm, 0x7f7f7f7f, unsigned: false);
+ }
+
+ public static void Shsub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHsub(context, rd, rn, rm, 0x7fff7fff, unsigned: false);
+ }
+
+ public static void Shsub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHsub(context, rd, rn, rm, 0x7f7f7f7f, unsigned: false);
+ }
+
+ public static void Shasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+
+ context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1));
+ });
+ }
+
+ public static void Shsax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1));
+ });
+ }
+
+ public static void Uhadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHadd(context, rd, rn, rm, 0x7fff7fff, unsigned: true);
+ }
+
+ public static void Uhadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHadd(context, rd, rn, rm, 0x7f7f7f7f, unsigned: true);
+ }
+
+ public static void Uhasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+
+ context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1));
+ });
+ }
+
+ public static void Uhsax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ context.Arm64Assembler.Lsr(d, d, InstEmitCommon.Const(1));
+ });
+ }
+
+ public static void Uhsub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHsub(context, rd, rn, rm, 0x7fff7fff, unsigned: true);
+ }
+
+ public static void Uhsub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitHsub(context, rd, rn, rm, 0x7f7f7f7f, unsigned: true);
+ }
+
+ private static void EmitHadd(CodeGenContext context, uint rd, uint rn, uint rm, int mask, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister res = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister carry = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ // This relies on the equality x+y == ((x&y) << 1) + (x^y).
+ // Note that x^y always contains the LSB of the result.
+ // Since we want to calculate (x+y)/2, we can instead calculate (x&y) + ((x^y)>>1).
+ // We mask by 0x7F/0x7FFF to remove the LSB so that it doesn't leak into the field below.
+
+ context.Arm64Assembler.And(res.Operand, rmOperand, rnOperand);
+ context.Arm64Assembler.Eor(carry.Operand, rmOperand, rnOperand);
+ context.Arm64Assembler.Lsr(rdOperand, carry.Operand, InstEmitCommon.Const(1));
+ context.Arm64Assembler.And(rdOperand, rdOperand, InstEmitCommon.Const(mask));
+ context.Arm64Assembler.Add(rdOperand, rdOperand, res.Operand);
+
+ if (!unsigned)
+ {
+ // Propagates the sign bit from (x^y)>>1 upwards by one.
+ context.Arm64Assembler.And(carry.Operand, carry.Operand, InstEmitCommon.Const(~mask));
+ context.Arm64Assembler.Eor(rdOperand, rdOperand, carry.Operand);
+ }
+ }
+
+ private static void EmitHsub(CodeGenContext context, uint rd, uint rn, uint rm, int mask, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister carry = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister left = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister right = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ // This relies on the equality x-y == (x^y) - (((x^y)&y) << 1).
+ // Note that x^y always contains the LSB of the result.
+ // Since we want to calculate (x+y)/2, we can instead calculate ((x^y)>>1) - ((x^y)&y).
+
+ context.Arm64Assembler.Eor(carry.Operand, rmOperand, rnOperand);
+ context.Arm64Assembler.Lsr(left.Operand, carry.Operand, InstEmitCommon.Const(1));
+ context.Arm64Assembler.And(right.Operand, carry.Operand, rmOperand);
+
+ // We must now perform a partitioned subtraction.
+ // We can do this because minuend contains 7/15 bit fields.
+ // We use the extra bit in minuend as a bit to borrow from; we set this bit.
+ // We invert this bit at the end as this tells us if that bit was borrowed from.
+
+ context.Arm64Assembler.Orr(rdOperand, left.Operand, InstEmitCommon.Const(~mask));
+ context.Arm64Assembler.Sub(rdOperand, rdOperand, right.Operand);
+ context.Arm64Assembler.Eor(rdOperand, rdOperand, InstEmitCommon.Const(~mask));
+
+ if (!unsigned)
+ {
+ // We then sign extend the result into this bit.
+ context.Arm64Assembler.And(carry.Operand, carry.Operand, InstEmitCommon.Const(~mask));
+ context.Arm64Assembler.Eor(rdOperand, rdOperand, carry.Operand);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
new file mode 100644
index 00000000..6ab4b949
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
@@ -0,0 +1,1172 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitMemory
+ {
+ private enum PrefetchType : uint
+ {
+ Pld = 0,
+ Pli = 1,
+ Pst = 2,
+ }
+
+ public static void Lda(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldar);
+ }
+
+ public static void Ldab(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldarb);
+ }
+
+ public static void Ldaex(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxr);
+ }
+
+ public static void Ldaexb(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrb);
+ }
+
+ public static void Ldaexd(CodeGenContext context, uint rt, uint rt2, uint rn)
+ {
+ EmitMemoryDWordInstruction(context, rt, rt2, rn, isStore: false, context.Arm64Assembler.Ldaxp);
+ }
+
+ public static void Ldaexh(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrh);
+ }
+
+ public static void Ldah(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldarh);
+ }
+
+ public static void LdcI(CodeGenContext context, uint rn, int imm, bool p, bool u, bool w)
+ {
+ // TODO.
+ }
+
+ public static void LdcL(CodeGenContext context, uint imm, bool p, bool u, bool w)
+ {
+ // TODO.
+ }
+
+ public static void Ldm(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
+
+ EmitMemoryMultipleInstructionCore(
+ context,
+ tempRegister.Operand,
+ registerList,
+ isStore: false,
+ context.Arm64Assembler.LdrRiUn,
+ context.Arm64Assembler.LdpRiUn);
+
+ if (w)
+ {
+ Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0);
+ }
+ }
+
+ public static void Ldmda(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleDaInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void Ldmdb(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleDbInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void Ldmib(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleIbInstruction(context, rn, registerList, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void LdrI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 2, p, u, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur);
+ }
+
+ public static void LdrL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryLiteralInstruction(context, rt, imm, 2, p, u, w, context.Arm64Assembler.LdrRiUn);
+ }
+
+ public static void LdrR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur);
+ }
+
+ public static void LdrbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb);
+ }
+
+ public static void LdrbL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryLiteralInstruction(context, rt, imm, 0, p, u, w, context.Arm64Assembler.LdrbRiUn);
+ }
+
+ public static void LdrbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb);
+ }
+
+ public static void LdrbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb);
+ }
+
+ public static void LdrbtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrbRiUn, context.Arm64Assembler.Ldurb);
+ }
+
+ public static void LdrdI(CodeGenContext context, uint rt, uint rt2, uint rn, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryDWordInstructionI(context, rt, rt2, rn, imm, p, u, w, isStore: false, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void LdrdL(CodeGenContext context, uint rt, uint rt2, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryDWordLiteralInstruction(context, rt, rt2, imm, p, u, w, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void LdrdR(CodeGenContext context, uint rt, uint rt2, uint rn, uint rm, bool p, bool u, bool w)
+ {
+ EmitMemoryDWordInstructionR(context, rt, rt2, rn, rm, p, u, w, isStore: false, context.Arm64Assembler.LdpRiUn);
+ }
+
+ public static void Ldrex(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxr);
+ }
+
+ public static void Ldrexb(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrb);
+ }
+
+ public static void Ldrexd(CodeGenContext context, uint rt, uint rt2, uint rn)
+ {
+ EmitMemoryDWordInstruction(context, rt, rt2, rn, isStore: false, context.Arm64Assembler.Ldaxp);
+ }
+
+ public static void Ldrexh(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: false, context.Arm64Assembler.Ldaxrh);
+ }
+
+ public static void LdrhI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh);
+ }
+
+ public static void LdrhL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryLiteralInstruction(context, rt, imm, 1, p, u, w, context.Arm64Assembler.LdrhRiUn);
+ }
+
+ public static void LdrhR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh);
+ }
+
+ public static void LdrhtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh);
+ }
+
+ public static void LdrhtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrhRiUn, context.Arm64Assembler.Ldurh);
+ }
+
+ public static void LdrsbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb);
+ }
+
+ public static void LdrsbL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryLiteralInstruction(context, rt, imm, 0, p, u, w, context.Arm64Assembler.LdrsbRiUn);
+ }
+
+ public static void LdrsbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb);
+ }
+
+ public static void LdrsbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb);
+ }
+
+ public static void LdrsbtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrsbRiUn, context.Arm64Assembler.Ldursb);
+ }
+
+ public static void LdrshI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh);
+ }
+
+ public static void LdrshL(CodeGenContext context, uint rt, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryLiteralInstruction(context, rt, imm, 1, p, u, w, context.Arm64Assembler.LdrshRiUn);
+ }
+
+ public static void LdrshR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh);
+ }
+
+ public static void LdrshtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh);
+ }
+
+ public static void LdrshtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrshRiUn, context.Arm64Assembler.Ldursh);
+ }
+
+ public static void LdrtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 2, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur);
+ }
+
+ public static void LdrtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: false, context.Arm64Assembler.LdrRiUn, context.Arm64Assembler.Ldur);
+ }
+
+ public static void PldI(CodeGenContext context, uint rn, uint imm, bool u, bool r)
+ {
+ EmitMemoryPrefetchInstruction(context, rn, imm, u, r ? PrefetchType.Pld : PrefetchType.Pst);
+ }
+
+ public static void PldL(CodeGenContext context, uint imm, bool u)
+ {
+ EmitMemoryPrefetchLiteralInstruction(context, imm, u, PrefetchType.Pld);
+ }
+
+ public static void PldR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5, bool u, bool r)
+ {
+ EmitMemoryPrefetchInstruction(context, rn, rm, u, sType, imm5, r ? PrefetchType.Pld : PrefetchType.Pst);
+ }
+
+ public static void PliI(CodeGenContext context, uint rn, uint imm, bool u)
+ {
+ EmitMemoryPrefetchInstruction(context, rn, imm, u, PrefetchType.Pli);
+ }
+
+ public static void PliL(CodeGenContext context, uint imm, bool u)
+ {
+ EmitMemoryPrefetchLiteralInstruction(context, imm, u, PrefetchType.Pli);
+ }
+
+ public static void PliR(CodeGenContext context, uint rn, uint rm, uint sType, uint imm5, bool u)
+ {
+ EmitMemoryPrefetchInstruction(context, rn, rm, u, sType, imm5, PrefetchType.Pli);
+ }
+
+ public static void Stc(CodeGenContext context, uint rn, int imm, bool p, bool u, bool w)
+ {
+ // TODO.
+ }
+
+ public static void Stl(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlr);
+ }
+
+ public static void Stlb(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlrb);
+ }
+
+ public static void Stlex(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxr);
+ }
+
+ public static void Stlexb(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrb);
+ }
+
+ public static void Stlexd(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn)
+ {
+ EmitMemoryDWordStrexInstruction(context, rd, rt, rt2, rn, context.Arm64Assembler.Stlxp);
+ }
+
+ public static void Stlexh(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrh);
+ }
+
+ public static void Stlh(CodeGenContext context, uint rt, uint rn)
+ {
+ EmitMemoryInstruction(context, rt, rn, isStore: true, context.Arm64Assembler.Stlrh);
+ }
+
+ public static void Stm(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
+
+ EmitMemoryMultipleInstructionCore(
+ context,
+ tempRegister.Operand,
+ registerList,
+ isStore: true,
+ context.Arm64Assembler.StrRiUn,
+ context.Arm64Assembler.StpRiUn);
+
+ if (w)
+ {
+ Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0);
+ }
+ }
+
+ public static void Stmda(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleDaInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn);
+ }
+
+ public static void Stmdb(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleDbInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn);
+ }
+
+ public static void Stmib(CodeGenContext context, uint rn, uint registerList, bool w)
+ {
+ EmitMemoryMultipleIbInstruction(context, rn, registerList, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.StpRiUn);
+ }
+
+ public static void StrI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 2, p, u, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur);
+ }
+
+ public static void StrR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur);
+ }
+
+ public static void StrbI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, p, u, w, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb);
+ }
+
+ public static void StrbR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb);
+ }
+
+ public static void StrbtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 0, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb);
+ }
+
+ public static void StrbtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrbRiUn, context.Arm64Assembler.Sturb);
+ }
+
+ public static void StrdI(CodeGenContext context, uint rt, uint rt2, uint rn, uint imm, bool p, bool u, bool w)
+ {
+ EmitMemoryDWordInstructionI(context, rt, rt2, rn, imm, p, u, w, isStore: true, context.Arm64Assembler.StpRiUn);
+ }
+
+ public static void StrdR(CodeGenContext context, uint rt, uint rt2, uint rn, uint rm, bool p, bool u, bool w)
+ {
+ EmitMemoryDWordInstructionR(context, rt, rt2, rn, rm, p, u, w, isStore: true, context.Arm64Assembler.StpRiUn);
+ }
+
+ public static void Strex(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxr);
+ }
+
+ public static void Strexb(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrb);
+ }
+
+ public static void Strexd(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn)
+ {
+ EmitMemoryDWordStrexInstruction(context, rd, rt, rt2, rn, context.Arm64Assembler.Stlxp);
+ }
+
+ public static void Strexh(CodeGenContext context, uint rd, uint rt, uint rn)
+ {
+ EmitMemoryStrexInstruction(context, rd, rt, rn, context.Arm64Assembler.Stlxrh);
+ }
+
+ public static void StrhI(CodeGenContext context, uint rt, uint rn, int imm, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, p, u, w, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh);
+ }
+
+ public static void StrhR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool p, bool u, bool w)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, p, u, w, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh);
+ }
+
+ public static void StrhtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 1, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh);
+ }
+
+ public static void StrhtR(CodeGenContext context, uint rt, uint rn, uint rm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, 0, 0, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrhRiUn, context.Arm64Assembler.Sturh);
+ }
+
+ public static void StrtI(CodeGenContext context, uint rt, uint rn, int imm, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, imm, 2, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur);
+ }
+
+ public static void StrtR(CodeGenContext context, uint rt, uint rn, uint rm, uint sType, uint imm5, bool postIndex, bool u)
+ {
+ EmitMemoryInstruction(context, rt, rn, rm, sType, imm5, !postIndex, u, false, isStore: true, context.Arm64Assembler.StrRiUn, context.Arm64Assembler.Stur);
+ }
+
+ private static void EmitMemoryMultipleDaInstruction(
+ CodeGenContext context,
+ uint rn,
+ uint registerList,
+ bool w,
+ bool isStore,
+ Action writeInst,
+ Action writeInstPair)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+ Operand offset;
+
+ if (registerList != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4 - 4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+
+ EmitMemoryMultipleInstructionCore(
+ context,
+ tempRegister.Operand,
+ registerList,
+ isStore,
+ writeInst,
+ writeInstPair);
+ }
+
+ if (w)
+ {
+ offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ }
+ }
+
+ private static void EmitMemoryMultipleDbInstruction(
+ CodeGenContext context,
+ uint rn,
+ uint registerList,
+ bool w,
+ bool isStore,
+ Action writeInst,
+ Action writeInstPair)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4);
+
+ bool writesToRn = (registerList & (1u << (int)rn)) != 0;
+
+ if (w && !writesToRn)
+ {
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
+ }
+ else
+ {
+ WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+ }
+
+ EmitMemoryMultipleInstructionCore(
+ context,
+ tempRegister.Operand,
+ registerList,
+ isStore,
+ writeInst,
+ writeInstPair);
+
+ if (w && writesToRn)
+ {
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ }
+ }
+
+ private static void EmitMemoryMultipleIbInstruction(
+ CodeGenContext context,
+ uint rn,
+ uint registerList,
+ bool w,
+ bool isStore,
+ Action writeInst,
+ Action writeInstPair)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand offset = InstEmitCommon.Const(4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, true, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+
+ EmitMemoryMultipleInstructionCore(
+ context,
+ tempRegister.Operand,
+ registerList,
+ isStore,
+ writeInst,
+ writeInstPair);
+
+ if (w)
+ {
+ offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4);
+
+ WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, true, ArmShiftType.Lsl, 0);
+ }
+ }
+
+ private static void EmitMemoryMultipleInstructionCore(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint registerList,
+ bool isStore,
+ Action writeInst,
+ Action writeInstPair)
+ {
+ uint registers = registerList;
+ int offs = 0;
+
+ while (registers != 0)
+ {
+ int regIndex = BitOperations.TrailingZeroCount(registers);
+
+ registers &= ~(1u << regIndex);
+
+ Operand rt = isStore
+ ? InstEmitCommon.GetInputGpr(context, (uint)regIndex)
+ : InstEmitCommon.GetOutputGpr(context, (uint)regIndex);
+
+ int regIndex2 = BitOperations.TrailingZeroCount(registers);
+ if (regIndex2 < 32)
+ {
+ registers &= ~(1u << regIndex2);
+
+ Operand rt2 = isStore
+ ? InstEmitCommon.GetInputGpr(context, (uint)regIndex2)
+ : InstEmitCommon.GetOutputGpr(context, (uint)regIndex2);
+
+ writeInstPair(rt, rt2, baseAddress, offs);
+
+ offs += 8;
+ }
+ else
+ {
+ writeInst(rt, baseAddress, offs);
+
+ offs += 4;
+ }
+ }
+ }
+
+ private static void EmitMemoryInstruction(
+ CodeGenContext context,
+ uint rt,
+ uint rn,
+ int imm,
+ int scale,
+ bool p,
+ bool u,
+ bool w,
+ bool isStore,
+ Action writeInst,
+ Action writeInstUnscaled)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand offset = InstEmitCommon.Const(imm);
+
+ EmitMemoryInstruction(context, writeInst, writeInstUnscaled, rtOperand, rnOperand, offset, scale, p, u, w);
+ }
+
+ private static void EmitMemoryInstruction(
+ CodeGenContext context,
+ uint rt,
+ uint rn,
+ uint rm,
+ uint sType,
+ uint imm5,
+ bool p,
+ bool u,
+ bool w,
+ bool isStore,
+ Action writeInst,
+ Action writeInstUnscaled)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ EmitMemoryInstruction(context, writeInst, writeInstUnscaled, rtOperand, rnOperand, rmOperand, 0, p, u, w, (ArmShiftType)sType, (int)imm5);
+ }
+
+ private static void EmitMemoryInstruction(CodeGenContext context, uint rt, uint rn, bool isStore, Action action)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+
+ action(rtOperand, tempRegister.Operand);
+ }
+
+ private static void EmitMemoryDWordInstruction(CodeGenContext context, uint rt, uint rt2, uint rn, bool isStore, Action action)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+
+ action(rtOperand, rt2Operand, tempRegister.Operand);
+ }
+
+ private static void EmitMemoryDWordInstructionI(
+ CodeGenContext context,
+ uint rt,
+ uint rt2,
+ uint rn,
+ uint imm,
+ bool p,
+ bool u,
+ bool w,
+ bool isStore,
+ Action action)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand offset = InstEmitCommon.Const((int)imm);
+
+ EmitMemoryDWordInstruction(context, rtOperand, rt2Operand, rnOperand, offset, p, u, w, action);
+ }
+
+ private static void EmitMemoryDWordInstructionR(
+ CodeGenContext context,
+ uint rt,
+ uint rt2,
+ uint rn,
+ uint rm,
+ bool p,
+ bool u,
+ bool w,
+ bool isStore,
+ Action action)
+ {
+ Operand rtOperand = isStore ? InstEmitCommon.GetInputGpr(context, rt) : InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = isStore ? InstEmitCommon.GetInputGpr(context, rt2) : InstEmitCommon.GetOutputGpr(context, rt2);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ EmitMemoryDWordInstruction(context, rtOperand, rt2Operand, rnOperand, rmOperand, p, u, w, action);
+ }
+
+ private static void EmitMemoryDWordInstruction(
+ CodeGenContext context,
+ Operand rt,
+ Operand rt2,
+ Operand baseAddress,
+ Operand offset,
+ bool index,
+ bool add,
+ bool wBack,
+ Action action)
+ {
+ Assembler asm = context.Arm64Assembler;
+ RegisterAllocator regAlloc = context.RegisterAllocator;
+
+ if (index && !wBack)
+ {
+ // Offset.
+
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ int signedOffs = add ? offset.AsInt32() : -offset.AsInt32();
+ int offs = 0;
+
+ if (offset.Kind == OperandKind.Constant && offset.Value == 0)
+ {
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ }
+ else if (offset.Kind == OperandKind.Constant && CanFoldDWordOffset(context.MemoryManagerType, signedOffs))
+ {
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ offs = signedOffs;
+ }
+ else
+ {
+ WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
+ }
+
+ action(rt, rt2, tempRegister.Operand, offs);
+ }
+ else if (context.IsThumb ? !index && wBack : !index && !wBack)
+ {
+ // Post-indexed.
+
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+
+ action(rt, rt2, tempRegister.Operand, 0);
+
+ WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0);
+ }
+ else if (index && wBack)
+ {
+ // Pre-indexed.
+
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ if (rt.Value == baseAddress.Value)
+ {
+ // If Rt and Rn are the same register, ensure we perform the write back after the read/write.
+
+ WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
+
+ action(rt, rt2, tempRegister.Operand, 0);
+
+ context.Arm64Assembler.Mov(baseAddress, tempRegister.Operand);
+ }
+ else
+ {
+ WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+
+ action(rt, rt2, tempRegister.Operand, 0);
+ }
+ }
+ }
+
+ private static void EmitMemoryStrexInstruction(CodeGenContext context, uint rd, uint rt, uint rn, Action action)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+
+ action(rdOperand, rtOperand, tempRegister.Operand);
+ }
+
+ private static void EmitMemoryDWordStrexInstruction(CodeGenContext context, uint rd, uint rt, uint rt2, uint rn, Action action)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+
+ action(rdOperand, rtOperand, rt2Operand, tempRegister.Operand);
+ }
+
+ private static void EmitMemoryInstruction(
+ CodeGenContext context,
+ Action writeInst,
+ Action writeInstUnscaled,
+ Operand rt,
+ Operand baseAddress,
+ Operand offset,
+ int scale,
+ bool index,
+ bool add,
+ bool wBack,
+ ArmShiftType shiftType = ArmShiftType.Lsl,
+ int shift = 0)
+ {
+ Assembler asm = context.Arm64Assembler;
+ RegisterAllocator regAlloc = context.RegisterAllocator;
+
+ if (index && !wBack)
+ {
+ // Offset.
+
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ int signedOffs = add ? offset.AsInt32() : -offset.AsInt32();
+ int offs = 0;
+ bool unscaled = false;
+
+ if (offset.Kind == OperandKind.Constant && offset.Value == 0)
+ {
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ }
+ else if (offset.Kind == OperandKind.Constant && shift == 0 && CanFoldOffset(context.MemoryManagerType, signedOffs, scale, writeInstUnscaled != null, out unscaled))
+ {
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ offs = signedOffs;
+ }
+ else
+ {
+ WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
+ }
+
+ if (unscaled)
+ {
+ writeInstUnscaled(rt, tempRegister.Operand, offs);
+ }
+ else
+ {
+ writeInst(rt, tempRegister.Operand, offs);
+ }
+ }
+ else if (context.IsThumb ? !index && wBack : !index && !wBack)
+ {
+ // Post-indexed.
+
+ if (rt.Type == offset.Type && rt.Value == offset.Value)
+ {
+ // If Rt and Rm are the same register, we must ensure we add the register offset (Rm)
+ // before the value is loaded, otherwise we will be adding the wrong value.
+
+ if (rt.Type != baseAddress.Type || rt.Value != baseAddress.Value)
+ {
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift);
+
+ writeInst(rt, tempRegister.Operand, 0);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister2 = regAlloc.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+ WriteAddShiftOffset(asm, tempRegister2.Operand, baseAddress, offset, add, shiftType, shift);
+
+ writeInst(rt, tempRegister.Operand, 0);
+
+ asm.Mov(baseAddress, tempRegister2.Operand);
+ }
+ }
+ else
+ {
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+
+ writeInst(rt, tempRegister.Operand, 0);
+
+ WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift);
+ }
+ }
+ else if (index && wBack)
+ {
+ // Pre-indexed.
+
+ using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
+
+ if (rt.Value == baseAddress.Value)
+ {
+ // If Rt and Rn are the same register, ensure we perform the write back after the read/write.
+
+ WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
+
+ writeInst(rt, tempRegister.Operand, 0);
+
+ context.Arm64Assembler.Mov(baseAddress, tempRegister.Operand);
+ }
+ else
+ {
+ WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift);
+ WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
+
+ writeInst(rt, tempRegister.Operand, 0);
+ }
+ }
+ else
+ {
+ Debug.Fail($"Invalid pre-index and write-back combination.");
+ }
+ }
+
+ private static void EmitMemoryLiteralInstruction(CodeGenContext context, uint rt, uint imm, int scale, bool p, bool u, bool w, Action action)
+ {
+ if (!p || w)
+ {
+ EmitMemoryInstruction(context, rt, RegisterUtils.PcRegister, (int)imm, scale, p, u, w, isStore: false, action, null);
+
+ return;
+ }
+
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+ uint targetAddress = context.Pc & ~3u;
+
+ if (u)
+ {
+ targetAddress += imm;
+ }
+ else
+ {
+ targetAddress -= imm;
+ }
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
+
+ action(rtOperand, tempRegister.Operand, 0);
+ }
+
+ private static void EmitMemoryDWordLiteralInstruction(CodeGenContext context, uint rt, uint rt2, uint imm, bool p, bool u, bool w, Action action)
+ {
+ if (!p || w)
+ {
+ EmitMemoryDWordInstructionI(context, rt, rt2, RegisterUtils.PcRegister, imm, p, u, w, isStore: false, action);
+
+ return;
+ }
+
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2);
+ uint targetAddress = context.Pc & ~3u;
+
+ if (u)
+ {
+ targetAddress += imm;
+ }
+ else
+ {
+ targetAddress -= imm;
+ }
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
+
+ action(rtOperand, rt2Operand, tempRegister.Operand, 0);
+ }
+
+ private static void EmitMemoryPrefetchInstruction(CodeGenContext context, uint rn, uint imm, bool u, PrefetchType type)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ int signedOffs = u ? (int)imm : -(int)imm;
+ int offs = 0;
+ bool unscaled = false;
+
+ if (imm == 0)
+ {
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+ }
+ else if (CanFoldOffset(context.MemoryManagerType, signedOffs, 3, true, out unscaled))
+ {
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
+ offs = signedOffs;
+ }
+ else
+ {
+ WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)imm), u, ArmShiftType.Lsl, 0);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+ }
+
+ if (unscaled)
+ {
+ context.Arm64Assembler.Prfum(tempRegister.Operand, offs, (uint)type, 0, 0);
+ }
+ else
+ {
+ context.Arm64Assembler.PrfmI(tempRegister.Operand, offs, (uint)type, 0, 0);
+ }
+ }
+
+ private static void EmitMemoryPrefetchInstruction(CodeGenContext context, uint rn, uint rm, bool u, uint sType, uint shift, PrefetchType type)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, rmOperand, u, (ArmShiftType)sType, (int)shift);
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+
+ context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0);
+ }
+
+ private static void EmitMemoryPrefetchLiteralInstruction(CodeGenContext context, uint imm, bool u, PrefetchType type)
+ {
+ uint targetAddress = context.Pc & ~3u;
+
+ if (u)
+ {
+ targetAddress += imm;
+ }
+ else
+ {
+ targetAddress -= imm;
+ }
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
+
+ context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0);
+ }
+
+ public static bool CanFoldOffset(MemoryManagerType mmType, int offset, int scale, bool hasUnscaled, out bool unscaled)
+ {
+ if (mmType != MemoryManagerType.HostMappedUnsafe)
+ {
+ unscaled = false;
+
+ return false;
+ }
+
+ int mask = (1 << scale) - 1;
+
+ if ((offset & mask) == 0 && offset >= 0 && offset < 0x1000)
+ {
+ // We can use the unsigned, scaled encoding.
+
+ unscaled = false;
+
+ return true;
+ }
+
+ // Check if we can use the signed, unscaled encoding.
+
+ unscaled = hasUnscaled && offset >= -0x100 && offset < 0x100;
+
+ return unscaled;
+ }
+
+ private static bool CanFoldDWordOffset(MemoryManagerType mmType, int offset)
+ {
+ if (mmType != MemoryManagerType.HostMappedUnsafe)
+ {
+ return false;
+ }
+
+ return offset >= 0 && offset < 0x40 && (offset & 3) == 0;
+ }
+
+ private static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, uint guestAddress)
+ {
+ asm.Mov(destination, guestAddress);
+
+ WriteAddressTranslation(mmType, regAlloc, asm, destination, destination);
+ }
+
+ public static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, Operand guestAddress)
+ {
+ Operand destination64 = new(destination.Kind, OperandType.I64, destination.Value);
+ Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);
+
+ if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe)
+ {
+ // We don't need to mask the address for the safe mode, since it is already naturally limited to 32-bit
+ // and can never reach out of the guest address space.
+
+ asm.Add(destination64, basePointer, guestAddress);
+ }
+ else
+ {
+ throw new NotImplementedException(mmType.ToString());
+ }
+ }
+
+ public static void WriteAddShiftOffset(in Assembler asm, Operand rd, Operand rn, Operand offset, bool add, ArmShiftType shiftType, int shift)
+ {
+ Debug.Assert(offset.Kind != OperandKind.Constant || offset.AsInt32() >= 0);
+
+ if (shiftType == ArmShiftType.Ror)
+ {
+ asm.Ror(rd, rn, InstEmitCommon.Const(shift & 31));
+
+ if (add)
+ {
+ asm.Add(rd, rd, offset, ArmShiftType.Lsl, 0);
+ }
+ else
+ {
+ asm.Sub(rd, rd, offset, ArmShiftType.Lsl, 0);
+ }
+ }
+ else
+ {
+ if (add)
+ {
+ asm.Add(rd, rn, offset, shiftType, shift);
+ }
+ else
+ {
+ asm.Sub(rd, rn, offset, shiftType, shift);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs
new file mode 100644
index 00000000..88850cb3
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs
@@ -0,0 +1,350 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitMove
+ {
+ public static void MvnI(CodeGenContext context, uint rd, uint imm, bool immRotated, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ if (s)
+ {
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ if (immRotated)
+ {
+ if ((imm & (1u << 31)) != 0)
+ {
+ context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(1 << 29));
+ }
+ else
+ {
+ context.Arm64Assembler.Bfc(flagsRegister.Operand, 29, 1);
+ }
+ }
+
+ context.Arm64Assembler.Mov(rdOperand, ~imm);
+ context.Arm64Assembler.Tst(rdOperand, rdOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ context.Arm64Assembler.Mov(rdOperand, ~imm);
+ }
+ }
+
+ public static void MvnR(CodeGenContext context, uint rd, uint rm, uint sType, uint imm5, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister flagsRegister = default;
+
+ if (s)
+ {
+ flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand);
+ }
+ else
+ {
+ rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType);
+ }
+
+ context.Arm64Assembler.Mvn(rdOperand, rmOperand);
+
+ if (s)
+ {
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ flagsRegister.Dispose();
+
+ context.SetNzcvModified();
+ }
+ }
+
+ public static void MvnRr(CodeGenContext context, uint rd, uint rm, uint sType, uint rs, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister flagsRegister = default;
+
+ if (s)
+ {
+ flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand);
+ }
+ else
+ {
+ rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType);
+ }
+
+ context.Arm64Assembler.Mvn(rdOperand, rmOperand);
+
+ if (s)
+ {
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ flagsRegister.Dispose();
+
+ context.SetNzcvModified();
+ }
+ }
+
+ public static void MovI(CodeGenContext context, uint rd, uint imm, bool immRotated, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ if (s)
+ {
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ if (immRotated)
+ {
+ if ((imm & (1u << 31)) != 0)
+ {
+ context.Arm64Assembler.Orr(flagsRegister.Operand, flagsRegister.Operand, InstEmitCommon.Const(2));
+ }
+ else
+ {
+ context.Arm64Assembler.Bfc(flagsRegister.Operand, 1, 1);
+ }
+ }
+
+ context.Arm64Assembler.Mov(rdOperand, imm);
+ context.Arm64Assembler.Tst(rdOperand, rdOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ context.Arm64Assembler.Mov(rdOperand, imm);
+ }
+ }
+
+ public static void MovR(CodeGenContext context, uint rd, uint rm, uint sType, uint imm5, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (InstEmitAlu.CanShift(sType, imm5) && !s)
+ {
+ if (imm5 != 0)
+ {
+ switch ((ArmShiftType)sType)
+ {
+ case ArmShiftType.Lsl:
+ context.Arm64Assembler.Lsl(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Lsr:
+ context.Arm64Assembler.Lsr(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Asr:
+ context.Arm64Assembler.Asr(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Ror:
+ context.Arm64Assembler.Ror(rdOperand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ }
+ }
+ else
+ {
+ context.Arm64Assembler.Mov(rdOperand, rmOperand);
+ }
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister flagsRegister = default;
+
+ if (s)
+ {
+ flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, flagsRegister.Operand);
+ }
+ else
+ {
+ rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null);
+ }
+
+ context.Arm64Assembler.Mov(rdOperand, rmOperand);
+
+ if (s)
+ {
+ context.Arm64Assembler.Tst(rdOperand, rdOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ flagsRegister.Dispose();
+
+ context.SetNzcvModified();
+ }
+ }
+ }
+
+ public static void MovR(CodeGenContext context, uint cond, uint rd, uint rm, uint sType, uint imm5, bool s)
+ {
+ if (context.ConsumeSkipNextInstruction())
+ {
+ return;
+ }
+
+ if ((ArmCondition)cond >= ArmCondition.Al || s)
+ {
+ MovR(context, rd, rm, sType, imm5, s);
+
+ return;
+ }
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (InstEmitAlu.CanShift(sType, imm5))
+ {
+ if (imm5 != 0)
+ {
+ switch ((ArmShiftType)sType)
+ {
+ case ArmShiftType.Lsl:
+ context.Arm64Assembler.Lsl(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Lsr:
+ context.Arm64Assembler.Lsr(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Asr:
+ context.Arm64Assembler.Asr(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ case ArmShiftType.Ror:
+ context.Arm64Assembler.Ror(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5));
+ break;
+ }
+
+ context.Arm64Assembler.Csel(rdOperand, tempRegister.Operand, rdOperand, (ArmCondition)cond);
+ }
+ else
+ {
+ Operand other = rdOperand;
+
+ InstInfo nextInstruction = context.PeekNextInstruction();
+
+ if (nextInstruction.Name == InstName.MovR)
+ {
+ // If this instruction is followed by another move with the inverse condition,
+ // we can just put it into the second operand of the CSEL instruction and skip the next move.
+
+ InstCondb28w4Sb20w1Rdb12w4Imm5b7w5Stypeb5w2Rmb0w4 nextInst = new(nextInstruction.Encoding);
+
+ if (nextInst.Rd == rd &&
+ nextInst.S == 0 &&
+ nextInst.Stype == 0 &&
+ nextInst.Imm5 == 0 &&
+ nextInst.Cond == (cond ^ 1u) &&
+ nextInst.Rm != RegisterUtils.PcRegister)
+ {
+ other = InstEmitCommon.GetInputGpr(context, nextInst.Rm);
+ context.SetSkipNextInstruction();
+ }
+ }
+
+ context.Arm64Assembler.Csel(rdOperand, rmOperand, other, (ArmCondition)cond);
+ }
+ }
+ else
+ {
+ rmOperand = InstEmitAlu.GetMShiftedByImmediate(context, tempRegister.Operand, rmOperand, imm5, sType, null);
+
+ context.Arm64Assembler.Csel(rdOperand, rmOperand, rdOperand, (ArmCondition)cond);
+ }
+ }
+
+ public static void MovRr(CodeGenContext context, uint rd, uint rm, uint sType, uint rs, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand rsOperand = InstEmitCommon.GetInputGpr(context, rs);
+
+ if (!s)
+ {
+ InstEmitAlu.GetMShiftedByReg(context, rdOperand, rmOperand, rsOperand, sType);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ rmOperand = InstEmitAlu.GetMShiftedByReg(context, tempRegister.Operand, rmOperand, rsOperand, sType, flagsRegister.Operand);
+
+ context.Arm64Assembler.Mov(rdOperand, rmOperand);
+ context.Arm64Assembler.Tst(rdOperand, rdOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ }
+
+ public static void Movt(CodeGenContext context, uint rd, uint imm)
+ {
+ Operand rdOperand = InstEmitCommon.GetInputGpr(context, rd);
+
+ context.Arm64Assembler.Movk(rdOperand, (int)imm, 1);
+ }
+
+ public static void Pkh(CodeGenContext context, uint rd, uint rn, uint rm, bool tb, uint imm5)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (!tb && imm5 == 0)
+ {
+ context.Arm64Assembler.Extr(rdOperand, rnOperand, rmOperand, 16);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (tb)
+ {
+ context.Arm64Assembler.Asr(tempRegister.Operand, rmOperand, InstEmitCommon.Const(imm5 == 0 ? 31 : (int)imm5));
+ context.Arm64Assembler.Extr(rdOperand, tempRegister.Operand, rnOperand, 16);
+ }
+ else
+ {
+ context.Arm64Assembler.Lsl(tempRegister.Operand, rmOperand, InstEmitCommon.Const((int)imm5));
+ context.Arm64Assembler.Extr(rdOperand, rnOperand, tempRegister.Operand, 16);
+ }
+ }
+
+ context.Arm64Assembler.Ror(rdOperand, rdOperand, InstEmitCommon.Const(16));
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs
new file mode 100644
index 00000000..042ab815
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs
@@ -0,0 +1,603 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitMultiply
+ {
+ public static void Mla(CodeGenContext context, uint rd, uint rn, uint rm, uint ra)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ context.Arm64Assembler.Madd(rdOperand, rnOperand, rmOperand, raOperand);
+ }
+
+ public static void Mls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ context.Arm64Assembler.Msub(rdOperand, rnOperand, rmOperand, raOperand);
+ }
+
+ public static void Mul(CodeGenContext context, uint rd, uint rn, uint rm, bool s)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ if (s)
+ {
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ context.Arm64Assembler.Mul(rdOperand, rnOperand, rmOperand);
+ context.Arm64Assembler.Tst(rdOperand, rdOperand);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ context.Arm64Assembler.Mul(rdOperand, rnOperand, rmOperand);
+ }
+ }
+
+ public static void Smlabb(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool nHigh, bool mHigh)
+ {
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh);
+ SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh);
+
+ context.Arm64Assembler.Sxtw(tempA64, raOperand);
+ context.Arm64Assembler.Smaddl(tempN.Operand, tempN.Operand, tempM.Operand, tempA64);
+
+ CheckResultOverflow(context, tempM64, tempN.Operand);
+
+ context.Arm64Assembler.Mov(rdOperand, tempN.Operand);
+ }
+
+ public static void Smlad(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x)
+ {
+ EmitSmladSmlsd(context, rd, rn, rm, ra, x, add: true);
+ }
+
+ public static void Smlal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ EmitMultiplyAddLong(context, context.Arm64Assembler.Smaddl, rdLo, rdHi, rn, rm, s);
+ }
+
+ public static void Smlalbb(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool nHigh, bool mHigh)
+ {
+ Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo);
+ Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value);
+ Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh);
+ SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh);
+
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ context.Arm64Assembler.Lsl(tempA64, rdHiOperand64, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Orr(tempA64, tempA64, rdLoOperand);
+
+ context.Arm64Assembler.Smaddl(rdLoOperand64, tempN.Operand, tempM.Operand, tempA64);
+
+ if (rdLo != rdHi)
+ {
+ context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32));
+ }
+
+ context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend.
+ }
+
+ public static void Smlald(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x)
+ {
+ EmitSmlaldSmlsld(context, rdLo, rdHi, rn, rm, x, add: true);
+ }
+
+ public static void Smlawb(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool mHigh)
+ {
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh);
+
+ context.Arm64Assembler.Sxtw(tempA64, raOperand);
+ context.Arm64Assembler.Lsl(tempA64, tempA64, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Smaddl(tempN.Operand, rnOperand, tempM.Operand, tempA64);
+ context.Arm64Assembler.Asr(tempN64, tempN64, InstEmitCommon.Const(16));
+
+ CheckResultOverflow(context, tempM64, tempN.Operand);
+
+ context.Arm64Assembler.Mov(rdOperand, tempN.Operand);
+ }
+
+ public static void Smlsd(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x)
+ {
+ EmitSmladSmlsd(context, rd, rn, rm, ra, x, add: false);
+ }
+
+ public static void Smlsld(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x)
+ {
+ EmitSmlaldSmlsld(context, rdLo, rdHi, rn, rm, x, add: false);
+ }
+
+ public static void Smmla(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r)
+ {
+ EmitSmmlaSmmls(context, rd, rn, rm, ra, r, add: true);
+ }
+
+ public static void Smmls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r)
+ {
+ EmitSmmlaSmmls(context, rd, rn, rm, ra, r, add: false);
+ }
+
+ public static void Smmul(CodeGenContext context, uint rd, uint rn, uint rm, bool r)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value);
+
+ context.Arm64Assembler.Smull(rdOperand64, rnOperand, rmOperand);
+
+ if (r)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempRegister.Operand, 0x80000000u);
+ context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempRegister.Operand);
+ }
+
+ context.Arm64Assembler.Lsr(rdOperand64, rdOperand64, InstEmitCommon.Const(32));
+ }
+
+ public static void Smuad(CodeGenContext context, uint rd, uint rn, uint rm, bool x)
+ {
+ EmitSmuadSmusd(context, rd, rn, rm, x, add: true);
+ }
+
+ public static void Smulbb(CodeGenContext context, uint rd, uint rn, uint rm, bool nHigh, bool mHigh)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ SelectSignedHalfword(context, tempN.Operand, rnOperand, nHigh);
+ SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh);
+
+ context.Arm64Assembler.Smull(rdOperand64, tempN.Operand, tempM.Operand);
+
+ context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend.
+ }
+
+ public static void Smull(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ EmitMultiplyLong(context, context.Arm64Assembler.Smull, rdLo, rdHi, rn, rm, s);
+ }
+
+ public static void Smulwb(CodeGenContext context, uint rd, uint rn, uint rm, bool mHigh)
+ {
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ SelectSignedHalfword(context, tempM.Operand, rmOperand, mHigh);
+
+ context.Arm64Assembler.Smull(tempN.Operand, rnOperand, tempM.Operand);
+ context.Arm64Assembler.Asr(tempN64, tempN64, InstEmitCommon.Const(16));
+
+ CheckResultOverflow(context, tempM64, tempN.Operand);
+
+ context.Arm64Assembler.Mov(rdOperand, tempN.Operand);
+ }
+
+ public static void Smusd(CodeGenContext context, uint rd, uint rn, uint rm, bool x)
+ {
+ EmitSmuadSmusd(context, rd, rn, rm, x, add: false);
+ }
+
+ public static void Umaal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm)
+ {
+ Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo);
+ Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value);
+ Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value);
+
+ if (rdLo == rdHi)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempRegister64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value);
+
+ context.Arm64Assembler.Umaddl(tempRegister64, rnOperand, rmOperand, rdLoOperand64);
+ context.Arm64Assembler.Add(rdLoOperand64, tempRegister64, rdHiOperand64);
+ }
+ else
+ {
+ context.Arm64Assembler.Umaddl(rdLoOperand64, rnOperand, rmOperand, rdLoOperand64);
+ context.Arm64Assembler.Add(rdLoOperand64, rdLoOperand64, rdHiOperand64);
+ }
+
+ if (rdLo != rdHi)
+ {
+ context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32));
+ }
+
+ context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend.
+ }
+
+ public static void Umlal(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ EmitMultiplyAddLong(context, context.Arm64Assembler.Umaddl, rdLo, rdHi, rn, rm, s);
+ }
+
+ public static void Umull(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ EmitMultiplyLong(context, context.Arm64Assembler.Umull, rdLo, rdHi, rn, rm, s);
+ }
+
+ private static void EmitMultiplyLong(CodeGenContext context, Action action, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo);
+ Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value);
+ Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value);
+
+ if (s)
+ {
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ action(rdLoOperand64, rnOperand, rmOperand);
+ context.Arm64Assembler.Tst(rdLoOperand64, rdLoOperand64);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+ }
+ else
+ {
+ action(rdLoOperand64, rnOperand, rmOperand);
+ }
+
+ if (rdLo != rdHi)
+ {
+ context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32));
+ }
+
+ context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend.
+ }
+
+ private static void EmitMultiplyAddLong(CodeGenContext context, Action action, uint rdLo, uint rdHi, uint rn, uint rm, bool s)
+ {
+ Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo);
+ Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value);
+ Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value);
+
+ using ScopedRegister raRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand raOperand64 = new(OperandKind.Register, OperandType.I64, raRegister.Operand.Value);
+
+ context.Arm64Assembler.Lsl(raOperand64, rdHiOperand64, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Orr(raOperand64, raOperand64, rdLoOperand);
+
+ if (s)
+ {
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ action(rdLoOperand64, rnOperand, rmOperand, raOperand64);
+ context.Arm64Assembler.Tst(rdLoOperand64, rdLoOperand64);
+
+ InstEmitCommon.RestoreCvFlags(context, flagsRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ action(rdLoOperand64, rnOperand, rmOperand, raOperand64);
+ }
+
+ if (rdLo != rdHi)
+ {
+ context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32));
+ }
+
+ context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend.
+ }
+
+ private static void EmitSmladSmlsd(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool x, bool add)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ ScopedRegister swapTemp = default;
+
+ if (x)
+ {
+ swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ rmOperand = swapTemp.Operand;
+ }
+
+ context.Arm64Assembler.Sxth(tempN64, rnOperand);
+ context.Arm64Assembler.Sxth(tempM64, rmOperand);
+ context.Arm64Assembler.Sxtw(tempA64, raOperand);
+
+ context.Arm64Assembler.Mul(rdOperand64, tempN64, tempM64);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ if (add)
+ {
+ context.Arm64Assembler.Smaddl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64);
+ }
+ else
+ {
+ context.Arm64Assembler.Smsubl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64);
+ }
+
+ context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempA64);
+
+ CheckResultOverflow(context, tempM64, rdOperand64);
+
+ context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend.
+
+ if (x)
+ {
+ swapTemp.Dispose();
+ }
+ }
+
+ private static void EmitSmlaldSmlsld(CodeGenContext context, uint rdLo, uint rdHi, uint rn, uint rm, bool x, bool add)
+ {
+ Operand rdLoOperand = InstEmitCommon.GetOutputGpr(context, rdLo);
+ Operand rdHiOperand = InstEmitCommon.GetOutputGpr(context, rdHi);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdLoOperand64 = new(OperandKind.Register, OperandType.I64, rdLoOperand.Value);
+ Operand rdHiOperand64 = new(OperandKind.Register, OperandType.I64, rdHiOperand.Value);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ ScopedRegister swapTemp = default;
+
+ if (x)
+ {
+ swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ rmOperand = swapTemp.Operand;
+ }
+
+ context.Arm64Assembler.Sxth(tempN64, rnOperand);
+ context.Arm64Assembler.Sxth(tempM64, rmOperand);
+
+ context.Arm64Assembler.Mul(rdLoOperand64, tempN64, tempM64);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ if (add)
+ {
+ context.Arm64Assembler.Smaddl(rdLoOperand64, tempN.Operand, tempM.Operand, rdLoOperand64);
+ }
+ else
+ {
+ context.Arm64Assembler.Smsubl(rdLoOperand64, tempN.Operand, tempM.Operand, rdLoOperand64);
+ }
+
+ context.Arm64Assembler.Lsl(tempA64, rdHiOperand64, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Orr(tempA64, tempA64, rdLoOperand);
+
+ context.Arm64Assembler.Add(rdLoOperand64, rdLoOperand64, tempA64);
+
+ if (rdLo != rdHi)
+ {
+ context.Arm64Assembler.Lsr(rdHiOperand64, rdLoOperand64, InstEmitCommon.Const(32));
+ }
+
+ context.Arm64Assembler.Mov(rdLoOperand, rdLoOperand); // Zero-extend.
+
+ if (x)
+ {
+ swapTemp.Dispose();
+ }
+ }
+
+ private static void EmitSmmlaSmmls(CodeGenContext context, uint rd, uint rn, uint rm, uint ra, bool r, bool add)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+ Operand raOperand = InstEmitCommon.GetInputGpr(context, ra);
+
+ Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value);
+ Operand raOperand64 = new(OperandKind.Register, OperandType.I64, raOperand.Value);
+
+ using ScopedRegister tempA = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempA64 = new(OperandKind.Register, OperandType.I64, tempA.Operand.Value);
+
+ context.Arm64Assembler.Lsl(tempA64, raOperand64, InstEmitCommon.Const(32));
+
+ if (add)
+ {
+ context.Arm64Assembler.Smaddl(rdOperand64, rnOperand, rmOperand, tempA64);
+ }
+ else
+ {
+ context.Arm64Assembler.Smsubl(rdOperand64, rnOperand, rmOperand, tempA64);
+ }
+
+ if (r)
+ {
+ context.Arm64Assembler.Mov(tempA.Operand, 0x80000000u);
+ context.Arm64Assembler.Add(rdOperand64, rdOperand64, tempA64);
+ }
+
+ context.Arm64Assembler.Lsr(rdOperand64, rdOperand64, InstEmitCommon.Const(32));
+ }
+
+ private static void EmitSmuadSmusd(CodeGenContext context, uint rd, uint rn, uint rm, bool x, bool add)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ Operand rdOperand64 = new(OperandKind.Register, OperandType.I64, rdOperand.Value);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+
+ ScopedRegister swapTemp = default;
+
+ if (x)
+ {
+ swapTemp = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Ror(swapTemp.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ rmOperand = swapTemp.Operand;
+ }
+
+ context.Arm64Assembler.Sxth(tempN64, rnOperand);
+ context.Arm64Assembler.Sxth(tempM64, rmOperand);
+
+ context.Arm64Assembler.Mul(rdOperand64, tempN64, tempM64);
+
+ context.Arm64Assembler.Asr(tempN.Operand, rnOperand, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Asr(tempM.Operand, rmOperand, InstEmitCommon.Const(16));
+
+ if (add)
+ {
+ context.Arm64Assembler.Smaddl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64);
+ }
+ else
+ {
+ context.Arm64Assembler.Smsubl(rdOperand64, tempN.Operand, tempM.Operand, rdOperand64);
+ }
+
+ context.Arm64Assembler.Mov(rdOperand, rdOperand); // Zero-extend.
+
+ if (x)
+ {
+ swapTemp.Dispose();
+ }
+ }
+
+ private static void SelectSignedHalfword(CodeGenContext context, Operand dest, Operand source, bool high)
+ {
+ if (high)
+ {
+ context.Arm64Assembler.Asr(dest, source, InstEmitCommon.Const(16));
+ }
+ else
+ {
+ context.Arm64Assembler.Sxth(dest, source);
+ }
+ }
+
+ private static void CheckResultOverflow(CodeGenContext context, Operand temp64, Operand result)
+ {
+ context.Arm64Assembler.Sxtw(temp64, result);
+ context.Arm64Assembler.Sub(temp64, temp64, result);
+
+ int branchIndex = context.CodeWriter.InstructionPointer;
+
+ context.Arm64Assembler.Cbz(temp64, 0);
+
+ // Set Q flag if we had an overflow.
+ InstEmitSaturate.SetQFlag(context);
+
+ int delta = context.CodeWriter.InstructionPointer - branchIndex;
+ context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5));
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs
new file mode 100644
index 00000000..a59f00fc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs
@@ -0,0 +1,344 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonArithmetic
+ {
+ public static void Vaba(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uaba : context.Arm64Assembler.Saba, null);
+ }
+
+ public static void Vabal(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uabal : context.Arm64Assembler.Sabal);
+ }
+
+ public static void VabdF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FabdV, context.Arm64Assembler.FabdVH);
+ }
+
+ public static void VabdI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uabd : context.Arm64Assembler.Sabd, null);
+ }
+
+ public static void Vabdl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uabdl : context.Arm64Assembler.Sabdl);
+ }
+
+ public static void Vabs(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FabsSingleAndDouble, context.Arm64Assembler.FabsHalf);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.AbsV);
+ }
+ }
+
+ public static void VaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FaddSingleAndDouble, context.Arm64Assembler.FaddHalf);
+ }
+
+ public static void VaddI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.AddV, context.Arm64Assembler.AddS);
+ }
+
+ public static void Vaddhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Addhn);
+ }
+
+ public static void Vaddl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uaddl : context.Arm64Assembler.Saddl);
+ }
+
+ public static void Vaddw(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryWide(context, rd, rn, rm, size, u ? context.Arm64Assembler.Uaddw : context.Arm64Assembler.Saddw);
+ }
+
+ public static void VfmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmlaVecSingleAndDouble, context.Arm64Assembler.FmlaVecHalf);
+ }
+
+ public static void VfmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmlsVecSingleAndDouble, context.Arm64Assembler.FmlsVecHalf);
+ }
+
+ public static void Vhadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uhadd : context.Arm64Assembler.Shadd, null);
+ }
+
+ public static void Vhsub(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uhsub : context.Arm64Assembler.Shsub, null);
+ }
+
+ public static void Vmaxnm(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxnmSingleAndDouble, context.Arm64Assembler.FmaxnmHalf);
+ }
+
+ public static void VmaxF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxSingleAndDouble, context.Arm64Assembler.FmaxHalf);
+ }
+
+ public static void VmaxI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umax : context.Arm64Assembler.Smax, null);
+ }
+
+ public static void Vminnm(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminnmSingleAndDouble, context.Arm64Assembler.FminnmHalf);
+ }
+
+ public static void VminF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminSingleAndDouble, context.Arm64Assembler.FminHalf);
+ }
+
+ public static void VminI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umin : context.Arm64Assembler.Smin, null);
+ }
+
+ public static void VmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryMulNegRdF(context, rd, rn, rm, sz, q, negProduct: false);
+ }
+
+ public static void VmlaI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.MlaVec);
+ }
+
+ public static void VmlaS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryMulNegRdByScalarAnyF(context, rd, rn, rm, size, q, negProduct: false);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MlaElt);
+ }
+ }
+
+ public static void VmlalI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlalVec : context.Arm64Assembler.SmlalVec);
+ }
+
+ public static void VmlalS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlalElt : context.Arm64Assembler.SmlalElt);
+ }
+
+ public static void VmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryMulNegRdF(context, rd, rn, rm, sz, q, negProduct: true);
+ }
+
+ public static void VmlsI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.MlsVec);
+ }
+
+ public static void VmlsS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryMulNegRdByScalarAnyF(context, rd, rn, rm, size, q, negProduct: true);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MlsElt);
+ }
+ }
+
+ public static void VmlslI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlslVec : context.Arm64Assembler.SmlslVec);
+ }
+
+ public static void VmlslS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmlslElt : context.Arm64Assembler.SmlslElt);
+ }
+
+ public static void VmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmulVecSingleAndDouble, context.Arm64Assembler.FmulVecHalf);
+ }
+
+ public static void VmulI(CodeGenContext context, uint rd, uint rn, uint rm, bool op, uint size, uint q)
+ {
+ if (op)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.Pmul, null);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.MulVec, null);
+ }
+ }
+
+ public static void VmulS(CodeGenContext context, uint rd, uint rn, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryByScalarAnyF(context, rd, rn, rm, size, q, context.Arm64Assembler.FmulElt2regElementSingleAndDouble, context.Arm64Assembler.FmulElt2regElementHalf);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.MulElt);
+ }
+ }
+
+ public static void VmullI(CodeGenContext context, uint rd, uint rn, uint rm, bool op, bool u, uint size)
+ {
+ if (op)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size == 2 ? 3 : size, context.Arm64Assembler.Pmull);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmullVec : context.Arm64Assembler.SmullVec);
+ }
+ }
+
+ public static void VmullS(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, u ? context.Arm64Assembler.UmullElt : context.Arm64Assembler.SmullElt);
+ }
+
+ public static void Vneg(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FnegSingleAndDouble, context.Arm64Assembler.FnegHalf);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.NegV);
+ }
+ }
+
+ public static void Vpadal(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryRd(context, rd, rm, size, q, op ? context.Arm64Assembler.Uadalp : context.Arm64Assembler.Sadalp);
+ }
+
+ public static void VpaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FaddpVecSingleAndDouble, context.Arm64Assembler.FaddpVecHalf);
+ }
+
+ public static void VpaddI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.AddpVec, null);
+ }
+
+ public static void Vpaddl(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, op ? context.Arm64Assembler.Uaddlp : context.Arm64Assembler.Saddlp);
+ }
+
+ public static void VpmaxF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FmaxpVecSingleAndDouble, context.Arm64Assembler.FmaxpVecHalf);
+ }
+
+ public static void VpmaxI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Umaxp : context.Arm64Assembler.Smaxp, null);
+ }
+
+ public static void VpminF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FminpVecSingleAndDouble, context.Arm64Assembler.FminpVecHalf);
+ }
+
+ public static void VpminI(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Uminp : context.Arm64Assembler.Sminp, null);
+ }
+
+ public static void Vrecpe(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrecpeV, context.Arm64Assembler.FrecpeVH);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public static void Vrecps(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FrecpsV, context.Arm64Assembler.FrecpsVH);
+ }
+
+ public static void Vrsqrte(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrsqrteV, context.Arm64Assembler.FrsqrteVH);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public static void Vrsqrts(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FrsqrtsV, context.Arm64Assembler.FrsqrtsVH);
+ }
+
+ public static void VsubF(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FsubSingleAndDouble, context.Arm64Assembler.FsubHalf);
+ }
+
+ public static void VsubI(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SubV, context.Arm64Assembler.SubS);
+ }
+
+ public static void Vsubhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Subhn);
+ }
+
+ public static void Vsubl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, u ? context.Arm64Assembler.Usubl : context.Arm64Assembler.Ssubl);
+ }
+
+ public static void Vsubw(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryWide(context, rd, rn, rm, size, u ? context.Arm64Assembler.Usubw : context.Arm64Assembler.Ssubw);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs
new file mode 100644
index 00000000..9601f4c2
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs
@@ -0,0 +1,35 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonBit
+ {
+ public static void Vcls(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Cls);
+ }
+
+ public static void Vclz(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Clz);
+ }
+
+ public static void Vcnt(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Cnt);
+ }
+
+ public static void Vrev16(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev16);
+ }
+
+ public static void Vrev32(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev32);
+ }
+
+ public static void Vrev64(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.Rev64);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs
new file mode 100644
index 00000000..dce6556e
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs
@@ -0,0 +1,1513 @@
+
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonCommon
+ {
+ public static ScopedRegister MoveScalarToSide(CodeGenContext context, uint srcReg, bool isFP32, bool forceAllocation = false)
+ {
+ int shift = isFP32 ? 2 : 1;
+ uint mask = isFP32 ? 3u : 1u;
+ uint elt = srcReg & mask;
+
+ if (elt == 0 && !forceAllocation)
+ {
+ return new ScopedRegister(context.RegisterAllocator, context.RegisterAllocator.RemapFpRegister((int)(srcReg >> shift), isFP32), false);
+ }
+
+ Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift));
+ ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(isFP32);
+
+ uint imm5 = GetImm5ForElementIndex(elt, isFP32);
+
+ context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5);
+
+ return tempRegister;
+ }
+
+ public static ScopedRegister Move16BitScalarToSide(CodeGenContext context, uint srcReg, bool top = false)
+ {
+ uint elt = srcReg & 3;
+
+ Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> 2));
+ ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(true);
+
+ uint imm5 = GetImm5ForElementIndex((elt << 1) | (top ? 1u : 0u), 1);
+
+ context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5);
+
+ return tempRegister;
+ }
+
+ public static void MoveScalarToSide(CodeGenContext context, Operand dest, uint srcReg, bool isFP32)
+ {
+ int shift = isFP32 ? 2 : 1;
+ uint mask = isFP32 ? 3u : 1u;
+ uint elt = srcReg & mask;
+
+ Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift));
+
+ uint imm5 = GetImm5ForElementIndex(elt, isFP32);
+
+ context.Arm64Assembler.DupEltScalarFromElement(dest, source, imm5);
+ }
+
+ public static ScopedRegister MoveScalarToSideIntoGpr(CodeGenContext context, uint srcReg, bool isFP32)
+ {
+ int shift = isFP32 ? 2 : 1;
+ uint mask = isFP32 ? 3u : 1u;
+ uint elt = srcReg & mask;
+
+ Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> shift));
+ ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Umov(tempRegister.Operand, source, (int)elt, isFP32 ? 2 : 3);
+
+ return tempRegister;
+ }
+
+ public static void InsertResult(CodeGenContext context, Operand source, uint dstReg, bool isFP32)
+ {
+ int shift = isFP32 ? 2 : 1;
+ uint mask = isFP32 ? 3u : 1u;
+ uint elt = dstReg & mask;
+
+ uint imm5 = GetImm5ForElementIndex(elt, isFP32);
+
+ Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> shift));
+
+ context.Arm64Assembler.InsElt(dest, source, 0, imm5);
+ }
+
+ public static void Insert16BitResult(CodeGenContext context, Operand source, uint dstReg, bool top = false)
+ {
+ uint elt = dstReg & 3u;
+
+ uint imm5 = GetImm5ForElementIndex((elt << 1) | (top ? 1u : 0u), 1);
+
+ Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> 2));
+
+ context.Arm64Assembler.InsElt(dest, source, 0, imm5);
+ }
+
+ public static void InsertResultFromGpr(CodeGenContext context, Operand source, uint dstReg, bool isFP32)
+ {
+ int shift = isFP32 ? 2 : 1;
+ uint mask = isFP32 ? 3u : 1u;
+ uint elt = dstReg & mask;
+
+ uint imm5 = GetImm5ForElementIndex(elt, isFP32);
+
+ Operand dest = context.RegisterAllocator.RemapSimdRegister((int)(dstReg >> shift));
+
+ context.Arm64Assembler.InsGen(dest, source, imm5);
+ }
+
+ public static uint GetImm5ForElementIndex(uint elt, bool isFP32)
+ {
+ return isFP32 ? (4u | (elt << 3)) : (8u | (elt << 4));
+ }
+
+ public static uint GetImm5ForElementIndex(uint elt, uint size)
+ {
+ return (1u << (int)size) | (elt << ((int)size + 1));
+ }
+
+ public static void EmitScalarUnaryF(CodeGenContext context, uint rd, uint rm, uint size, Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, size ^ 2u);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarUnaryF(CodeGenContext context, uint rd, uint rm, uint size, Action action, Action actionHalf)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ if (size == 1)
+ {
+ actionHalf(tempRegister.Operand, rmReg.Operand);
+ }
+ else
+ {
+ action(tempRegister.Operand, rmReg.Operand, size & 1);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarUnaryToGprTempF(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint size,
+ uint sf,
+ Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ action(tempRegister.Operand, rmReg.Operand, size ^ 2u, sf);
+
+ InsertResultFromGpr(context, tempRegister.Operand, rd, sf == 0);
+ }
+
+ public static void EmitScalarUnaryFromGprTempF(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint size,
+ uint sf,
+ Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rmReg = MoveScalarToSideIntoGpr(context, rm, sf == 0);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action(tempRegister.Operand, rmReg.Operand, size ^ 2u, sf);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarUnaryFixedF(CodeGenContext context, uint rd, uint rm, uint fbits, uint size, bool is16Bit, Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ (uint immb, uint immh) = GetImmbImmh(fbits, size);
+
+ using ScopedRegister rmReg = is16Bit ? Move16BitScalarToSide(context, rm) : MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, immb, immh);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarBinaryF(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size ^ 2u);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarBinaryShift(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint shift,
+ uint size,
+ bool isShl,
+ Action action)
+ {
+ bool singleRegs = size != 3;
+
+ (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl);
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, immb, immh);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarTernaryRdF(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, singleRegs);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size ^ 2u);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarTernaryRdF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rdReg = MoveScalarToSide(context, rd, singleRegs);
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rdReg, rnReg, rmReg);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, rdReg.Operand, size ^ 2u);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitScalarTernaryMulNegRdF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ bool negD,
+ bool negProduct)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, singleRegs);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, singleRegs);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ uint ftype = size ^ 2u;
+
+ context.Arm64Assembler.FmulFloat(productRegister.Operand, rnReg.Operand, rmReg.Operand, ftype);
+
+ if (negD)
+ {
+ context.Arm64Assembler.FnegFloat(tempRegister.Operand, tempRegister.Operand, ftype);
+ }
+
+ if (negProduct)
+ {
+ context.Arm64Assembler.FnegFloat(productRegister.Operand, productRegister.Operand, ftype);
+ }
+
+ context.Arm64Assembler.FaddFloat(tempRegister.Operand, tempRegister.Operand, productRegister.Operand, ftype);
+
+ InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, Action action)
+ {
+ Debug.Assert(((rd | rm) & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand);
+ }
+
+ public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, uint q, Action action)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand, q);
+ }
+ }
+
+ public static void EmitVectorUnary(CodeGenContext context, uint rd, uint rm, uint size, uint q, Action action)
+ {
+ Debug.Assert(size < 3);
+
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand, size, q);
+ }
+ }
+
+ public static void EmitVectorUnaryLong(CodeGenContext context, uint rd, uint rm, uint size, Action action)
+ {
+ Debug.Assert((rd & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rm & 1;
+
+ action(rdOperand, rmOperand, size, q);
+ }
+
+ public static void EmitVectorUnaryNarrow(CodeGenContext context, uint rd, uint rm, uint size, Action action)
+ {
+ Debug.Assert((rm & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rd & 1;
+
+ if (q == 0)
+ {
+ // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action(tempRegister.Operand, rmOperand, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ action(rdOperand, rmOperand, size, q);
+ }
+ }
+
+ public static void EmitVectorBinary(CodeGenContext context, uint rd, uint rn, uint rm, Action action)
+ {
+ Debug.Assert(((rd | rn | rm) & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rnOperand, rmOperand);
+ }
+
+ public static void EmitVectorBinary(CodeGenContext context, uint rd, uint rn, uint rm, uint q, Action action)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rnOperand, rmOperand, q);
+ }
+ }
+
+ public static void EmitVectorBinary(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ Action actionScalar)
+ {
+ Debug.Assert(size <= 3);
+
+ if (q == 0)
+ {
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ if (size == 3)
+ {
+ actionScalar(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size);
+ }
+ else
+ {
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+ }
+
+ public static void EmitVectorBinaryRd(CodeGenContext context, uint rd, uint rm, uint size, uint q, Action action)
+ {
+ Debug.Assert(size < 3);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ action(tempRegister.Operand, rmReg.Operand, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+
+ public static void EmitVectorBinaryShift(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint shift,
+ uint size,
+ uint q,
+ bool isShl,
+ Action action,
+ Action actionScalar)
+ {
+ (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl);
+
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ if (size == 3)
+ {
+ actionScalar(tempRegister.Operand, rmReg.Operand, immb, immh);
+ }
+ else
+ {
+ action(tempRegister.Operand, rmReg.Operand, immb, immh, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand, immb, immh, q);
+ }
+ }
+
+ public static void EmitVectorBinaryLong(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action)
+ {
+ Debug.Assert((rd & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ if ((rn & 1) == (rm & 1))
+ {
+ // Both inputs are on the same side of the vector, so we can use the variant that selects the half.
+
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rn & 1;
+
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+ else
+ {
+ // Inputs are on different sides of the vector, we have to move them.
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ action(rdOperand, rnReg.Operand, rmReg.Operand, size, 0);
+ }
+ }
+
+ public static void EmitVectorBinaryLongShift(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint shift,
+ uint size,
+ bool isShl,
+ Action action)
+ {
+ (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl);
+
+ Debug.Assert((rd & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+
+ uint q = rn & 1;
+
+ action(rdOperand, rnOperand, immb, immh, q);
+ }
+
+ public static void EmitVectorBinaryLongByScalar(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ Action action)
+ {
+ Debug.Assert((rd & 1) == 0);
+
+ (uint h, uint l, uint m) = GetIndexForReg(ref rm, size);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rn & 1;
+
+ action(rdOperand, rnOperand, h, rmOperand, m, l, size, q);
+ }
+
+ public static void EmitVectorBinaryNarrow(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ Action action)
+ {
+ Debug.Assert((rn & 1) == 0);
+ Debug.Assert((rm & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rd & 1;
+
+ if (q == 0)
+ {
+ // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action(tempRegister.Operand, rnOperand, rmOperand, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+ }
+
+ public static void EmitVectorBinaryNarrowShift(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint shift,
+ uint size,
+ bool isShl,
+ Action action)
+ {
+ (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl);
+
+ Debug.Assert((rm & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rd & 1;
+
+ if (q == 0)
+ {
+ // Writing to the lower half would clear the higher bits, we don't want that, so use a temp register and move the element.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action(tempRegister.Operand, rmOperand, immb, immh, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ action(rdOperand, rmOperand, immb, immh, q);
+ }
+ }
+
+ public static void EmitVectorBinaryWide(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action)
+ {
+ Debug.Assert(((rd | rn) & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rm & 1;
+
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+
+ public static void EmitVectorBinaryByScalar(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action)
+ {
+ EmitVectorByScalarCore(context, rd, rn, rm, size, q, action, isTernary: false);
+ }
+
+ public static void EmitVectorTernaryRd(CodeGenContext context, uint rd, uint rn, uint rm, uint q, Action action)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rnOperand, rmOperand, q);
+ }
+ }
+
+ public static void EmitVectorTernaryRd(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q, Action action)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+ }
+
+ public static void EmitVectorTernaryRdLong(CodeGenContext context, uint rd, uint rn, uint rm, uint size, Action action)
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ if ((rn & 1) == (rm & 1))
+ {
+ // Both inputs are on the same side of the vector, so we can use the variant that selects the half.
+
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rn & 1;
+
+ action(rdOperand, rnOperand, rmOperand, size, q);
+ }
+ else
+ {
+ // Inputs are on different sides of the vector, we have to move them.
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ action(rdOperand, rnReg.Operand, rmReg.Operand, size, 0);
+ }
+ }
+
+ public static void EmitVectorTernaryRdLongByScalar(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ Action action)
+ {
+ (uint h, uint l, uint m) = GetIndexForReg(ref rm, size);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint q = rn & 1;
+
+ action(rdOperand, rnOperand, h, rmOperand, m, l, size, q);
+ }
+
+ public static void EmitVectorTernaryRdShift(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint shift,
+ uint size,
+ uint q,
+ bool isShl,
+ Action action,
+ Action actionScalar)
+ {
+ (uint immb, uint immh) = GetImmbImmhForShift(shift, size, isShl);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ if (size == 3)
+ {
+ actionScalar(tempRegister.Operand, rmReg.Operand, immb, immh);
+ }
+ else
+ {
+ action(tempRegister.Operand, rmReg.Operand, immb, immh, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand, immb, immh, q);
+ }
+ }
+
+ public static void EmitVectorTernaryRdByScalar(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action)
+ {
+ EmitVectorByScalarCore(context, rd, rn, rm, size, q, action, isTernary: true);
+ }
+
+ private static void EmitVectorByScalarCore(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ bool isTernary)
+ {
+ (uint h, uint l, uint m) = GetIndexForReg(ref rm, size);
+
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (q == 0)
+ {
+ if (isTernary)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+
+ action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg);
+
+ action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, size, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+
+ action(rdOperand, rnOperand, h, rmOperand, m, l, size, q);
+ }
+ }
+
+ public static void EmitVectorUnaryF(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint sz,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ Debug.Assert(sz == 0 || sz == 1);
+
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ if (sz == 1)
+ {
+ actionHalf(tempRegister.Operand, rmReg.Operand, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rmReg.Operand, 0, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (sz == 1)
+ {
+ actionHalf(rdOperand, rmOperand, q);
+ }
+ else
+ {
+ action(rdOperand, rmOperand, 0, q);
+ }
+ }
+ }
+
+ public static void EmitVectorUnaryAnyF(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+ Debug.Assert(size != 3 || q == 1);
+
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ if (size == 1)
+ {
+ actionHalf(tempRegister.Operand, rmReg.Operand, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rmReg.Operand, size ^ 2u, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (size == 1)
+ {
+ actionHalf(rdOperand, rmOperand, q);
+ }
+ else
+ {
+ action(rdOperand, rmOperand, size ^ 2u, q);
+ }
+ }
+ }
+
+ public static void EmitVectorUnaryFixedAnyF(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint fbits,
+ uint size,
+ uint q,
+ Action action)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+ Debug.Assert(size != 3 || q == 1);
+
+ (uint immb, uint immh) = GetImmbImmh(fbits, size);
+
+ if (q == 0)
+ {
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ action(tempRegister.Operand, rmReg.Operand, immb, immh, q);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ action(rdOperand, rmOperand, immb, immh, q);
+ }
+ }
+
+ public static void EmitVectorBinaryF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint sz,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ Debug.Assert(sz == 0 || sz == 1);
+
+ if (q == 0)
+ {
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ if (sz == 1)
+ {
+ actionHalf(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, 0, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (sz == 1)
+ {
+ actionHalf(rdOperand, rnOperand, rmOperand, q);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, rmOperand, 0, q);
+ }
+ }
+ }
+
+ public static void EmitVectorBinaryByScalarAnyF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ EmitVectorByScalarAnyFCore(context, rd, rn, rm, size, q, action, actionHalf, isTernary: false);
+ }
+
+ public static void EmitVectorTernaryRdF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint sz,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ Debug.Assert(sz == 0 || sz == 1);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ if (sz == 1)
+ {
+ actionHalf(tempRegister.Operand, rnReg.Operand, rmReg.Operand, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rnReg.Operand, rmReg.Operand, 0, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (sz == 1)
+ {
+ actionHalf(rdOperand, rnOperand, rmOperand, q);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, rmOperand, 0, q);
+ }
+ }
+ }
+
+ public static void EmitVectorTernaryMulNegRdF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint sz,
+ uint q,
+ bool negProduct)
+ {
+ Debug.Assert(sz == 0 || sz == 1);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = MoveScalarToSide(context, rm, false);
+
+ EmitMulNegVector(context, tempRegister.Operand, rnReg.Operand, rmReg.Operand, sz, q, negProduct);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ EmitMulNegVector(context, rdOperand, rnOperand, rmOperand, sz, q, negProduct);
+ }
+ }
+
+ private static void EmitMulNegVector(
+ CodeGenContext context,
+ Operand rd,
+ Operand rn,
+ Operand rm,
+ uint sz,
+ uint q,
+ bool negProduct)
+ {
+ using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (sz == 1)
+ {
+ context.Arm64Assembler.FmulVecHalf(productRegister.Operand, rn, rm, q);
+
+ if (negProduct)
+ {
+ context.Arm64Assembler.FnegHalf(productRegister.Operand, productRegister.Operand, q);
+ }
+
+ context.Arm64Assembler.FaddHalf(rd, rd, productRegister.Operand, q);
+ }
+ else
+ {
+ context.Arm64Assembler.FmulVecSingleAndDouble(productRegister.Operand, rn, rm, 0, q);
+
+ if (negProduct)
+ {
+ context.Arm64Assembler.FnegSingleAndDouble(productRegister.Operand, productRegister.Operand, 0, q);
+ }
+
+ context.Arm64Assembler.FaddSingleAndDouble(rd, rd, productRegister.Operand, 0, q);
+ }
+ }
+
+ public static void EmitVectorTernaryRdByScalarAnyF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ Action actionHalf)
+ {
+ EmitVectorByScalarAnyFCore(context, rd, rn, rm, size, q, action, actionHalf, isTernary: true);
+ }
+
+ private static void EmitVectorByScalarAnyFCore(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ Action action,
+ Action actionHalf,
+ bool isTernary)
+ {
+ (uint h, uint l, uint m) = GetIndexForReg(ref rm, size);
+
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (q == 0)
+ {
+ if (isTernary)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+
+ if (size == 1)
+ {
+ actionHalf(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, 0, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+
+ using ScopedRegister tempRegister = PickSimdRegister(context.RegisterAllocator, rnReg);
+
+ if (size == 1)
+ {
+ actionHalf(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, q);
+ }
+ else
+ {
+ action(tempRegister.Operand, rnReg.Operand, h, rmOperand, m, l, 0, q);
+ }
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+
+ if (size == 1)
+ {
+ actionHalf(rdOperand, rnOperand, h, rmOperand, m, l, q);
+ }
+ else
+ {
+ action(rdOperand, rnOperand, h, rmOperand, m, l, 0, q);
+ }
+ }
+ }
+
+ public static void EmitVectorTernaryMulNegRdByScalarAnyF(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint rm,
+ uint size,
+ uint q,
+ bool negProduct)
+ {
+ (uint h, uint l, uint m) = GetIndexForReg(ref rm, size);
+
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ using ScopedRegister rnReg = MoveScalarToSide(context, rn, false);
+
+ EmitMulNegVectorByScalar(context, tempRegister.Operand, rnReg.Operand, rmOperand, h, l, m, size, q, negProduct);
+
+ InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+
+ EmitMulNegVectorByScalar(context, rdOperand, rnOperand, rmOperand, h, l, m, size, q, negProduct);
+ }
+ }
+
+ private static void EmitMulNegVectorByScalar(
+ CodeGenContext context,
+ Operand rd,
+ Operand rn,
+ Operand rm,
+ uint h,
+ uint l,
+ uint m,
+ uint sz,
+ uint q,
+ bool negProduct)
+ {
+ using ScopedRegister productRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (sz == 1)
+ {
+ context.Arm64Assembler.FmulElt2regElementHalf(productRegister.Operand, rn, h, rm, m, l, q);
+
+ if (negProduct)
+ {
+ context.Arm64Assembler.FnegHalf(productRegister.Operand, productRegister.Operand, q);
+ }
+
+ context.Arm64Assembler.FaddHalf(rd, rd, productRegister.Operand, q);
+ }
+ else
+ {
+ context.Arm64Assembler.FmulElt2regElementSingleAndDouble(productRegister.Operand, rn, h, rm, m, l, 0, q);
+
+ if (negProduct)
+ {
+ context.Arm64Assembler.FnegSingleAndDouble(productRegister.Operand, productRegister.Operand, 0, q);
+ }
+
+ context.Arm64Assembler.FaddSingleAndDouble(rd, rd, productRegister.Operand, 0, q);
+ }
+ }
+
+ private static (uint, uint, uint) GetIndexForReg(ref uint reg, uint size)
+ {
+ int shift = (int)(size + 2);
+ uint index = reg >> shift;
+ reg &= (1u << shift) - 1;
+ index |= (reg & 1) << (5 - shift);
+
+ uint h, l, m;
+
+ if (size == 1)
+ {
+ Debug.Assert((index >> 3) == 0);
+
+ m = index & 1;
+ l = (index >> 1) & 1;
+ h = index >> 2;
+ }
+ else
+ {
+ Debug.Assert(size == 2);
+ Debug.Assert((index >> 2) == 0);
+
+ m = 0;
+ l = index & 1;
+ h = (index >> 1) & 1;
+ }
+
+ return (h, l, m);
+ }
+
+ private static (uint, uint) GetImmbImmh(uint value, uint size)
+ {
+ Debug.Assert(value > 0 && value <= (8u << (int)size));
+
+ uint imm = (8u << (int)size) | ((8u << (int)size) - value);
+
+ Debug.Assert((imm >> 7) == 0);
+
+ uint immb = imm & 7;
+ uint immh = imm >> 3;
+
+ return (immb, immh);
+ }
+
+ public static (uint, uint) GetImmbImmhForShift(uint value, uint size, bool isShl)
+ {
+ if (isShl)
+ {
+ Debug.Assert(value >= 0 && value < (8u << (int)size));
+
+ uint imm = (8u << (int)size) | (value & (0x3fu >> (int)(3 - size)));
+
+ Debug.Assert((imm >> 7) == 0);
+
+ uint immb = imm & 7;
+ uint immh = imm >> 3;
+
+ return (immb, immh);
+ }
+ else
+ {
+ return GetImmbImmh(value, size);
+ }
+ }
+
+ public static uint GetSizeFromImm6(uint imm6)
+ {
+ if ((imm6 & 0b100000) != 0)
+ {
+ return 2;
+ }
+ else if ((imm6 & 0b10000) != 0)
+ {
+ return 1;
+ }
+ else
+ {
+ Debug.Assert((imm6 & 0b1000) != 0);
+
+ return 0;
+ }
+ }
+
+ public static uint GetSizeFromImm7(uint imm7)
+ {
+ if ((imm7 & 0b1000000) != 0)
+ {
+ return 3;
+ }
+ else if ((imm7 & 0b100000) != 0)
+ {
+ return 2;
+ }
+ else if ((imm7 & 0b10000) != 0)
+ {
+ return 1;
+ }
+ else
+ {
+ Debug.Assert((imm7 & 0b1000) != 0);
+
+ return 0;
+ }
+ }
+
+ public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1)
+ {
+ if (option1.IsAllocated)
+ {
+ return option1;
+ }
+
+ return registerAllocator.AllocateTempSimdRegisterScoped();
+ }
+
+ public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1, ScopedRegister option2)
+ {
+ if (option1.IsAllocated)
+ {
+ return option1;
+ }
+ else if (option2.IsAllocated)
+ {
+ return option2;
+ }
+
+ return registerAllocator.AllocateTempSimdRegisterScoped();
+ }
+
+ public static ScopedRegister PickSimdRegister(RegisterAllocator registerAllocator, ScopedRegister option1, ScopedRegister option2, ScopedRegister option3)
+ {
+ if (option1.IsAllocated)
+ {
+ return option1;
+ }
+ else if (option2.IsAllocated)
+ {
+ return option2;
+ }
+ else if (option3.IsAllocated)
+ {
+ return option3;
+ }
+
+ return registerAllocator.AllocateTempSimdRegisterScoped();
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs
new file mode 100644
index 00000000..8da99385
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs
@@ -0,0 +1,126 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonCompare
+ {
+ public static void Vacge(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FacgeV, context.Arm64Assembler.FacgeVH);
+ }
+
+ public static void Vacgt(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FacgtV, context.Arm64Assembler.FacgtVH);
+ }
+
+ public static void VceqI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmeqZeroV, context.Arm64Assembler.FcmeqZeroVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmeqZeroV);
+ }
+ }
+
+ public static void VceqR(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.CmeqRegV, context.Arm64Assembler.CmeqRegS);
+ }
+
+ public static void VceqFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmeqRegV, context.Arm64Assembler.FcmeqRegVH);
+ }
+
+ public static void VcgeI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmgeZeroV, context.Arm64Assembler.FcmgeZeroVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmgeZeroV);
+ }
+ }
+
+ public static void VcgeR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rn,
+ rm,
+ size,
+ q,
+ u ? context.Arm64Assembler.CmhsV : context.Arm64Assembler.CmgeRegV,
+ u ? context.Arm64Assembler.CmhsS : context.Arm64Assembler.CmgeRegS);
+ }
+
+ public static void VcgeFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmgeRegV, context.Arm64Assembler.FcmgeRegVH);
+ }
+
+ public static void VcgtI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmgtZeroV, context.Arm64Assembler.FcmgtZeroVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmgtZeroV);
+ }
+ }
+
+ public static void VcgtR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rn,
+ rm,
+ size,
+ q,
+ u ? context.Arm64Assembler.CmhiV : context.Arm64Assembler.CmgtRegV,
+ u ? context.Arm64Assembler.CmhiS : context.Arm64Assembler.CmgtRegS);
+ }
+
+ public static void VcgtFR(CodeGenContext context, uint rd, uint rn, uint rm, uint sz, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryF(context, rd, rn, rm, sz, q, context.Arm64Assembler.FcmgtRegV, context.Arm64Assembler.FcmgtRegVH);
+ }
+
+ public static void VcleI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmleV, context.Arm64Assembler.FcmleVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmleV);
+ }
+ }
+
+ public static void VcltI(CodeGenContext context, uint rd, uint rm, bool f, uint size, uint q)
+ {
+ if (f)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcmltV, context.Arm64Assembler.FcmltVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.CmltV);
+ }
+ }
+
+ public static void Vtst(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.CmtstV, context.Arm64Assembler.CmtstS);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs
new file mode 100644
index 00000000..81fce678
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonConvert
+ {
+ public static void Vcvta(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ if (op)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtauV, context.Arm64Assembler.FcvtauVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtasV, context.Arm64Assembler.FcvtasVH);
+ }
+ }
+
+ public static void Vcvtm(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ if (op)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtmuV, context.Arm64Assembler.FcvtmuVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtmsV, context.Arm64Assembler.FcvtmsVH);
+ }
+ }
+
+ public static void Vcvtn(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ if (op)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtnuV, context.Arm64Assembler.FcvtnuVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtnsV, context.Arm64Assembler.FcvtnsVH);
+ }
+ }
+
+ public static void Vcvtp(CodeGenContext context, uint rd, uint rm, bool op, uint size, uint q)
+ {
+ if (op)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtpuV, context.Arm64Assembler.FcvtpuVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtpsV, context.Arm64Assembler.FcvtpsVH);
+ }
+ }
+
+ public static void VcvtHs(CodeGenContext context, uint rd, uint rm, bool op)
+ {
+ bool halfToSingle = op;
+ if (halfToSingle)
+ {
+ // Half to single.
+
+ InstEmitNeonCommon.EmitVectorUnaryLong(context, rd, rm, 0, context.Arm64Assembler.Fcvtl);
+ }
+ else
+ {
+ // Single to half.
+
+ InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, 0, context.Arm64Assembler.Fcvtn);
+ }
+ }
+
+ public static void VcvtIs(CodeGenContext context, uint rd, uint rm, uint op, uint size, uint q)
+ {
+ Debug.Assert(op >> 2 == 0);
+
+ bool unsigned = (op & 1) != 0;
+ bool toInteger = (op >> 1) != 0;
+
+ if (toInteger)
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtzuIntV, context.Arm64Assembler.FcvtzuIntVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FcvtzsIntV, context.Arm64Assembler.FcvtzsIntVH);
+ }
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.UcvtfIntV, context.Arm64Assembler.UcvtfIntVH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.ScvtfIntV, context.Arm64Assembler.ScvtfIntVH);
+ }
+ }
+ }
+
+ public static void VcvtXs(CodeGenContext context, uint rd, uint rm, uint imm6, uint op, bool u, uint q)
+ {
+ Debug.Assert(op >> 2 == 0);
+
+ bool unsigned = u;
+ bool toFixed = (op & 1) != 0;
+ uint size = 1 + (op >> 1);
+ uint fbits = Math.Clamp(64u - imm6, 1, 8u << (int)size);
+
+ if (toFixed)
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.FcvtzuFixV);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.FcvtzsFixV);
+ }
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.UcvtfFixV);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryFixedAnyF(context, rd, rm, fbits, size, q, context.Arm64Assembler.ScvtfFixV);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs
new file mode 100644
index 00000000..a36ae82c
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs
@@ -0,0 +1,43 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonCrypto
+ {
+ public static void Aesd(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 0);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesd);
+ }
+
+ public static void Aese(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 0);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aese);
+ }
+
+ public static void Aesimc(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 0);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesimc);
+ }
+
+ public static void Aesmc(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 0);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Aesmc);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs
new file mode 100644
index 00000000..57090ac8
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs
@@ -0,0 +1,97 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonHash
+ {
+ public static void Sha1c(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1c);
+ }
+
+ public static void Sha1h(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 2);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha1h);
+ }
+
+ public static void Sha1m(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1m);
+ }
+
+ public static void Sha1p(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1p);
+ }
+
+ public static void Sha1su0(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha1su0);
+ }
+
+ public static void Sha1su1(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 2);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha1su1);
+ }
+
+ public static void Sha256h(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256h);
+ }
+
+ public static void Sha256h2(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256h2);
+ }
+
+ public static void Sha256su0(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(size == 2);
+
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, context.Arm64Assembler.Sha256su0);
+ }
+
+ public static void Sha256su1(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ // TODO: Feature check, emulation if not supported.
+
+ Debug.Assert(q == 1);
+
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, context.Arm64Assembler.Sha256su1);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs
new file mode 100644
index 00000000..af2e54cc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs
@@ -0,0 +1,79 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonLogical
+ {
+ public static void VandR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.And);
+ }
+
+ public static void VbicI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q)
+ {
+ EmitMovi(context, rd, cmode, imm8, 1, q);
+ }
+
+ public static void VbicR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.BicReg);
+ }
+
+ public static void VbifR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bif);
+ }
+
+ public static void VbitR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bit);
+ }
+
+ public static void VbslR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, q, context.Arm64Assembler.Bsl);
+ }
+
+ public static void VeorR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.Eor);
+ }
+
+ public static void VornR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.Orn);
+ }
+
+ public static void VorrI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q)
+ {
+ EmitMovi(context, rd, cmode, imm8, 0, q);
+ }
+
+ public static void VorrR(CodeGenContext context, uint rd, uint rn, uint rm, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, q, context.Arm64Assembler.OrrReg);
+ }
+
+ private static void EmitMovi(CodeGenContext context, uint rd, uint cmode, uint imm8, uint op, uint q)
+ {
+ (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = InstEmitNeonMove.Split(imm8);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ context.Arm64Assembler.Movi(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, op, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.Movi(rdOperand, h, g, f, e, d, cmode, c, b, a, op, q);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs
new file mode 100644
index 00000000..e77dc0a2
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs
@@ -0,0 +1,797 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonMemory
+ {
+ public static void Vld11(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+
+ EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) =>
+ {
+ EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 1, 1, context.Arm64Assembler.Ld1SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vld1A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) =>
+ {
+ EmitMemoryLoad1SingleReplicateInstruction(context, address, rd, size, t + 1, 1, context.Arm64Assembler.Ld1rAsNoPostIndex);
+ });
+ }
+
+ public static void Vld1M(CodeGenContext context, uint rd, uint rn, uint rm, uint registersCount, uint align, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 8 * (int)registersCount, (address) =>
+ {
+ EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, registersCount, 1, context.Arm64Assembler.Ld1MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vld21(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 2, step, context.Arm64Assembler.Ld2SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vld2A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 2, t + 1, context.Arm64Assembler.Ld2rAsNoPostIndex);
+ });
+ }
+
+ public static void Vld2M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 16, (address) =>
+ {
+ EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 2, step, context.Arm64Assembler.Ld2MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vld2M(CodeGenContext context, uint rd, uint rn, uint rm, uint align, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 32, (address) =>
+ {
+ EmitMemoryLoad1234Multiple2x2Instruction(context, address, rd, size, context.Arm64Assembler.Ld2MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vld31(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 3, step, context.Arm64Assembler.Ld3SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vld3A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 3, t + 1, context.Arm64Assembler.Ld3rAsNoPostIndex);
+ });
+ }
+
+ public static void Vld3M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 24, (address) =>
+ {
+ EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 3, step, context.Arm64Assembler.Ld3MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vld41(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad1234SingleInstruction(context, address, rd, index, size, 4, step, context.Arm64Assembler.Ld4SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vld4A(CodeGenContext context, uint rd, uint rn, uint rm, uint a, uint t, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryLoad234SingleReplicateInstruction(context, address, rd, size, 4, t + 1, context.Arm64Assembler.Ld4rAsNoPostIndex);
+ });
+ }
+
+ public static void Vld4M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 32, (address) =>
+ {
+ EmitMemoryLoad1234MultipleInstruction(context, address, rd, size, 4, step, context.Arm64Assembler.Ld4MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vldm(CodeGenContext context, uint rd, uint rn, uint registerCount, bool u, bool w, bool singleRegs)
+ {
+ EmitMemoryMultipleInstruction(context, rd, rn, registerCount, u, w, singleRegs, isStore: false);
+ }
+
+ public static void Vldr(CodeGenContext context, uint rd, uint rn, uint imm8, bool u, uint size)
+ {
+ EmitMemoryInstruction(context, rd, rn, imm8, u, size, isStore: false);
+ }
+
+ public static void Vst11(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+
+ EmitMemory1234InstructionCore(context, rn, rm, 1 << (int)size, (address) =>
+ {
+ EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 1, 1, context.Arm64Assembler.St1SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vst1M(CodeGenContext context, uint rd, uint rn, uint rm, uint registersCount, uint align, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 8 * (int)registersCount, (address) =>
+ {
+ EmitMemoryStore1234MultipleInstruction(context, address, rd, size, registersCount, 1, context.Arm64Assembler.St1MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vst21(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 2 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 2, step, context.Arm64Assembler.St2SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vst2M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 16, (address) =>
+ {
+ EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 2, step, context.Arm64Assembler.St2MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vst2M(CodeGenContext context, uint rd, uint rn, uint rm, uint align, uint size)
+ {
+ EmitMemory1234InstructionCore(context, rn, rm, 32, (address) =>
+ {
+ EmitMemoryStore1234Multiple2x2Instruction(context, address, rd, size, context.Arm64Assembler.St2MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vst31(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 3 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 3, step, context.Arm64Assembler.St3SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vst3M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 24, (address) =>
+ {
+ EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 3, step, context.Arm64Assembler.St3MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vst41(CodeGenContext context, uint rd, uint rn, uint rm, uint indexAlign, uint size)
+ {
+ uint index = indexAlign >> ((int)size + 1);
+ uint step = size > 0 && (indexAlign & (1u << (int)size)) != 0 ? 2u : 1u;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 4 * (1 << (int)size), (address) =>
+ {
+ EmitMemoryStore1234SingleInstruction(context, address, rd, index, size, 4, step, context.Arm64Assembler.St4SnglAsNoPostIndex);
+ });
+ }
+
+ public static void Vst4M(CodeGenContext context, uint rd, uint rn, uint rm, uint type, uint align, uint size)
+ {
+ uint step = (type & 1) + 1;
+
+ EmitMemory1234InstructionCore(context, rn, rm, 32, (address) =>
+ {
+ EmitMemoryStore1234MultipleInstruction(context, address, rd, size, 4, step, context.Arm64Assembler.St4MultAsNoPostIndex);
+ });
+ }
+
+ public static void Vstm(CodeGenContext context, uint rd, uint rn, uint registerCount, bool u, bool w, bool singleRegs)
+ {
+ EmitMemoryMultipleInstruction(context, rd, rn, registerCount, u, w, singleRegs, isStore: true);
+ }
+
+ public static void Vstr(CodeGenContext context, uint rd, uint rn, uint imm8, bool u, uint size)
+ {
+ EmitMemoryInstruction(context, rd, rn, imm8, u, size, isStore: true);
+ }
+
+ private static void EmitMemoryMultipleInstruction(
+ CodeGenContext context,
+ uint rd,
+ uint rn,
+ uint registerCount,
+ bool add,
+ bool wBack,
+ bool singleRegs,
+ bool isStore)
+ {
+ Operand baseAddress = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand offset = InstEmitCommon.Const((int)registerCount * (singleRegs ? 4 : 8));
+
+ if (!add)
+ {
+ if (wBack)
+ {
+ InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
+ }
+ else
+ {
+ InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
+ }
+ }
+ else
+ {
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
+ }
+
+ EmitMemoryMultipleInstructionCore(context, tempRegister.Operand, rd, registerCount, singleRegs, isStore);
+
+ if (add && wBack)
+ {
+ context.Arm64Assembler.Add(baseAddress, baseAddress, offset);
+ }
+ }
+
+ private static void EmitMemoryMultipleInstructionCore(CodeGenContext context, Operand baseAddress, uint rd, uint registerCount, bool singleRegs, bool isStore)
+ {
+ int offs = 0;
+ uint r = rd;
+ uint upperBound = Math.Min(rd + registerCount, 32u);
+ uint regMask = singleRegs ? 3u : 1u;
+
+ // Read/write misaligned elements first.
+
+ for (; (r & regMask) != 0 && r < upperBound; r++)
+ {
+ EmitMemoryInstruction(context, baseAddress, r, offs, singleRegs, isStore);
+
+ offs += singleRegs ? 4 : 8;
+ }
+
+ // Read/write aligned, full vectors.
+
+ while (upperBound - r >= (singleRegs ? 4 : 2))
+ {
+ int qIndex = (int)(r >> (singleRegs ? 2 : 1));
+
+ Operand rtOperand = context.RegisterAllocator.RemapSimdRegister(qIndex);
+
+ if (upperBound - r >= (singleRegs ? 8 : 4) && (offs & 0xf) == 0)
+ {
+ Operand rt2Operand = context.RegisterAllocator.RemapSimdRegister(qIndex + 1);
+
+ if (isStore)
+ {
+ context.Arm64Assembler.StpRiUn(rtOperand, rt2Operand, baseAddress, offs);
+ }
+ else
+ {
+ context.Arm64Assembler.LdpRiUn(rtOperand, rt2Operand, baseAddress, offs);
+ }
+
+ r += singleRegs ? 8u : 4u;
+ offs += 32;
+ }
+ else
+ {
+ if ((offs & 0xf) == 0)
+ {
+ if (isStore)
+ {
+ context.Arm64Assembler.StrRiUn(rtOperand, baseAddress, offs);
+ }
+ else
+ {
+ context.Arm64Assembler.LdrRiUn(rtOperand, baseAddress, offs);
+ }
+ }
+ else
+ {
+ if (isStore)
+ {
+ context.Arm64Assembler.Stur(rtOperand, baseAddress, offs);
+ }
+ else
+ {
+ context.Arm64Assembler.Ldur(rtOperand, baseAddress, offs);
+ }
+ }
+
+ r += singleRegs ? 4u : 2u;
+ offs += 16;
+ }
+ }
+
+ // Read/write last misaligned elements.
+
+ for (; r < upperBound; r++)
+ {
+ EmitMemoryInstruction(context, baseAddress, r, offs, singleRegs, isStore);
+
+ offs += singleRegs ? 4 : 8;
+ }
+ }
+
+ private static void EmitMemoryInstruction(CodeGenContext context, Operand baseAddress, uint r, int offs, bool singleRegs, bool isStore)
+ {
+ if (isStore)
+ {
+ using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, r, singleRegs);
+
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, baseAddress, offs);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs);
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, baseAddress, offs);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, r, singleRegs);
+ }
+ }
+
+ private static void EmitMemoryInstruction(CodeGenContext context, uint rd, uint rn, uint imm8, bool add, uint size, bool isStore)
+ {
+ bool singleRegs = size != 3;
+ int offs = (int)imm8;
+
+ if (size == 1)
+ {
+ offs <<= 1;
+ }
+ else
+ {
+ offs <<= 2;
+ }
+
+ using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (rn == RegisterUtils.PcRegister)
+ {
+ if (!add)
+ {
+ offs = -offs;
+ }
+
+ context.Arm64Assembler.Mov(address.Operand, (context.Pc & ~3u) + (uint)offs);
+
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand);
+
+ offs = 0;
+ }
+ else
+ {
+ Operand rnOperand = context.RegisterAllocator.RemapGprRegister((int)rn);
+
+ if (InstEmitMemory.CanFoldOffset(context.MemoryManagerType, add ? offs : -offs, (int)size, true, out _))
+ {
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand);
+
+ if (!add)
+ {
+ offs = -offs;
+ }
+ }
+ else
+ {
+ InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, address.Operand, rnOperand, InstEmitCommon.Const(offs), add, ArmShiftType.Lsl, 0);
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand);
+
+ offs = 0;
+ }
+ }
+
+ if ((size == 3 && (offs & 7) != 0) || offs < 0)
+ {
+ if (isStore)
+ {
+ using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs);
+
+ context.Arm64Assembler.Stur(tempRegister.Operand, address.Operand, offs, size);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs);
+
+ context.Arm64Assembler.Ldur(tempRegister.Operand, address.Operand, offs, size);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+ }
+ else
+ {
+ if (isStore)
+ {
+ using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs);
+
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, address.Operand, offs, size);
+ }
+ else
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(singleRegs);
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, address.Operand, offs, size);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+ }
+ }
+
+ private static void EmitMemory1234InstructionCore(CodeGenContext context, uint rn, uint rm, int bytes, Action callback)
+ {
+ bool wBack = rm != RegisterUtils.PcRegister;
+ bool registerIndex = rm != RegisterUtils.PcRegister && rm != RegisterUtils.SpRegister;
+
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand);
+
+ callback(address.Operand);
+
+ if (wBack)
+ {
+ if (registerIndex)
+ {
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ context.Arm64Assembler.Add(rnOperand, rnOperand, rmOperand);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(rnOperand, rnOperand, InstEmitCommon.Const(bytes));
+ }
+ }
+ }
+
+ private static void EmitMemoryLoad1234SingleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint index,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters);
+
+ action(tempRegisters[0].Operand, baseAddress, index, size);
+
+ MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryLoad1SingleReplicateInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ if ((rd & 1) == 0 && registerCount == 2)
+ {
+ action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1)), baseAddress, size, 1);
+ }
+ else
+ {
+ uint vecsCount = (registerCount + 1) >> 1;
+
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)vecsCount);
+
+ action(tempRegisters[0].Operand, baseAddress, size, registerCount > 1 ? 1u : 0u);
+
+ MoveQuadwordsToDoublewords(context, rd, registerCount, step, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+ }
+
+ private static void EmitMemoryLoad234SingleReplicateInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ action(tempRegisters[0].Operand, baseAddress, size, 0u);
+
+ MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryLoad1234MultipleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ action(tempRegisters[0].Operand, baseAddress, size, 0);
+
+ MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryLoad1234MultipleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ action(tempRegisters[0].Operand, baseAddress, registerCount, size, 0);
+
+ MoveQuadwordsLowerToDoublewords(context, rd, registerCount, step, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryLoad1234Multiple2x2Instruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ Action action)
+ {
+ if ((rd & 1) == 0)
+ {
+ action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1), 2), baseAddress, size, 1);
+ }
+ else
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, 2);
+
+ action(tempRegisters[0].Operand, baseAddress, size, 1);
+
+ MoveQuadwordsToDoublewords2x2(context, rd, tempRegisters);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+ }
+
+ private static void EmitMemoryStore1234SingleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint index,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters);
+
+ action(tempRegisters[0].Operand, baseAddress, index, size);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryStore1234MultipleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters);
+
+ action(tempRegisters[0].Operand, baseAddress, size, 0);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryStore1234MultipleInstruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ uint registerCount,
+ uint step,
+ Action action)
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, (int)registerCount);
+
+ MoveDoublewordsToQuadwordsLower(context, rd, registerCount, step, tempRegisters);
+
+ action(tempRegisters[0].Operand, baseAddress, registerCount, size, 0);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+
+ private static void EmitMemoryStore1234Multiple2x2Instruction(
+ CodeGenContext context,
+ Operand baseAddress,
+ uint rd,
+ uint size,
+ Action action)
+ {
+ if ((rd & 1) == 0)
+ {
+ action(context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1), 2), baseAddress, size, 1);
+ }
+ else
+ {
+ ScopedRegister[] tempRegisters = AllocateSequentialRegisters(context, 2);
+
+ MoveDoublewordsToQuadwords2x2(context, rd, tempRegisters);
+
+ action(tempRegisters[0].Operand, baseAddress, size, 1);
+
+ FreeSequentialRegisters(tempRegisters);
+ }
+ }
+
+ private static ScopedRegister[] AllocateSequentialRegisters(CodeGenContext context, int count)
+ {
+ ScopedRegister[] registers = new ScopedRegister[count];
+
+ for (int index = 0; index < count; index++)
+ {
+ registers[index] = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+ }
+
+ AssertSequentialRegisters(registers);
+
+ return registers;
+ }
+
+ private static void FreeSequentialRegisters(ReadOnlySpan registers)
+ {
+ for (int index = 0; index < registers.Length; index++)
+ {
+ registers[index].Dispose();
+ }
+ }
+
+ [Conditional("DEBUG")]
+ private static void AssertSequentialRegisters(ReadOnlySpan registers)
+ {
+ for (int index = 1; index < registers.Length; index++)
+ {
+ Debug.Assert(registers[index].Operand.GetRegister().Index == registers[0].Operand.GetRegister().Index + index);
+ }
+ }
+
+ private static void MoveQuadwordsLowerToDoublewords(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers)
+ {
+ for (int index = 0; index < registerCount; index++)
+ {
+ uint r = rd + (uint)index * step;
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1));
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false);
+ context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 0, imm5);
+ }
+ }
+
+ private static void MoveDoublewordsToQuadwordsLower(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers)
+ {
+ for (int index = 0; index < registerCount; index++)
+ {
+ uint r = rd + (uint)index * step;
+
+ InstEmitNeonCommon.MoveScalarToSide(context, registers[index].Operand, r, false);
+ }
+ }
+
+ private static void MoveDoublewordsToQuadwords2x2(CodeGenContext context, uint rd, ReadOnlySpan registers)
+ {
+ for (int index = 0; index < 2; index++)
+ {
+ uint r = rd + (uint)index * 2;
+ uint r2 = r + 1;
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1));
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(0, false);
+ context.Arm64Assembler.InsElt(registers[index].Operand, rdOperand, (r & 1u) << 3, imm5);
+
+ rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r2 >> 1));
+ imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(1, false);
+ context.Arm64Assembler.InsElt(registers[index].Operand, rdOperand, (r2 & 1u) << 3, imm5);
+ }
+ }
+
+ private static void MoveQuadwordsToDoublewords(CodeGenContext context, uint rd, uint registerCount, uint step, ReadOnlySpan registers)
+ {
+ for (int index = 0; index < registerCount; index++)
+ {
+ uint r = rd + (uint)index * step;
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1));
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false);
+ context.Arm64Assembler.InsElt(rdOperand, registers[index >> 1].Operand, ((uint)index & 1u) << 3, imm5);
+ }
+ }
+
+ private static void MoveQuadwordsToDoublewords2x2(CodeGenContext context, uint rd, ReadOnlySpan registers)
+ {
+ for (int index = 0; index < 2; index++)
+ {
+ uint r = rd + (uint)index * 2;
+ uint r2 = r + 1;
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r >> 1));
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r & 1u, false);
+ context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 0, imm5);
+
+ rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(r2 >> 1));
+ imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(r2 & 1u, false);
+ context.Arm64Assembler.InsElt(rdOperand, registers[index].Operand, 1u << 3, imm5);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs
new file mode 100644
index 00000000..08a0673a
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs
@@ -0,0 +1,665 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonMove
+ {
+ public static void VdupR(CodeGenContext context, uint rd, uint rt, uint b, uint e, uint q)
+ {
+ uint size = 2 - (e | (b << 1));
+
+ Debug.Assert(size < 3);
+
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(0, size);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.DupGen(tempRegister.Operand, rtOperand, imm5, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Debug.Assert((rd & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.DupGen(rdOperand, rtOperand, imm5, q);
+ }
+ }
+
+ public static void VdupS(CodeGenContext context, uint rd, uint rm, uint imm4, uint q)
+ {
+ uint size = (uint)BitOperations.TrailingZeroCount(imm4);
+
+ Debug.Assert(size < 3);
+
+ uint index = imm4 >> (int)(size + 1);
+
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(index | ((rm & 1) << (int)(3 - size)), size);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.DupEltVectorFromElement(tempRegister.Operand, rmOperand, imm5, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Debug.Assert((rd & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.DupEltVectorFromElement(rdOperand, rmOperand, imm5, q);
+ }
+ }
+
+ public static void Vext(CodeGenContext context, uint rd, uint rn, uint rm, uint imm4, uint q)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister rnReg = InstEmitNeonCommon.MoveScalarToSide(context, rn, false);
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ context.Arm64Assembler.Ext(tempRegister.Operand, rnReg.Operand, imm4, rmReg.Operand, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Debug.Assert(((rd | rn | rm) & 1) == 0);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rnOperand = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ context.Arm64Assembler.Ext(rdOperand, rnOperand, imm4, rmOperand, q);
+ }
+ }
+
+ public static void Vmovl(CodeGenContext context, uint rd, uint rm, bool u, uint imm3h)
+ {
+ uint size = (uint)BitOperations.TrailingZeroCount(imm3h);
+ Debug.Assert(size < 3);
+
+ InstEmitNeonCommon.EmitVectorBinaryLongShift(
+ context,
+ rd,
+ rm,
+ 0,
+ size,
+ isShl: true,
+ u ? context.Arm64Assembler.Ushll : context.Arm64Assembler.Sshll);
+ }
+
+ public static void Vmovn(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ Debug.Assert(size < 3);
+
+ InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, context.Arm64Assembler.Xtn);
+ }
+
+ public static void Vmovx(CodeGenContext context, uint rd, uint rm)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryShift(context, rd, rm, 16, 2, isShl: false, context.Arm64Assembler.UshrS);
+ }
+
+ public static void VmovD(CodeGenContext context, uint rt, uint rt2, uint rm, bool op)
+ {
+ Operand rmReg = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ uint top = rm & 1;
+ uint ftype = top + 1;
+
+ if (op)
+ {
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2);
+
+ Operand rtOperand64 = new(OperandKind.Register, OperandType.I64, rtOperand.Value);
+ Operand rt2Operand64 = new(OperandKind.Register, OperandType.I64, rt2Operand.Value);
+
+ context.Arm64Assembler.FmovFloatGen(rtOperand64, rmReg, ftype, 1, 0, top);
+
+ context.Arm64Assembler.Lsr(rt2Operand64, rtOperand64, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Mov(rtOperand, rtOperand); // Zero-extend.
+ }
+ else
+ {
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempRegister64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value);
+
+ context.Arm64Assembler.Lsl(tempRegister64, rt2Operand, InstEmitCommon.Const(32));
+ context.Arm64Assembler.Orr(tempRegister64, tempRegister64, rtOperand);
+
+ if (top == 0)
+ {
+ // Doing FMOV on Rm directly would clear the high bits if we are moving to the bottom.
+
+ using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.FmovFloatGen(tempRegister2.Operand, tempRegister64, ftype, 1, 1, top);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rm, false);
+ }
+ else
+ {
+ context.Arm64Assembler.FmovFloatGen(rmReg, tempRegister64, ftype, 1, 1, top);
+ }
+ }
+ }
+
+ public static void VmovH(CodeGenContext context, uint rt, uint rn, bool op)
+ {
+ if (op)
+ {
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+
+ using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rn, true);
+
+ context.Arm64Assembler.FmovFloatGen(rtOperand, tempRegister.Operand, 3, 0, 0, 0);
+ }
+ else
+ {
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 3, 0, 1, 0);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rn, true);
+ }
+ }
+
+ public static void VmovI(CodeGenContext context, uint rd, uint op, uint cmode, uint imm8, uint q)
+ {
+ (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(imm8);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.Movi(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, op, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.Movi(rdOperand, h, g, f, e, d, cmode, c, b, a, op, q);
+ }
+ }
+
+ public static void VmovFI(CodeGenContext context, uint rd, uint imm8, uint size)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.FmovFloatImm(tempRegister.Operand, imm8, size ^ 2u);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, size != 3);
+ }
+
+ public static void VmovR(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ bool singleRegister = size == 2;
+
+ int shift = singleRegister ? 2 : 1;
+ uint mask = singleRegister ? 3u : 1u;
+ uint dstElt = rd & mask;
+ uint srcElt = rm & mask;
+
+ uint imm4 = srcElt << (singleRegister ? 2 : 3);
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(dstElt, singleRegister);
+
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> shift));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> shift));
+
+ context.Arm64Assembler.InsElt(rdOperand, rmOperand, imm4, imm5);
+ }
+
+ public static void VmovRs(CodeGenContext context, uint rd, uint rt, uint opc1, uint opc2)
+ {
+ uint index;
+ uint size;
+
+ if ((opc1 & 2u) != 0)
+ {
+ index = opc2 | ((opc1 & 1u) << 2);
+ size = 0;
+ }
+ else if ((opc2 & 1u) != 0)
+ {
+ index = (opc2 >> 1) | ((opc1 & 1u) << 1);
+ size = 1;
+ }
+ else
+ {
+ Debug.Assert(opc1 == 0 || opc1 == 1);
+ Debug.Assert(opc2 == 0);
+
+ index = opc1 & 1u;
+ size = 2;
+ }
+
+ index |= (rd & 1u) << (int)(3 - size);
+
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ Operand rdReg = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.InsGen(rdReg, rtOperand, InstEmitNeonCommon.GetImm5ForElementIndex(index, size));
+ }
+
+ public static void VmovS(CodeGenContext context, uint rt, uint rn, bool op)
+ {
+ if (op)
+ {
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+
+ using ScopedRegister tempRegister = InstEmitNeonCommon.MoveScalarToSide(context, rn, true);
+
+ context.Arm64Assembler.FmovFloatGen(rtOperand, tempRegister.Operand, 0, 0, 0, 0);
+ }
+ else
+ {
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 0, 0, 1, 0);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rn, true);
+ }
+ }
+
+ public static void VmovSr(CodeGenContext context, uint rt, uint rn, bool u, uint opc1, uint opc2)
+ {
+ uint index;
+ uint size;
+
+ if ((opc1 & 2u) != 0)
+ {
+ index = opc2 | ((opc1 & 1u) << 2);
+ size = 0;
+ }
+ else if ((opc2 & 1u) != 0)
+ {
+ index = (opc2 >> 1) | ((opc1 & 1u) << 1);
+ size = 1;
+ }
+ else
+ {
+ Debug.Assert(opc1 == 0 || opc1 == 1);
+ Debug.Assert(opc2 == 0);
+ Debug.Assert(!u);
+
+ index = opc1 & 1u;
+ size = 2;
+ }
+
+ index |= (rn & 1u) << (int)(3 - size);
+
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+
+ Operand rnReg = context.RegisterAllocator.RemapSimdRegister((int)(rn >> 1));
+
+ if (u || size > 1)
+ {
+ context.Arm64Assembler.Umov(rtOperand, rnReg, (int)index, (int)size);
+ }
+ else
+ {
+ context.Arm64Assembler.Smov(rtOperand, rnReg, (int)index, (int)size);
+ }
+ }
+
+ public static void VmovSs(CodeGenContext context, uint rt, uint rt2, uint rm, bool op)
+ {
+ if ((rm & 1) == 0)
+ {
+ // If we are moving an aligned pair of single-precision registers,
+ // we can just move a single double-precision register.
+
+ VmovD(context, rt, rt2, rm >> 1, op);
+
+ return;
+ }
+
+ if (op)
+ {
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetOutputGpr(context, rt2);
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, true);
+ using ScopedRegister rmReg2 = InstEmitNeonCommon.MoveScalarToSide(context, rm + 1, true);
+
+ context.Arm64Assembler.FmovFloatGen(rtOperand, rmReg.Operand, 0, 0, 0, 0);
+ context.Arm64Assembler.FmovFloatGen(rt2Operand, rmReg2.Operand, 0, 0, 0, 0);
+ }
+ else
+ {
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+ Operand rt2Operand = InstEmitCommon.GetInputGpr(context, rt2);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rtOperand, 0, 0, 1, 0);
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm, true);
+
+ context.Arm64Assembler.FmovFloatGen(tempRegister.Operand, rt2Operand, 0, 0, 1, 0);
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm + 1, true);
+ }
+ }
+
+ public static void VmvnI(CodeGenContext context, uint rd, uint cmode, uint imm8, uint q)
+ {
+ (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(imm8);
+
+ if (q == 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ context.Arm64Assembler.Mvni(tempRegister.Operand, h, g, f, e, d, cmode, c, b, a, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+
+ context.Arm64Assembler.Mvni(rdOperand, h, g, f, e, d, cmode, c, b, a, q);
+ }
+ }
+
+ public static void VmvnR(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, q, context.Arm64Assembler.Not);
+ }
+
+ public static void Vswp(CodeGenContext context, uint rd, uint rm, uint q)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (q == 0)
+ {
+ InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false);
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false);
+
+ InstEmitNeonCommon.InsertResult(context, rmReg.Operand, rd, false);
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rm, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ context.Arm64Assembler.Orr(tempRegister.Operand, rdOperand, rdOperand); // Temp = Rd
+ context.Arm64Assembler.Orr(rdOperand, rmOperand, rmOperand); // Rd = Rm
+ context.Arm64Assembler.Orr(rmOperand, tempRegister.Operand, tempRegister.Operand); // Rm = Temp
+ }
+ }
+
+ public static void Vtbl(CodeGenContext context, uint rd, uint rn, uint rm, bool op, uint len)
+ {
+ // On AArch64, TBL/TBX works with 128-bit vectors, while on AArch32 it works with 64-bit vectors.
+ // We must combine the 64-bit vectors into a larger 128-bit one in some cases.
+
+ // TODO: Peephole optimization to combine adjacent TBL instructions?
+
+ Debug.Assert(len <= 3);
+
+ bool isTbl = !op;
+
+ len = Math.Min(len, 31 - rn);
+
+ bool rangeMismatch = !isTbl && (len & 1) == 0;
+
+ using ScopedRegister indicesReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false, rangeMismatch);
+
+ if (rangeMismatch)
+ {
+ // Force any index >= 8 * regs to be the maximum value, since on AArch64 we are working with a full vector,
+ // and the out of range value is 16 * regs, not 8 * regs.
+
+ Debug.Assert(indicesReg.IsAllocated);
+
+ using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (len == 0)
+ {
+ (uint immb, uint immh) = InstEmitNeonCommon.GetImmbImmhForShift(3, 0, isShl: false);
+
+ context.Arm64Assembler.UshrV(tempRegister2.Operand, indicesReg.Operand, immb, immh, 0);
+ context.Arm64Assembler.CmeqZeroV(tempRegister2.Operand, tempRegister2.Operand, 0, 0);
+ context.Arm64Assembler.Orn(indicesReg.Operand, indicesReg.Operand, tempRegister2.Operand, 0);
+ }
+ else
+ {
+ (uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h) = Split(8u * (len + 1));
+
+ context.Arm64Assembler.Movi(tempRegister2.Operand, h, g, f, e, d, 0xe, c, b, a, 0, 0);
+ context.Arm64Assembler.CmgeRegV(tempRegister2.Operand, indicesReg.Operand, tempRegister2.Operand, 0, 0);
+ context.Arm64Assembler.OrrReg(indicesReg.Operand, indicesReg.Operand, tempRegister2.Operand, 0);
+ }
+ }
+
+ ScopedRegister tableReg1 = default;
+ ScopedRegister tableReg2 = default;
+
+ switch (len)
+ {
+ case 0:
+ tableReg1 = MoveHalfToSideZeroUpper(context, rn);
+ break;
+ case 1:
+ tableReg1 = MoveDoublewords(context, rn, rn + 1);
+ break;
+ case 2:
+ tableReg1 = MoveDoublewords(context, rn, rn + 1, isOdd: true);
+ tableReg2 = MoveHalfToSideZeroUpper(context, rn + 2);
+ break;
+ case 3:
+ tableReg1 = MoveDoublewords(context, rn, rn + 1);
+ tableReg2 = MoveDoublewords(context, rn + 2, rn + 3);
+ break;
+ }
+
+ // TBL works with consecutive registers, it is assumed that two consecutive calls to the register allocator
+ // will return consecutive registers.
+
+ Debug.Assert(len < 2 || tableReg1.Operand.GetRegister().Index + 1 == tableReg2.Operand.GetRegister().Index);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (isTbl)
+ {
+ context.Arm64Assembler.Tbl(tempRegister.Operand, tableReg1.Operand, len >> 1, indicesReg.Operand, 0);
+ }
+ else
+ {
+ InstEmitNeonCommon.MoveScalarToSide(context, tempRegister.Operand, rd, false);
+
+ context.Arm64Assembler.Tbx(tempRegister.Operand, tableReg1.Operand, len >> 1, indicesReg.Operand, 0);
+ }
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+
+ tableReg1.Dispose();
+
+ if (len > 1)
+ {
+ tableReg2.Dispose();
+ }
+ }
+
+ public static void Vtrn(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ EmitVectorBinaryInterleavedTrn(context, rd, rm, size, q, context.Arm64Assembler.Trn1, context.Arm64Assembler.Trn2);
+ }
+
+ public static void Vuzp(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ EmitVectorBinaryInterleaved(context, rd, rm, size, q, context.Arm64Assembler.Uzp1, context.Arm64Assembler.Uzp2);
+ }
+
+ public static void Vzip(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ EmitVectorBinaryInterleaved(context, rd, rm, size, q, context.Arm64Assembler.Zip1, context.Arm64Assembler.Zip2);
+ }
+
+ public static (uint, uint, uint, uint, uint, uint, uint, uint) Split(uint imm8)
+ {
+ uint a = (imm8 >> 7) & 1;
+ uint b = (imm8 >> 6) & 1;
+ uint c = (imm8 >> 5) & 1;
+ uint d = (imm8 >> 4) & 1;
+ uint e = (imm8 >> 3) & 1;
+ uint f = (imm8 >> 2) & 1;
+ uint g = (imm8 >> 1) & 1;
+ uint h = imm8 & 1;
+
+ return (a, b, c, d, e, f, g, h);
+ }
+
+ private static ScopedRegister MoveHalfToSideZeroUpper(CodeGenContext context, uint srcReg)
+ {
+ uint elt = srcReg & 1u;
+
+ Operand source = context.RegisterAllocator.RemapSimdRegister((int)(srcReg >> 1));
+ ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(false);
+
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(elt, false);
+
+ context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, source, imm5);
+
+ return tempRegister;
+ }
+
+ private static ScopedRegister MoveDoublewords(CodeGenContext context, uint lowerReg, uint upperReg, bool isOdd = false)
+ {
+ if ((lowerReg & 1) == 0 && upperReg == lowerReg + 1 && !isOdd)
+ {
+ return new ScopedRegister(context.RegisterAllocator, context.RegisterAllocator.RemapSimdRegister((int)(lowerReg >> 1)), false);
+ }
+
+ Operand lowerSrc = context.RegisterAllocator.RemapSimdRegister((int)(lowerReg >> 1));
+ Operand upperSrc = context.RegisterAllocator.RemapSimdRegister((int)(upperReg >> 1));
+ ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempFpRegisterScoped(false);
+
+ uint imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(lowerReg & 1u, false);
+
+ context.Arm64Assembler.DupEltScalarFromElement(tempRegister.Operand, lowerSrc, imm5);
+
+ imm5 = InstEmitNeonCommon.GetImm5ForElementIndex(1, false);
+
+ context.Arm64Assembler.InsElt(tempRegister.Operand, upperSrc, (upperReg & 1u) << 3, imm5);
+
+ return tempRegister;
+ }
+
+ private static void EmitVectorBinaryInterleavedTrn(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint size,
+ uint q,
+ Action action1,
+ Action action2)
+ {
+ if (rd == rm)
+ {
+ // The behaviour when the registers are the same is "unpredictable" according to the manual.
+
+ if (q == 0)
+ {
+ using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, false);
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister1 = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+ using ScopedRegister tempRegister2 = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rdReg, rmReg);
+
+ action1(tempRegister1.Operand, rdReg.Operand, rmReg.Operand, size, q);
+ action2(tempRegister2.Operand, rdReg.Operand, tempRegister1.Operand, size, q);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rd, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action1(tempRegister.Operand, rdOperand, rmOperand, size, q);
+ action2(rmOperand, rdOperand, tempRegister.Operand, size, q);
+ }
+ }
+ else
+ {
+ EmitVectorBinaryInterleaved(context, rd, rm, size, q, action1, action2);
+ }
+ }
+
+ private static void EmitVectorBinaryInterleaved(
+ CodeGenContext context,
+ uint rd,
+ uint rm,
+ uint size,
+ uint q,
+ Action action1,
+ Action action2)
+ {
+ if (q == 0)
+ {
+ using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, false);
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false);
+
+ using ScopedRegister tempRegister1 = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+ using ScopedRegister tempRegister2 = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rdReg, rmReg);
+
+ action1(tempRegister1.Operand, rdReg.Operand, rmReg.Operand, size, q);
+ action2(tempRegister2.Operand, rdReg.Operand, rmReg.Operand, size, q);
+
+ if (rd != rm)
+ {
+ InstEmitNeonCommon.InsertResult(context, tempRegister1.Operand, rd, false);
+ }
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister2.Operand, rm, false);
+ }
+ else
+ {
+ Operand rdOperand = context.RegisterAllocator.RemapSimdRegister((int)(rd >> 1));
+ Operand rmOperand = context.RegisterAllocator.RemapSimdRegister((int)(rm >> 1));
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ action1(tempRegister.Operand, rdOperand, rmOperand, size, q);
+ action2(rmOperand, rdOperand, rmOperand, size, q);
+
+ if (rd != rm)
+ {
+ context.Arm64Assembler.OrrReg(rdOperand, tempRegister.Operand, tempRegister.Operand, 1);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs
new file mode 100644
index 00000000..3c6ca65d
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs
@@ -0,0 +1,105 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonRound
+ {
+ public static void Vraddhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Raddhn);
+ }
+
+ public static void Vrhadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, u ? context.Arm64Assembler.Urhadd : context.Arm64Assembler.Srhadd, null);
+ }
+
+ public static void Vrshl(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rm,
+ rn,
+ size,
+ q,
+ u ? context.Arm64Assembler.UrshlV : context.Arm64Assembler.SrshlV,
+ u ? context.Arm64Assembler.UrshlS : context.Arm64Assembler.SrshlS);
+ }
+
+ public static void Vrshr(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = InstEmitNeonShift.GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(
+ context,
+ rd,
+ rm,
+ shift,
+ size,
+ q,
+ isShl: false,
+ u ? context.Arm64Assembler.UrshrV : context.Arm64Assembler.SrshrV,
+ u ? context.Arm64Assembler.UrshrS : context.Arm64Assembler.SrshrS);
+ }
+
+ public static void Vrshrn(CodeGenContext context, uint rd, uint rm, uint imm6)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6);
+ uint shift = InstEmitNeonShift.GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.Rshrn);
+ }
+
+ public static void Vrsra(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = InstEmitNeonShift.GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorTernaryRdShift(
+ context,
+ rd,
+ rm,
+ shift,
+ size,
+ q,
+ isShl: false,
+ u ? context.Arm64Assembler.UrsraV : context.Arm64Assembler.SrsraV,
+ u ? context.Arm64Assembler.UrsraS : context.Arm64Assembler.SrsraS);
+ }
+
+ public static void Vrsubhn(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrow(context, rd, rn, rm, size, context.Arm64Assembler.Rsubhn);
+ }
+
+ public static void Vrinta(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintaSingleAndDouble, context.Arm64Assembler.FrintaHalf);
+ }
+
+ public static void Vrintm(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintmSingleAndDouble, context.Arm64Assembler.FrintmHalf);
+ }
+
+ public static void Vrintn(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintnSingleAndDouble, context.Arm64Assembler.FrintnHalf);
+ }
+
+ public static void Vrintp(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintpSingleAndDouble, context.Arm64Assembler.FrintpHalf);
+ }
+
+ public static void Vrintx(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintxSingleAndDouble, context.Arm64Assembler.FrintxHalf);
+ }
+
+ public static void Vrintz(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryAnyF(context, rd, rm, size, q, context.Arm64Assembler.FrintzSingleAndDouble, context.Arm64Assembler.FrintzHalf);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs
new file mode 100644
index 00000000..aeab726a
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs
@@ -0,0 +1,205 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonSaturate
+ {
+ public static void Vqabs(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.SqabsV);
+ }
+
+ public static void Vqadd(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rn,
+ rm,
+ size,
+ q,
+ u ? context.Arm64Assembler.UqaddV : context.Arm64Assembler.SqaddV,
+ u ? context.Arm64Assembler.UqaddS : context.Arm64Assembler.SqaddS);
+ }
+
+ public static void Vqdmlal(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlalVecV);
+ }
+
+ public static void VqdmlalS(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlalElt2regElement);
+ }
+
+ public static void Vqdmlsl(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlslVecV);
+ }
+
+ public static void VqdmlslS(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmlslElt2regElement);
+ }
+
+ public static void Vqdmulh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SqdmulhVecV, context.Arm64Assembler.SqdmulhVecS);
+ }
+
+ public static void VqdmulhS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqdmulhElt2regElement);
+ }
+
+ public static void Vqdmull(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLong(context, rd, rn, rm, size, context.Arm64Assembler.SqdmullVecV);
+ }
+
+ public static void VqdmullS(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryLongByScalar(context, rd, rn, rm, size, context.Arm64Assembler.SqdmullElt2regElement);
+ }
+
+ public static void Vqmovn(CodeGenContext context, uint rd, uint rm, uint op, uint size)
+ {
+ if (op == 3)
+ {
+ InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, context.Arm64Assembler.UqxtnV);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorUnaryNarrow(context, rd, rm, size, op == 1 ? context.Arm64Assembler.SqxtunV : context.Arm64Assembler.SqxtnV);
+ }
+ }
+
+ public static void Vqneg(CodeGenContext context, uint rd, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorUnary(context, rd, rm, size, q, context.Arm64Assembler.SqnegV);
+ }
+
+ public static void Vqrdmlah(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlahVecV);
+ }
+
+ public static void VqrdmlahS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlahElt2regElement);
+ }
+
+ public static void Vqrdmlsh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRd(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlshVecV);
+ }
+
+ public static void VqrdmlshS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorTernaryRdByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmlshElt2regElement);
+ }
+
+ public static void Vqrdmulh(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmulhVecV, context.Arm64Assembler.SqrdmulhVecS);
+ }
+
+ public static void VqrdmulhS(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryByScalar(context, rd, rn, rm, size, q, context.Arm64Assembler.SqrdmulhElt2regElement);
+ }
+
+ public static void Vqrshl(CodeGenContext context, uint rd, uint rn, uint rm, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.SqrshlV, context.Arm64Assembler.SqrshlS);
+ }
+
+ public static void Vqrshrn(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint imm6)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6);
+ uint shift = InstEmitNeonShift.GetShiftRight(imm6, size);
+
+ if (u && op == 0)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqrshrunV);
+ }
+ else if (!u && op == 1)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqrshrnV);
+ }
+ else
+ {
+ Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction.
+
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.UqrshrnV);
+ }
+ }
+
+ public static void VqshlI(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = InstEmitNeonShift.GetShiftLeft(imm6, size);
+
+ if (u && op == 0)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.SqshluV, context.Arm64Assembler.SqshluS);
+ }
+ else if (!u && op == 1)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.SqshlImmV, context.Arm64Assembler.SqshlImmS);
+ }
+ else
+ {
+ Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction.
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.UqshlImmV, context.Arm64Assembler.UqshlImmS);
+ }
+ }
+
+ public static void VqshlR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ if (u)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.UqshlRegV, context.Arm64Assembler.UqshlRegS);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitVectorBinary(context, rd, rm, rn, size, q, context.Arm64Assembler.SqshlRegV, context.Arm64Assembler.SqshlRegS);
+ }
+ }
+
+ public static void Vqshrn(CodeGenContext context, uint rd, uint rm, bool u, uint op, uint imm6)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6);
+ uint shift = InstEmitNeonShift.GetShiftRight(imm6, size);
+
+ if (u && op == 0)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqshrunV);
+ }
+ else if (!u && op == 1)
+ {
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.SqshrnV);
+ }
+ else
+ {
+ Debug.Assert(u && op == 1); // !u && op == 0 is the encoding for another instruction.
+
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.UqshrnV);
+ }
+ }
+
+ public static void Vqsub(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rn,
+ rm,
+ size,
+ q,
+ u ? context.Arm64Assembler.UqsubV : context.Arm64Assembler.SqsubV,
+ u ? context.Arm64Assembler.UqsubS : context.Arm64Assembler.SqsubS);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs
new file mode 100644
index 00000000..9f8d0bde
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs
@@ -0,0 +1,123 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonShift
+ {
+ public static void Vshll(CodeGenContext context, uint rd, uint rm, uint imm6, bool u)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6);
+ uint shift = GetShiftLeft(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rm, shift, size, isShl: true, u ? context.Arm64Assembler.Ushll : context.Arm64Assembler.Sshll);
+ }
+
+ public static void Vshll2(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ // Shift can't be encoded, so shift by value - 1 first, then first again by 1.
+ // Doesn't matter if we do a signed or unsigned shift in this case since all sign bits will be shifted out.
+
+ uint shift = 8u << (int)size;
+
+ InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rm, shift - 1, size, isShl: true, context.Arm64Assembler.Sshll);
+ InstEmitNeonCommon.EmitVectorBinaryLongShift(context, rd, rd, 1, size, isShl: true, context.Arm64Assembler.Sshll);
+ }
+
+ public static void VshlI(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = GetShiftLeft(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: true, context.Arm64Assembler.ShlV, context.Arm64Assembler.ShlS);
+ }
+
+ public static void VshlR(CodeGenContext context, uint rd, uint rn, uint rm, bool u, uint size, uint q)
+ {
+ InstEmitNeonCommon.EmitVectorBinary(
+ context,
+ rd,
+ rm,
+ rn,
+ size,
+ q,
+ u ? context.Arm64Assembler.UshlV : context.Arm64Assembler.SshlV,
+ u ? context.Arm64Assembler.UshlS : context.Arm64Assembler.SshlS);
+ }
+
+ public static void Vshr(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(
+ context,
+ rd,
+ rm,
+ shift,
+ size,
+ q,
+ isShl: false,
+ u ? context.Arm64Assembler.UshrV : context.Arm64Assembler.SshrV,
+ u ? context.Arm64Assembler.UshrS : context.Arm64Assembler.SshrS);
+ }
+
+ public static void Vshrn(CodeGenContext context, uint rd, uint rm, uint imm6)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm6(imm6);
+ uint shift = GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryNarrowShift(context, rd, rm, shift, size, isShl: false, context.Arm64Assembler.Shrn);
+ }
+
+ public static void Vsli(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = GetShiftLeft(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(
+ context,
+ rd,
+ rm,
+ shift,
+ size,
+ q,
+ isShl: true,
+ context.Arm64Assembler.SliV,
+ context.Arm64Assembler.SliS);
+ }
+
+ public static void Vsra(CodeGenContext context, uint rd, uint rm, bool u, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorTernaryRdShift(
+ context,
+ rd,
+ rm,
+ shift,
+ size,
+ q,
+ isShl: false,
+ u ? context.Arm64Assembler.UsraV : context.Arm64Assembler.SsraV,
+ u ? context.Arm64Assembler.UsraS : context.Arm64Assembler.SsraS);
+ }
+
+ public static void Vsri(CodeGenContext context, uint rd, uint rm, uint l, uint imm6, uint q)
+ {
+ uint size = InstEmitNeonCommon.GetSizeFromImm7(imm6 | (l << 6));
+ uint shift = GetShiftRight(imm6, size);
+
+ InstEmitNeonCommon.EmitVectorBinaryShift(context, rd, rm, shift, size, q, isShl: false, context.Arm64Assembler.SriV, context.Arm64Assembler.SriS);
+ }
+
+ public static uint GetShiftLeft(uint imm6, uint size)
+ {
+ return size < 3 ? imm6 - (8u << (int)size) : imm6;
+ }
+
+ public static uint GetShiftRight(uint imm6, uint size)
+ {
+ return (size == 3 ? 64u : (16u << (int)size)) - imm6;
+ ;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs
new file mode 100644
index 00000000..8c7bf91d
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs
@@ -0,0 +1,77 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitNeonSystem
+ {
+ public static void Vmrs(CodeGenContext context, uint rt, uint reg)
+ {
+ if (context.ConsumeSkipNextInstruction())
+ {
+ // This case means that we managed to combine a VCMP and VMRS instruction,
+ // so we have nothing to do here as FCMP/FCMPE already set PSTATE.NZCV.
+ context.SetNzcvModified();
+
+ return;
+ }
+
+ if (reg == 1)
+ {
+ // FPSCR
+
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ if (rt == RegisterUtils.PcRegister)
+ {
+ using ScopedRegister fpsrRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
+ context.Arm64Assembler.Lsr(fpsrRegister.Operand, fpsrRegister.Operand, InstEmitCommon.Const(28));
+
+ InstEmitCommon.RestoreNzcvFlags(context, fpsrRegister.Operand);
+
+ context.SetNzcvModified();
+ }
+ else
+ {
+ // FPSCR is a combination of the FPCR and FPSR registers.
+ // We also need to set the FPSR NZCV bits that no longer exist on AArch64.
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+
+ context.Arm64Assembler.MrsFpsr(rtOperand);
+ context.Arm64Assembler.MrsFpcr(tempRegister.Operand);
+ context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand);
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
+ context.Arm64Assembler.Bfc(tempRegister.Operand, 0, 28);
+ context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand);
+ }
+ }
+ else
+ {
+ Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
+
+ context.Arm64Assembler.Mov(rtOperand, 0u);
+ }
+ }
+
+ public static void Vmsr(CodeGenContext context, uint rt, uint reg)
+ {
+ if (reg == 1)
+ {
+ // FPSCR
+
+ // TODO: Do not set bits related to features that are not supported (like FP16)?
+
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ context.Arm64Assembler.MsrFpcr(rtOperand);
+ context.Arm64Assembler.MsrFpsr(rtOperand);
+ context.Arm64Assembler.StrRiUn(rtOperand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs
new file mode 100644
index 00000000..e2354f44
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs
@@ -0,0 +1,452 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitSaturate
+ {
+ public static void Qadd(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSubSaturate(context, rd, rn, rm, doubling: false, add: true);
+ }
+
+ public static void Qadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Qadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ EmitSaturateRange(context, d, d, 8, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Qasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+
+ EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Qdadd(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSubSaturate(context, rd, rn, rm, doubling: true, add: true);
+ }
+
+ public static void Qdsub(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSubSaturate(context, rd, rn, rm, doubling: true, add: false);
+ }
+
+ public static void Qsax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Qsub(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ EmitAddSubSaturate(context, rd, rn, rm, doubling: false, add: false);
+ }
+
+ public static void Qsub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ EmitSaturateRange(context, d, d, 16, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Qsub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ EmitSaturateRange(context, d, d, 8, unsigned: false, setQ: false);
+ });
+ }
+
+ public static void Ssat(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift)
+ {
+ EmitSaturate(context, rd, imm + 1, rn, sh, shift, unsigned: false);
+ }
+
+ public static void Ssat16(CodeGenContext context, uint rd, uint imm, uint rn)
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, (d, n) =>
+ {
+ EmitSaturateRange(context, d, n, imm + 1, unsigned: false);
+ });
+ }
+
+ public static void Uqadd16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned16BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ EmitSaturateUnsignedRange(context, d, 16);
+ });
+ }
+
+ public static void Uqadd8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned8BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ EmitSaturateUnsignedRange(context, d, 8);
+ });
+ }
+
+ public static void Uqasx(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+
+ EmitSaturateUnsignedRange(context, d, 16);
+ });
+ }
+
+ public static void Uqsax(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitUnsigned16BitXPair(context, rd, rn, rm, (d, n, m, e) =>
+ {
+ if (e == 0)
+ {
+ context.Arm64Assembler.Add(d, n, m);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ }
+
+ EmitSaturateUnsignedRange(context, d, 16);
+ });
+ }
+
+ public static void Uqsub16(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ EmitSaturateUnsignedRange(context, d, 16);
+ });
+ }
+
+ public static void Uqsub8(CodeGenContext context, uint rd, uint rn, uint rm)
+ {
+ InstEmitCommon.EmitSigned8BitPair(context, rd, rn, rm, (d, n, m) =>
+ {
+ context.Arm64Assembler.Sub(d, n, m);
+ EmitSaturateUnsignedRange(context, d, 8);
+ });
+ }
+
+ public static void Usat(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift)
+ {
+ EmitSaturate(context, rd, imm, rn, sh, shift, unsigned: true);
+ }
+
+ public static void Usat16(CodeGenContext context, uint rd, uint imm, uint rn)
+ {
+ InstEmitCommon.EmitSigned16BitPair(context, rd, rn, (d, n) =>
+ {
+ EmitSaturateRange(context, d, n, imm, unsigned: true);
+ });
+ }
+
+ private static void EmitAddSubSaturate(CodeGenContext context, uint rd, uint rn, uint rm, bool doubling, bool add)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+ Operand rmOperand = InstEmitCommon.GetInputGpr(context, rm);
+
+ using ScopedRegister tempN = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempM = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempN64 = new(OperandKind.Register, OperandType.I64, tempN.Operand.Value);
+ Operand tempM64 = new(OperandKind.Register, OperandType.I64, tempM.Operand.Value);
+
+ context.Arm64Assembler.Sxtw(tempN64, rnOperand);
+ context.Arm64Assembler.Sxtw(tempM64, rmOperand);
+
+ if (doubling)
+ {
+ context.Arm64Assembler.Lsl(tempN64, tempN64, InstEmitCommon.Const(1));
+
+ EmitSaturateLongToInt(context, tempN64, tempN64);
+ }
+
+ if (add)
+ {
+ context.Arm64Assembler.Add(tempN64, tempN64, tempM64);
+ }
+ else
+ {
+ context.Arm64Assembler.Sub(tempN64, tempN64, tempM64);
+ }
+
+ EmitSaturateLongToInt(context, rdOperand, tempN64);
+ }
+
+ private static void EmitSaturate(CodeGenContext context, uint rd, uint imm, uint rn, bool sh, uint shift, bool unsigned)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ if (sh && shift == 0)
+ {
+ shift = 31;
+ }
+
+ if (shift != 0)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (sh)
+ {
+ context.Arm64Assembler.Asr(tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)shift));
+ }
+ else
+ {
+ context.Arm64Assembler.Lsl(tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)shift));
+ }
+
+ EmitSaturateRange(context, rdOperand, tempRegister.Operand, imm, unsigned);
+ }
+ else
+ {
+ EmitSaturateRange(context, rdOperand, rnOperand, imm, unsigned);
+ }
+ }
+
+ private static void EmitSaturateRange(CodeGenContext context, Operand result, Operand value, uint saturateTo, bool unsigned, bool setQ = true)
+ {
+ Debug.Assert(saturateTo <= 32);
+ Debug.Assert(!unsigned || saturateTo < 32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister tempValue = default;
+
+ bool resultValueOverlap = result.Value == value.Value;
+
+ if (!unsigned && saturateTo == 32)
+ {
+ // No saturation possible for this case.
+
+ if (!resultValueOverlap)
+ {
+ context.Arm64Assembler.Mov(result, value);
+ }
+
+ return;
+ }
+ else if (saturateTo == 0)
+ {
+ // Result is always zero if we saturate 0 bits.
+
+ context.Arm64Assembler.Mov(result, 0u);
+
+ return;
+ }
+
+ if (resultValueOverlap)
+ {
+ tempValue = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.Mov(tempValue.Operand, value);
+ value = tempValue.Operand;
+ }
+
+ if (unsigned)
+ {
+ // Negative values always saturate (to zero).
+ // So we must always ignore the sign bit when masking, so that the truncated value will differ from the original one.
+
+ context.Arm64Assembler.And(result, value, InstEmitCommon.Const((int)(uint.MaxValue >> (32 - (int)saturateTo))));
+ }
+ else
+ {
+ context.Arm64Assembler.Sbfx(result, value, 0, (int)saturateTo);
+ }
+
+ context.Arm64Assembler.Sub(tempRegister.Operand, value, result);
+
+ int branchIndex = context.CodeWriter.InstructionPointer;
+
+ // If the result is 0, the values are equal and we don't need saturation.
+ context.Arm64Assembler.Cbz(tempRegister.Operand, 0);
+
+ // Saturate and set Q flag.
+ if (unsigned)
+ {
+ if (saturateTo == 31)
+ {
+ // Only saturation case possible when going from 32 bits signed to 32 or 31 bits unsigned
+ // is when the signed input is negative, as all positive values are representable on a 31 bits range.
+
+ context.Arm64Assembler.Mov(result, 0u);
+ }
+ else
+ {
+ context.Arm64Assembler.Asr(result, value, InstEmitCommon.Const(31));
+ context.Arm64Assembler.Mvn(result, result);
+ context.Arm64Assembler.Lsr(result, result, InstEmitCommon.Const(32 - (int)saturateTo));
+ }
+ }
+ else
+ {
+ if (saturateTo == 1)
+ {
+ context.Arm64Assembler.Asr(result, value, InstEmitCommon.Const(31));
+ }
+ else
+ {
+ context.Arm64Assembler.Mov(result, uint.MaxValue >> (33 - (int)saturateTo));
+ context.Arm64Assembler.Eor(result, result, value, ArmShiftType.Asr, 31);
+ }
+ }
+
+ if (setQ)
+ {
+ SetQFlag(context);
+ }
+
+ int delta = context.CodeWriter.InstructionPointer - branchIndex;
+ context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5));
+
+ if (resultValueOverlap)
+ {
+ tempValue.Dispose();
+ }
+ }
+
+ private static void EmitSaturateUnsignedRange(CodeGenContext context, Operand value, uint saturateTo)
+ {
+ Debug.Assert(saturateTo <= 32);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ if (saturateTo == 32)
+ {
+ // No saturation possible for this case.
+
+ return;
+ }
+ else if (saturateTo == 0)
+ {
+ // Result is always zero if we saturate 0 bits.
+
+ context.Arm64Assembler.Mov(value, 0u);
+
+ return;
+ }
+
+ context.Arm64Assembler.Lsr(tempRegister.Operand, value, InstEmitCommon.Const(32 - (int)saturateTo));
+
+ int branchIndex = context.CodeWriter.InstructionPointer;
+
+ // If the result is 0, the values are equal and we don't need saturation.
+ context.Arm64Assembler.Cbz(tempRegister.Operand, 0);
+
+ // Saturate.
+ context.Arm64Assembler.Mov(value, uint.MaxValue >> (32 - (int)saturateTo));
+
+ int delta = context.CodeWriter.InstructionPointer - branchIndex;
+ context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5));
+ }
+
+ private static void EmitSaturateLongToInt(CodeGenContext context, Operand result, Operand value)
+ {
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ ScopedRegister tempValue = default;
+
+ bool resultValueOverlap = result.Value == value.Value;
+
+ if (resultValueOverlap)
+ {
+ tempValue = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand tempValue64 = new(OperandKind.Register, OperandType.I64, tempValue.Operand.Value);
+
+ context.Arm64Assembler.Mov(tempValue64, value);
+ value = tempValue64;
+ }
+
+ Operand temp64 = new(OperandKind.Register, OperandType.I64, tempRegister.Operand.Value);
+ Operand result64 = new(OperandKind.Register, OperandType.I64, result.Value);
+
+ context.Arm64Assembler.Sxtw(result64, value);
+ context.Arm64Assembler.Sub(temp64, value, result64);
+
+ int branchIndex = context.CodeWriter.InstructionPointer;
+
+ // If the result is 0, the values are equal and we don't need saturation.
+ context.Arm64Assembler.Cbz(temp64, 0);
+
+ // Saturate and set Q flag.
+ context.Arm64Assembler.Mov(result, uint.MaxValue >> 1);
+ context.Arm64Assembler.Eor(result64, result64, value, ArmShiftType.Asr, 63);
+
+ SetQFlag(context);
+
+ int delta = context.CodeWriter.InstructionPointer - branchIndex;
+ context.CodeWriter.WriteInstructionAt(branchIndex, context.CodeWriter.ReadInstructionAt(branchIndex) | (uint)((delta & 0x7ffff) << 5));
+
+ context.Arm64Assembler.Mov(result, result); // Zero-extend.
+
+ if (resultValueOverlap)
+ {
+ tempValue.Dispose();
+ }
+ }
+
+ public static void SetQFlag(CodeGenContext context)
+ {
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 27));
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs
new file mode 100644
index 00000000..be0976fd
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs
@@ -0,0 +1,648 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitSystem
+ {
+ private delegate void SoftwareInterruptHandler(ulong address, int imm);
+ private delegate ulong Get64();
+ private delegate bool GetBool();
+
+ private const int SpIndex = 31;
+
+ public static void Bkpt(CodeGenContext context, uint imm)
+ {
+ context.AddPendingBkpt(imm);
+
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void Cps(CodeGenContext context, uint imod, uint m, uint a, uint i, uint f, uint mode)
+ {
+ // NOP in user mode.
+ }
+
+ public static void Dbg(CodeGenContext context, uint option)
+ {
+ // NOP in ARMv8.
+ }
+
+ public static void Hlt(CodeGenContext context, uint imm)
+ {
+ }
+
+ public static void Mcr(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crn, uint crm, uint opc2)
+ {
+ if (coproc != 15 || opc1 != 0)
+ {
+ Udf(context, encoding, 0);
+
+ return;
+ }
+
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+
+ switch (crn)
+ {
+ case 13: // Process and Thread Info.
+ if (crm == 0)
+ {
+ switch (opc2)
+ {
+ case 2:
+ context.Arm64Assembler.StrRiUn(rtOperand, ctx, NativeContextOffsets.TpidrEl0Offset);
+ return;
+ }
+ }
+ break;
+ }
+ }
+
+ public static void Mcrr(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crm)
+ {
+ if (coproc != 15 || opc1 != 0)
+ {
+ Udf(context, encoding, 0);
+
+ return;
+ }
+
+ // We don't have any system register that needs to be modified using a 64-bit value.
+ }
+
+ public static void Mrc(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint crn, uint crm, uint opc2)
+ {
+ if (coproc != 15 || opc1 != 0)
+ {
+ Udf(context, encoding, 0);
+
+ return;
+ }
+
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+ Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
+ bool hasValue = false;
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ Operand dest = rt == RegisterUtils.PcRegister ? tempRegister.Operand : rtOperand;
+
+ switch (crn)
+ {
+ case 13: // Process and Thread Info.
+ if (crm == 0)
+ {
+ switch (opc2)
+ {
+ case 2:
+ context.Arm64Assembler.LdrRiUn(dest, ctx, NativeContextOffsets.TpidrEl0Offset);
+ hasValue = true;
+ break;
+ case 3:
+ context.Arm64Assembler.LdrRiUn(dest, ctx, NativeContextOffsets.TpidrroEl0Offset);
+ hasValue = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ if (rt == RegisterUtils.PcRegister)
+ {
+ context.Arm64Assembler.MsrNzcv(dest);
+ context.SetNzcvModified();
+ }
+ else if (!hasValue)
+ {
+ context.Arm64Assembler.Mov(dest, 0u);
+ }
+ }
+
+ public static void Mrrc(CodeGenContext context, uint encoding, uint coproc, uint opc1, uint rt, uint rt2, uint crm)
+ {
+ if (coproc != 15)
+ {
+ Udf(context, encoding, 0);
+
+ return;
+ }
+
+ switch (crm)
+ {
+ case 14:
+ switch (opc1)
+ {
+ case 0:
+ context.AddPendingReadCntpct(rt, rt2);
+ context.Arm64Assembler.B(0);
+ return;
+ }
+ break;
+ }
+
+ // Unsupported system register.
+ context.Arm64Assembler.Mov(InstEmitCommon.GetOutputGpr(context, rt), 0u);
+ context.Arm64Assembler.Mov(InstEmitCommon.GetOutputGpr(context, rt2), 0u);
+ }
+
+ public static void Mrs(CodeGenContext context, uint rd, bool r)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ if (r)
+ {
+ // Reads SPSR, unpredictable in user mode.
+
+ context.Arm64Assembler.Mov(rdOperand, 0u);
+ }
+ else
+ {
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+
+ // Copy GE flags to destination register.
+ context.Arm64Assembler.Ubfx(rdOperand, tempRegister.Operand, 16, 4);
+
+ // Insert Q flag.
+ context.Arm64Assembler.And(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 27));
+ context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand);
+
+ // Insert NZCV flags.
+ context.Arm64Assembler.MrsNzcv(tempRegister.Operand);
+ context.Arm64Assembler.Orr(rdOperand, rdOperand, tempRegister.Operand);
+
+ // All other flags can't be accessed in user mode or have "unknown" values.
+ }
+ }
+
+ public static void MrsBr(CodeGenContext context, uint rd, uint m1, bool r)
+ {
+ Operand rdOperand = InstEmitCommon.GetOutputGpr(context, rd);
+
+ // Reads banked register, unpredictable in user mode.
+
+ context.Arm64Assembler.Mov(rdOperand, 0u);
+ }
+
+ public static void MsrBr(CodeGenContext context, uint rn, uint m1, bool r)
+ {
+ // Writes banked register, unpredictable in user mode.
+ }
+
+ public static void MsrI(CodeGenContext context, uint imm, uint mask, bool r)
+ {
+ if (r)
+ {
+ // Writes SPSR, unpredictable in user mode.
+ }
+ else
+ {
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+
+ if ((mask & 2) != 0)
+ {
+ // Endian flag.
+
+ context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 9) & 1);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 9, 1);
+ }
+
+ if ((mask & 4) != 0)
+ {
+ // GE flags.
+
+ context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 16) & 0xf);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 16, 4);
+ }
+
+ if ((mask & 8) != 0)
+ {
+ // NZCVQ flags.
+
+ context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 27) & 0x1f);
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 27, 5);
+ context.Arm64Assembler.Mov(tempRegister2.Operand, (imm >> 28) & 0xf);
+ InstEmitCommon.RestoreNzcvFlags(context, tempRegister2.Operand);
+ context.SetNzcvModified();
+ }
+ }
+ }
+
+ public static void MsrR(CodeGenContext context, uint rn, uint mask, bool r)
+ {
+ Operand rnOperand = InstEmitCommon.GetInputGpr(context, rn);
+
+ if (r)
+ {
+ // Writes SPSR, unpredictable in user mode.
+ }
+ else
+ {
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister tempRegister2 = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+
+ if ((mask & 2) != 0)
+ {
+ // Endian flag.
+
+ context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(9));
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 9, 1);
+ }
+
+ if ((mask & 4) != 0)
+ {
+ // GE flags.
+
+ context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(16));
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 16, 4);
+ }
+
+ if ((mask & 8) != 0)
+ {
+ // NZCVQ flags.
+
+ context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(27));
+ context.Arm64Assembler.Bfi(tempRegister.Operand, tempRegister2.Operand, 27, 5);
+ context.Arm64Assembler.Lsr(tempRegister2.Operand, rnOperand, InstEmitCommon.Const(28));
+ InstEmitCommon.RestoreNzcvFlags(context, tempRegister2.Operand);
+ context.SetNzcvModified();
+ }
+ }
+ }
+
+ public static void Setend(CodeGenContext context, bool e)
+ {
+ Operand ctx = Register(context.RegisterAllocator.FixedContextRegister);
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+
+ if (e)
+ {
+ context.Arm64Assembler.Orr(tempRegister.Operand, tempRegister.Operand, InstEmitCommon.Const(1 << 9));
+ }
+ else
+ {
+ context.Arm64Assembler.Bfc(tempRegister.Operand, 9, 1);
+ }
+
+ context.Arm64Assembler.StrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public static void Svc(CodeGenContext context, uint imm)
+ {
+ context.AddPendingSvc(imm);
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void Udf(CodeGenContext context, uint encoding, uint imm)
+ {
+ context.AddPendingUdf(encoding);
+ context.Arm64Assembler.B(0);
+ }
+
+ public static void PrivilegedInstruction(CodeGenContext context, uint encoding)
+ {
+ Udf(context, encoding, 0);
+ }
+
+ private static IntPtr GetBkptHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.Break);
+ }
+
+ private static IntPtr GetSvcHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.SupervisorCall);
+ }
+
+ private static IntPtr GetUdfHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.Undefined);
+ }
+
+ private static IntPtr GetCntpctEl0Ptr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.GetCntpctEl0);
+ }
+
+ private static IntPtr CheckSynchronizationPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.CheckSynchronization);
+ }
+
+ public static bool NeedsCall(InstName name)
+ {
+ // All instructions that might do a host call should be included here.
+ // That is required to reserve space on the stack for caller saved registers.
+
+ switch (name)
+ {
+ case InstName.Mcr:
+ case InstName.Mrc:
+ case InstName.Mrrc:
+ case InstName.Svc:
+ case InstName.Udf:
+ return true;
+ }
+
+ return false;
+ }
+
+ public static void WriteBkpt(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetBkptHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
+ }
+
+ public static void WriteSvc(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint svcId)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, svcId);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
+ }
+
+ public static void WriteUdf(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset, uint pc, uint imm)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), skipContext: true, spillBaseOffset, null, pc, imm);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: true, spillBaseOffset);
+ }
+
+ public static void WriteReadCntpct(CodeWriter writer, RegisterAllocator regAlloc, int spillBaseOffset, int rt, int rt2)
+ {
+ Assembler asm = new(writer);
+
+ uint resultMask = (1u << rt) | (1u << rt2);
+ int tempRegister = 0;
+
+ while ((resultMask & (1u << tempRegister)) != 0 && tempRegister < 32)
+ {
+ tempRegister++;
+ }
+
+ Debug.Assert(tempRegister < 32);
+
+ WriteSpill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister);
+
+ Operand rn = Register(tempRegister);
+
+ asm.Mov(rn, (ulong)GetCntpctEl0Ptr());
+ asm.Blr(rn);
+
+ if (rt != rt2)
+ {
+ asm.Lsr(Register(rt2), Register(0), InstEmitCommon.Const(32));
+ }
+
+ asm.Mov(Register(rt, OperandType.I32), Register(0, OperandType.I32)); // Zero-extend.
+
+ WriteFill(ref asm, regAlloc, resultMask, skipContext: false, spillBaseOffset, tempRegister);
+ }
+
+ public static void WriteSyncPoint(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset)
+ {
+ Assembler asm = new(writer);
+
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, skipContext: false, spillBaseOffset);
+ }
+
+ private static void WriteSyncPoint(CodeWriter writer, ref Assembler asm, RegisterAllocator regAlloc, TailMerger tailMerger, bool skipContext, int spillBaseOffset)
+ {
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ int branchIndex = writer.InstructionPointer;
+ asm.Cbnz(rt, 0);
+
+ WriteSpill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister);
+
+ Operand rn = Register(tempRegister == 0 ? 1 : 0);
+
+ asm.Mov(rn, (ulong)CheckSynchronizationPtr());
+ asm.Blr(rn);
+
+ tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32));
+
+ WriteFill(ref asm, regAlloc, 1u << tempRegister, skipContext, spillBaseOffset, tempRegister);
+
+ asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ uint branchInst = writer.ReadInstructionAt(branchIndex);
+ writer.WriteInstructionAt(branchIndex, branchInst | (((uint)(writer.InstructionPointer - branchIndex) & 0x7ffff) << 5));
+
+ asm.Sub(rt, rt, new Operand(OperandKind.Constant, OperandType.I32, 1));
+ asm.StrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void WriteCall(
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ IntPtr funcPtr,
+ bool skipContext,
+ int spillBaseOffset,
+ int? resultRegister,
+ params ulong[] callArgs)
+ {
+ uint resultMask = 0u;
+
+ if (resultRegister.HasValue)
+ {
+ resultMask = 1u << resultRegister.Value;
+ }
+
+ int tempRegister = callArgs.Length;
+
+ if (resultRegister.HasValue && tempRegister == resultRegister.Value)
+ {
+ tempRegister++;
+ }
+
+ WriteSpill(ref asm, regAlloc, resultMask, skipContext, spillBaseOffset, tempRegister);
+
+ // We only support up to 7 arguments right now.
+ // ABI defines the first 8 integer arguments to be passed on registers X0-X7.
+ // We need at least one register to put the function address on, so that reduces the number of
+ // registers we can use for that by one.
+
+ Debug.Assert(callArgs.Length < 8);
+
+ for (int index = 0; index < callArgs.Length; index++)
+ {
+ asm.Mov(Register(index), callArgs[index]);
+ }
+
+ Operand rn = Register(tempRegister);
+
+ asm.Mov(rn, (ulong)funcPtr);
+ asm.Blr(rn);
+
+ if (resultRegister.HasValue && resultRegister.Value != 0)
+ {
+ asm.Mov(Register(resultRegister.Value), Register(0));
+ }
+
+ WriteFill(ref asm, regAlloc, resultMask, skipContext, spillBaseOffset, tempRegister);
+ }
+
+ private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
+ {
+ WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: true);
+ }
+
+ private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, bool skipContext, int spillOffset, int tempRegister)
+ {
+ WriteSpillOrFill(ref asm, regAlloc, skipContext, exceptMask, spillOffset, tempRegister, spill: false);
+ }
+
+ private static void WriteSpillOrFill(
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ bool skipContext,
+ uint exceptMask,
+ int spillOffset,
+ int tempRegister,
+ bool spill)
+ {
+ uint gprMask = regAlloc.UsedGprsMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask);
+
+ if (skipContext)
+ {
+ gprMask &= ~Compiler.UsableGprsMask;
+ }
+
+ if (!spill)
+ {
+ // We must reload the status register before reloading the GPRs,
+ // since we might otherwise trash one of them by using it as temp register.
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.LdrRiUn(rt, Register(SpIndex), spillOffset + BitOperations.PopCount(gprMask) * 8);
+ asm.MsrNzcv(rt);
+ }
+
+ while (gprMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(gprMask);
+
+ if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(Register(reg), Register(reg + 1), Register(SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(3u << reg);
+ spillOffset += 16;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(reg), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(reg), Register(SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(1u << reg);
+ spillOffset += 8;
+ }
+ }
+
+ if (spill)
+ {
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.MrsNzcv(rt);
+ asm.StrRiUn(rt, Register(SpIndex), spillOffset);
+ }
+
+ spillOffset += 8;
+
+ if ((spillOffset & 8) != 0)
+ {
+ spillOffset += 8;
+ }
+
+ uint fpSimdMask = regAlloc.UsedFpSimdMask;
+
+ if (skipContext)
+ {
+ fpSimdMask &= ~Compiler.UsableFpSimdMask;
+ }
+
+ while (fpSimdMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(fpSimdMask);
+
+ if (reg < 31 && (fpSimdMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(Register(reg, OperandType.V128), Register(reg + 1, OperandType.V128), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(Register(reg, OperandType.V128), Register(reg + 1, OperandType.V128), Register(SpIndex), spillOffset);
+ }
+
+ fpSimdMask &= ~(3u << reg);
+ spillOffset += 32;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(reg, OperandType.V128), Register(SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(reg, OperandType.V128), Register(SpIndex), spillOffset);
+ }
+
+ fpSimdMask &= ~(1u << reg);
+ spillOffset += 16;
+ }
+ }
+ }
+
+ public static Operand Register(int register, OperandType type = OperandType.I64)
+ {
+ return new Operand(register, RegisterType.Integer, type);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs
new file mode 100644
index 00000000..efb2fc6b
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs
@@ -0,0 +1,95 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitVfpArithmetic
+ {
+ public static void VabsF(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FabsFloat);
+ }
+
+ public static void VaddF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FaddFloat);
+ }
+
+ public static void VdivF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FdivFloat);
+ }
+
+ public static void VfmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FmaddFloat);
+ }
+
+ public static void VfmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FmsubFloat);
+ }
+
+ public static void VfnmaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FnmaddFloat);
+ }
+
+ public static void VfnmsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryRdF(context, rd, rn, rm, size, context.Arm64Assembler.FnmsubFloat);
+ }
+
+ public static void Vmaxnm(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FmaxnmFloat);
+ }
+
+ public static void Vminnm(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FminnmFloat);
+ }
+
+ public static void VmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: false, negProduct: false);
+ }
+
+ public static void VmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: false, negProduct: true);
+ }
+
+ public static void VmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FmulFloat);
+ }
+
+ public static void VnegF(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FnegFloat);
+ }
+
+ public static void VnmlaF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: true, negProduct: true);
+ }
+
+ public static void VnmlsF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarTernaryMulNegRdF(context, rd, rn, rm, size, negD: true, negProduct: false);
+ }
+
+ public static void VnmulF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FnmulFloat);
+ }
+
+ public static void VsqrtF(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FsqrtFloat);
+ }
+
+ public static void VsubF(CodeGenContext context, uint rd, uint rn, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarBinaryF(context, rd, rn, rm, size, context.Arm64Assembler.FsubFloat);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs
new file mode 100644
index 00000000..f5f30609
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs
@@ -0,0 +1,133 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitVfpCompare
+ {
+ public static void VcmpI(CodeGenContext context, uint cond, uint rd, uint size)
+ {
+ EmitVcmpVcmpe(context, cond, rd, 0, size, zero: true, e: false);
+ }
+
+ public static void VcmpR(CodeGenContext context, uint cond, uint rd, uint rm, uint size)
+ {
+ EmitVcmpVcmpe(context, cond, rd, rm, size, zero: false, e: false);
+ }
+
+ public static void VcmpeI(CodeGenContext context, uint cond, uint rd, uint size)
+ {
+ EmitVcmpVcmpe(context, cond, rd, 0, size, zero: true, e: true);
+ }
+
+ public static void VcmpeR(CodeGenContext context, uint cond, uint rd, uint rm, uint size)
+ {
+ EmitVcmpVcmpe(context, cond, rd, rm, size, zero: false, e: true);
+ }
+
+ private static void EmitVcmpVcmpe(CodeGenContext context, uint cond, uint rd, uint rm, uint size, bool zero, bool e)
+ {
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+ uint ftype = size ^ 2u;
+ uint opc = zero ? 1u : 0u;
+
+ using ScopedRegister rdReg = InstEmitNeonCommon.MoveScalarToSide(context, rd, singleRegs);
+ ScopedRegister rmReg;
+ Operand rmOrZero;
+
+ if (zero)
+ {
+ rmReg = default;
+ rmOrZero = new Operand(0, RegisterType.Vector, OperandType.V128);
+ }
+ else
+ {
+ rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs);
+ rmOrZero = rmReg.Operand;
+ }
+
+ using ScopedRegister oldFlags = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ bool canPeepholeOptimize = CanFuseVcmpVmrs(context, cond);
+ if (!canPeepholeOptimize)
+ {
+ InstEmitCommon.GetCurrentFlags(context, oldFlags.Operand);
+ }
+
+ if (e)
+ {
+ context.Arm64Assembler.FcmpeFloat(rdReg.Operand, rmOrZero, opc, ftype);
+ }
+ else
+ {
+ context.Arm64Assembler.FcmpFloat(rdReg.Operand, rmOrZero, opc, ftype);
+ }
+
+ // Save result flags from the FCMP operation on FPSCR register, then restore the old flags if needed.
+
+ WriteUpdateFpsrNzcv(context);
+
+ if (!canPeepholeOptimize)
+ {
+ InstEmitCommon.RestoreNzcvFlags(context, oldFlags.Operand);
+ }
+
+ if (!zero)
+ {
+ rmReg.Dispose();
+ }
+ }
+
+ private static void WriteUpdateFpsrNzcv(CodeGenContext context)
+ {
+ using ScopedRegister fpsrRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+ using ScopedRegister flagsRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
+
+ Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
+
+ context.Arm64Assembler.LdrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
+
+ InstEmitCommon.GetCurrentFlags(context, flagsRegister.Operand);
+
+ context.Arm64Assembler.Bfi(fpsrRegister.Operand, flagsRegister.Operand, 28, 4);
+ context.Arm64Assembler.StrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
+ }
+
+ private static bool CanFuseVcmpVmrs(CodeGenContext context, uint vcmpCond)
+ {
+ // Conditions might be different for the VCMP and VMRS instructions if they are inside a IT block,
+ // we don't bother to check right now, so just always skip if inside an IT block.
+ if (context.InITBlock)
+ {
+ return false;
+ }
+
+ InstInfo nextInfo = context.PeekNextInstruction();
+
+ // We're looking for a VMRS instructions.
+ if (nextInfo.Name != InstName.Vmrs)
+ {
+ return false;
+ }
+
+ // Conditions must match.
+ if (vcmpCond != (nextInfo.Encoding >> 28))
+ {
+ return false;
+ }
+
+ // Reg must be 1, Rt must be PC indicating VMRS to PSTATE.NZCV.
+ if (((nextInfo.Encoding >> 16) & 0xf) != 1 || ((nextInfo.Encoding >> 12) & 0xf) != RegisterUtils.PcRegister)
+ {
+ return false;
+ }
+
+ context.SetSkipNextInstruction();
+
+ return true;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs
new file mode 100644
index 00000000..8e488695
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitVfpConvert
+ {
+ public static void Vcvta(CodeGenContext context, uint rd, uint rm, bool op, uint size)
+ {
+ if (size == 3)
+ {
+ // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtasFloat);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtauFloat);
+ }
+ }
+ else if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtasS, context.Arm64Assembler.FcvtasSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtauS, context.Arm64Assembler.FcvtauSH);
+ }
+ }
+
+ public static void Vcvtb(CodeGenContext context, uint rd, uint rm, uint sz, uint op)
+ {
+ EmitVcvtbVcvtt(context, rd, rm, sz, op, top: false);
+ }
+
+ public static void Vcvtm(CodeGenContext context, uint rd, uint rm, bool op, uint size)
+ {
+ if (size == 3)
+ {
+ // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtmsFloat);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtmuFloat);
+ }
+ }
+ else if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtmsS, context.Arm64Assembler.FcvtmsSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtmuS, context.Arm64Assembler.FcvtmuSH);
+ }
+ }
+
+ public static void Vcvtn(CodeGenContext context, uint rd, uint rm, bool op, uint size)
+ {
+ if (size == 3)
+ {
+ // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtnsFloat);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtnuFloat);
+ }
+ }
+ else if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtnsS, context.Arm64Assembler.FcvtnsSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtnuS, context.Arm64Assembler.FcvtnuSH);
+ }
+ }
+
+ public static void Vcvtp(CodeGenContext context, uint rd, uint rm, bool op, uint size)
+ {
+ if (size == 3)
+ {
+ // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtpsFloat);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtpuFloat);
+ }
+ }
+ else if (op)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtpsS, context.Arm64Assembler.FcvtpsSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtpuS, context.Arm64Assembler.FcvtpuSH);
+ }
+ }
+
+ public static void VcvtDs(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ bool doubleToSingle = size == 3;
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (doubleToSingle)
+ {
+ // Double to single.
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, false);
+
+ context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 0, 1);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, true);
+ }
+ else
+ {
+ // Single to double.
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, true);
+
+ context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 1, 0);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, false);
+ }
+ }
+
+ public static void VcvtIv(CodeGenContext context, uint rd, uint rm, bool unsigned, uint size)
+ {
+ if (size == 3)
+ {
+ // F64 -> S32/U32 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtzuFloatInt);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryToGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.FcvtzsFloatInt);
+ }
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtzuIntS, context.Arm64Assembler.FcvtzuIntSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FcvtzsIntS, context.Arm64Assembler.FcvtzsIntSH);
+ }
+ }
+ }
+
+ public static void VcvtVi(CodeGenContext context, uint rd, uint rm, bool unsigned, uint size)
+ {
+ if (size == 3)
+ {
+ // S32/U32 -> F64 conversion on SIMD is not supported, so we convert it to a GPR, then insert it back into the SIMD register.
+
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFromGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.UcvtfFloatInt);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFromGprTempF(context, rd, rm, size, 0, context.Arm64Assembler.ScvtfFloatInt);
+ }
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.UcvtfIntS, context.Arm64Assembler.UcvtfIntSH);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.ScvtfIntS, context.Arm64Assembler.ScvtfIntSH);
+ }
+ }
+ }
+
+ public static void VcvtXv(CodeGenContext context, uint rd, uint imm5, bool sx, uint sf, uint op, bool u)
+ {
+ Debug.Assert(op >> 1 == 0);
+
+ bool unsigned = u;
+ bool toFixed = op == 1;
+ uint size = sf;
+ uint fbits = Math.Clamp((sx ? 32u : 16u) - imm5, 1, 8u << (int)size);
+
+ if (toFixed)
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: false, context.Arm64Assembler.FcvtzuFixS);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: false, context.Arm64Assembler.FcvtzsFixS);
+ }
+ }
+ else
+ {
+ if (unsigned)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: !sx, context.Arm64Assembler.UcvtfFixS);
+ }
+ else
+ {
+ InstEmitNeonCommon.EmitScalarUnaryFixedF(context, rd, rd, fbits, size, is16Bit: !sx, context.Arm64Assembler.ScvtfFixS);
+ }
+ }
+ }
+
+ public static void VcvtrIv(CodeGenContext context, uint rd, uint rm, uint op, uint size)
+ {
+ bool unsigned = (op & 1) == 0;
+
+ Debug.Assert(size == 1 || size == 2 || size == 3);
+
+ bool singleRegs = size != 3;
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rmReg);
+
+ // Round using the FPCR rounding mode first, since the FCVTZ instructions will use the round to zero mode.
+ context.Arm64Assembler.FrintiFloat(tempRegister.Operand, rmReg.Operand, size ^ 2u);
+
+ if (unsigned)
+ {
+ if (size == 1)
+ {
+ context.Arm64Assembler.FcvtzuIntSH(tempRegister.Operand, tempRegister.Operand);
+ }
+ else
+ {
+ context.Arm64Assembler.FcvtzuIntS(tempRegister.Operand, tempRegister.Operand, size & 1);
+ }
+ }
+ else
+ {
+ if (size == 1)
+ {
+ context.Arm64Assembler.FcvtzsIntSH(tempRegister.Operand, tempRegister.Operand);
+ }
+ else
+ {
+ context.Arm64Assembler.FcvtzsIntS(tempRegister.Operand, tempRegister.Operand, size & 1);
+ }
+ }
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+
+ public static void Vcvtt(CodeGenContext context, uint rd, uint rm, uint sz, uint op)
+ {
+ EmitVcvtbVcvtt(context, rd, rm, sz, op, top: true);
+ }
+
+ public static void EmitVcvtbVcvtt(CodeGenContext context, uint rd, uint rm, uint sz, uint op, bool top)
+ {
+ bool usesDouble = sz == 1;
+ bool convertFromHalf = op == 0;
+
+ using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempSimdRegisterScoped();
+
+ if (convertFromHalf)
+ {
+ // Half to single/double.
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.Move16BitScalarToSide(context, rm, top);
+
+ context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, usesDouble ? 1u : 0u, 3u);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, !usesDouble);
+ }
+ else
+ {
+ // Single/double to half.
+
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, !usesDouble);
+
+ context.Arm64Assembler.FcvtFloat(tempRegister.Operand, rmReg.Operand, 3u, usesDouble ? 1u : 0u);
+
+ InstEmitNeonCommon.Insert16BitResult(context, tempRegister.Operand, rd, top);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs
new file mode 100644
index 00000000..5c1eefac
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs
@@ -0,0 +1,22 @@
+using Ryujinx.Cpu.LightningJit.CodeGen;
+
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitVfpMove
+ {
+ public static void Vsel(CodeGenContext context, uint rd, uint rn, uint rm, uint cc, uint size)
+ {
+ bool singleRegs = size != 3;
+ uint cond = (cc << 2) | ((cc & 2) ^ ((cc << 1) & 2));
+
+ using ScopedRegister rnReg = InstEmitNeonCommon.MoveScalarToSide(context, rn, singleRegs);
+ using ScopedRegister rmReg = InstEmitNeonCommon.MoveScalarToSide(context, rm, singleRegs);
+
+ using ScopedRegister tempRegister = InstEmitNeonCommon.PickSimdRegister(context.RegisterAllocator, rnReg, rmReg);
+
+ context.Arm64Assembler.FcselFloat(tempRegister.Operand, rnReg.Operand, cond, rmReg.Operand, size ^ 2u);
+
+ InstEmitNeonCommon.InsertResult(context, tempRegister.Operand, rd, singleRegs);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs
new file mode 100644
index 00000000..2826fa64
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs
@@ -0,0 +1,40 @@
+namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
+{
+ static class InstEmitVfpRound
+ {
+ public static void Vrinta(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintaFloat);
+ }
+
+ public static void Vrintm(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintmFloat);
+ }
+
+ public static void Vrintn(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintnFloat);
+ }
+
+ public static void Vrintp(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintpFloat);
+ }
+
+ public static void Vrintr(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintiFloat);
+ }
+
+ public static void Vrintx(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintxFloat);
+ }
+
+ public static void Vrintz(CodeGenContext context, uint rd, uint rm, uint size)
+ {
+ InstEmitNeonCommon.EmitScalarUnaryF(context, rd, rm, size, context.Arm64Assembler.FrintzFloat);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs
new file mode 100644
index 00000000..b46ae3b0
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs
@@ -0,0 +1,29 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ static class A64Compiler
+ {
+ public static CompiledFunction Compile(
+ CpuPreset cpuPreset,
+ IMemoryManager memoryManager,
+ ulong address,
+ AddressTable funcTable,
+ IntPtr dispatchStubPtr,
+ Architecture targetArch)
+ {
+ if (targetArch == Architecture.Arm64)
+ {
+ return Compiler.Compile(cpuPreset, memoryManager, address, funcTable, dispatchStubPtr);
+ }
+ else
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs
new file mode 100644
index 00000000..188630a1
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs
@@ -0,0 +1,138 @@
+using Ryujinx.Cpu.LightningJit.Graph;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ class Block : IBlock
+ {
+ public int Index { get; private set; }
+
+ private readonly List _predecessors;
+ private readonly List _successors;
+
+ public int PredecessorsCount => _predecessors.Count;
+ public int SuccessorsCount => _successors.Count;
+
+ public readonly ulong Address;
+ public readonly ulong EndAddress;
+ public readonly List Instructions;
+ public readonly bool EndsWithBranch;
+ public readonly bool IsTruncated;
+ public readonly bool IsLoopEnd;
+
+ public Block(ulong address, ulong endAddress, List instructions, bool endsWithBranch, bool isTruncated, bool isLoopEnd)
+ {
+ Debug.Assert((int)((endAddress - address) / 4) == instructions.Count);
+
+ _predecessors = new();
+ _successors = new();
+ Address = address;
+ EndAddress = endAddress;
+ Instructions = instructions;
+ EndsWithBranch = endsWithBranch;
+ IsTruncated = isTruncated;
+ IsLoopEnd = isLoopEnd;
+ }
+
+ public (Block, Block) SplitAtAddress(ulong address)
+ {
+ int splitIndex = (int)((address - Address) / 4);
+ int splitCount = Instructions.Count - splitIndex;
+
+ // Technically those are valid, but we don't want to create empty blocks.
+ Debug.Assert(splitIndex != 0);
+ Debug.Assert(splitCount != 0);
+
+ Block leftBlock = new(
+ Address,
+ address,
+ Instructions.GetRange(0, splitIndex),
+ false,
+ false,
+ false);
+
+ Block rightBlock = new(
+ address,
+ EndAddress,
+ Instructions.GetRange(splitIndex, splitCount),
+ EndsWithBranch,
+ IsTruncated,
+ IsLoopEnd);
+
+ return (leftBlock, rightBlock);
+ }
+
+ public void Number(int index)
+ {
+ Index = index;
+ }
+
+ public void AddSuccessor(Block block)
+ {
+ if (!_successors.Contains(block))
+ {
+ _successors.Add(block);
+ }
+ }
+
+ public void AddPredecessor(Block block)
+ {
+ if (!_predecessors.Contains(block))
+ {
+ _predecessors.Add(block);
+ }
+ }
+
+ public IBlock GetSuccessor(int index)
+ {
+ return _successors[index];
+ }
+
+ public IBlock GetPredecessor(int index)
+ {
+ return _predecessors[index];
+ }
+
+ public RegisterUse ComputeUseMasks()
+ {
+ if (Instructions.Count == 0)
+ {
+ return new(0u, 0u, 0u, 0u, 0u, 0u);
+ }
+
+ RegisterUse use = Instructions[0].RegisterUse;
+
+ for (int index = 1; index < Instructions.Count; index++)
+ {
+ RegisterUse currentUse = Instructions[index].RegisterUse;
+
+ use = new(use.Read | (currentUse.Read & ~use.Write), use.Write | currentUse.Write);
+ }
+
+ return use;
+ }
+
+ public bool EndsWithContextLoad()
+ {
+ return !IsTruncated && EndsWithContextStoreAndLoad();
+ }
+
+ public bool EndsWithContextStore()
+ {
+ return EndsWithContextStoreAndLoad();
+ }
+
+ private bool EndsWithContextStoreAndLoad()
+ {
+ if (Instructions.Count == 0)
+ {
+ return false;
+ }
+
+ InstName lastInstructionName = Instructions[^1].Name;
+
+ return lastInstructionName.IsCall() || lastInstructionName.IsException();
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs
new file mode 100644
index 00000000..8a12756b
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ static class ImmUtils
+ {
+ public static int ExtractSImm14Times4(uint encoding)
+ {
+ return ((int)(encoding >> 5) << 18) >> 16;
+ }
+
+ public static int ExtractSImm19Times4(uint encoding)
+ {
+ return ((int)(encoding >> 5) << 13) >> 11;
+ }
+
+ public static int ExtractSImm26Times4(uint encoding)
+ {
+ return (int)(encoding << 6) >> 4;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs
new file mode 100644
index 00000000..5a6c3eb0
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs
@@ -0,0 +1,108 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ [Flags]
+ enum InstFlags
+ {
+ None = 0,
+ Rd = 1 << 0,
+ RdSP = Rd | (1 << 1),
+ ReadRd = 1 << 2,
+ Rt = 1 << 3,
+ RtSeq = Rt | (1 << 4),
+ ReadRt = 1 << 5,
+ Rt2 = 1 << 6,
+ Rn = 1 << 7,
+ RnSeq = Rn | (1 << 8),
+ RnSP = Rn | (1 << 9),
+ Rm = 1 << 10,
+ Rs = 1 << 11,
+ Ra = 1 << 12,
+ Nzcv = 1 << 13,
+ C = 1 << 14,
+ S = 1 << 15,
+ Qc = 1 << 16,
+ FpSimd = 1 << 17,
+ FpSimdFromGpr = FpSimd | (1 << 18),
+ FpSimdToGpr = FpSimd | (1 << 19),
+ FpSimdFromToGpr = FpSimdFromGpr | FpSimdToGpr,
+ Memory = 1 << 20,
+ MemWBack = 1 << 21,
+
+ RdFpSimd = Rd | FpSimd,
+ RdReadRd = Rd | ReadRd,
+ RdReadRdRn = Rd | ReadRd | Rn,
+ RdReadRdRnFpSimd = Rd | ReadRd | Rn | FpSimd,
+ RdReadRdRnFpSimdFromGpr = Rd | ReadRd | Rn | FpSimdFromGpr,
+ RdReadRdRnQcFpSimd = Rd | ReadRd | Rn | Qc | FpSimd,
+ RdReadRdRnRmFpSimd = Rd | ReadRd | Rn | Rm | FpSimd,
+ RdReadRdRnRmQcFpSimd = Rd | ReadRd | Rn | Rm | Qc | FpSimd,
+ RdRn = Rd | Rn,
+ RdRnFpSimd = Rd | Rn | FpSimd,
+ RdRnFpSimdFromGpr = Rd | Rn | FpSimdFromGpr,
+ RdRnFpSimdToGpr = Rd | Rn | FpSimdToGpr,
+ RdRnQcFpSimd = Rd | Rn | Qc | FpSimd,
+ RdRnRm = Rd | Rn | Rm,
+ RdRnRmC = Rd | Rn | Rm | C,
+ RdRnRmCS = Rd | Rn | Rm | C | S,
+ RdRnRmFpSimd = Rd | Rn | Rm | FpSimd,
+ RdRnRmNzcv = Rd | Rn | Rm | Nzcv,
+ RdRnRmNzcvFpSimd = Rd | Rn | Rm | Nzcv | FpSimd,
+ RdRnRmQcFpSimd = Rd | Rn | Rm | Qc | FpSimd,
+ RdRnRmRa = Rd | Rn | Rm | Ra,
+ RdRnRmRaFpSimd = Rd | Rn | Rm | Ra | FpSimd,
+ RdRnRmS = Rd | Rn | Rm | S,
+ RdRnRsS = Rd | Rn | Rs | S,
+ RdRnS = Rd | Rn | S,
+ RdRnSeqRmFpSimd = Rd | RnSeq | Rm | FpSimd,
+ RdRnSFpSimd = Rd | Rn | S | FpSimd,
+ RdRnSFpSimdFromToGpr = Rd | Rn | S | FpSimdFromToGpr,
+ RdRnSP = Rd | RnSP,
+ RdRnSPRmS = Rd | RnSP | Rm | S,
+ RdRnSPS = Rd | RnSP | S,
+ RdSPRn = RdSP | Rn,
+ RdSPRnSP = RdSP | RnSP,
+ RdSPRnSPRm = RdSP | RnSP | Rm,
+ RnC = Rn | C,
+ RnNzcvS = Rn | Nzcv | S,
+ RnRm = Rn | Rm,
+ RnRmNzcvS = Rn | Rm | Nzcv | S,
+ RnRmNzcvSFpSimd = Rn | Rm | Nzcv | S | FpSimd,
+ RnRmSFpSimd = Rn | Rm | S | FpSimd,
+ RnSPRm = RnSP | Rm,
+ RtFpSimd = Rt | FpSimd,
+ RtReadRt = Rt | ReadRt,
+ RtReadRtRnSP = Rt | ReadRt | RnSP,
+ RtReadRtRnSPFpSimd = Rt | ReadRt | RnSP | FpSimd,
+ RtReadRtRnSPFpSimdMemWBack = Rt | ReadRt | RnSP | FpSimd | MemWBack,
+ RtReadRtRnSPMemWBack = Rt | ReadRt | RnSP | MemWBack,
+ RtReadRtRnSPRm = Rt | ReadRt | RnSP | Rm,
+ RtReadRtRnSPRmFpSimd = Rt | ReadRt | RnSP | Rm | FpSimd,
+ RtReadRtRnSPRmFpSimdMemWBack = Rt | ReadRt | RnSP | Rm | FpSimd | MemWBack,
+ RtReadRtRnSPRs = Rt | ReadRt | RnSP | Rs,
+ RtReadRtRnSPRsS = Rt | ReadRt | RnSP | Rs | S,
+ RtReadRtRt2RnSP = Rt | ReadRt | Rt2 | RnSP,
+ RtReadRtRt2RnSPFpSimd = Rt | ReadRt | Rt2 | RnSP | FpSimd,
+ RtReadRtRt2RnSPFpSimdMemWBack = Rt | ReadRt | Rt2 | RnSP | FpSimd | MemWBack,
+ RtReadRtRt2RnSPMemWBack = Rt | ReadRt | Rt2 | RnSP | MemWBack,
+ RtReadRtRt2RnSPRs = Rt | ReadRt | Rt2 | RnSP | Rs,
+ RtReadRtRt2RnSPS = Rt | ReadRt | Rt2 | RnSP | S,
+ RtRnSP = Rt | RnSP,
+ RtRnSPFpSimd = Rt | RnSP | FpSimd,
+ RtRnSPFpSimdMemWBack = Rt | RnSP | FpSimd | MemWBack,
+ RtRnSPMemWBack = Rt | RnSP | MemWBack,
+ RtRnSPRm = Rt | RnSP | Rm,
+ RtRnSPRmFpSimd = Rt | RnSP | Rm | FpSimd,
+ RtRnSPRmFpSimdMemWBack = Rt | RnSP | Rm | FpSimd | MemWBack,
+ RtRnSPRs = Rt | RnSP | Rs,
+ RtRt2RnSP = Rt | Rt2 | RnSP,
+ RtRt2RnSPFpSimd = Rt | Rt2 | RnSP | FpSimd,
+ RtRt2RnSPFpSimdMemWBack = Rt | Rt2 | RnSP | FpSimd | MemWBack,
+ RtRt2RnSPMemWBack = Rt | Rt2 | RnSP | MemWBack,
+ RtSeqReadRtRnSPFpSimd = RtSeq | ReadRt | RnSP | FpSimd,
+ RtSeqReadRtRnSPRmFpSimdMemWBack = RtSeq | ReadRt | RnSP | Rm | FpSimd | MemWBack,
+ RtSeqRnSPFpSimd = RtSeq | RnSP | FpSimd,
+ RtSeqRnSPRmFpSimdMemWBack = RtSeq | RnSP | Rm | FpSimd | MemWBack,
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs
new file mode 100644
index 00000000..031a3657
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs
@@ -0,0 +1,22 @@
+using Ryujinx.Cpu.LightningJit.Graph;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ readonly struct InstInfo
+ {
+ public readonly uint Encoding;
+ public readonly InstName Name;
+ public readonly InstFlags Flags;
+ public readonly AddressForm AddressForm;
+ public readonly RegisterUse RegisterUse;
+
+ public InstInfo(uint encoding, InstName name, InstFlags flags, AddressForm addressForm, in RegisterUse registerUse)
+ {
+ Encoding = encoding;
+ Name = name;
+ Flags = flags;
+ AddressForm = addressForm;
+ RegisterUse = registerUse;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs
new file mode 100644
index 00000000..58d78ae6
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs
@@ -0,0 +1,1134 @@
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ enum InstName
+ {
+ Abs,
+ AbsAdvsimdS,
+ AbsAdvsimdV,
+ Adc,
+ Adcs,
+ AddAddsubExt,
+ AddAddsubImm,
+ AddAddsubShift,
+ AddAdvsimdS,
+ AddAdvsimdV,
+ Addg,
+ AddhnAdvsimd,
+ AddpAdvsimdPair,
+ AddpAdvsimdVec,
+ AddsAddsubExt,
+ AddsAddsubImm,
+ AddsAddsubShift,
+ AddvAdvsimd,
+ Adr,
+ Adrp,
+ AesdAdvsimd,
+ AeseAdvsimd,
+ AesimcAdvsimd,
+ AesmcAdvsimd,
+ AndAdvsimd,
+ AndLogImm,
+ AndLogShift,
+ AndsLogImm,
+ AndsLogShift,
+ Asrv,
+ Autda,
+ Autdb,
+ AutiaGeneral,
+ AutiaSystem,
+ AutibGeneral,
+ AutibSystem,
+ Axflag,
+ BcaxAdvsimd,
+ BcCond,
+ BCond,
+ BfcvtFloat,
+ BfcvtnAdvsimd,
+ BfdotAdvsimdElt,
+ BfdotAdvsimdVec,
+ Bfm,
+ BfmlalAdvsimdElt,
+ BfmlalAdvsimdVec,
+ BfmmlaAdvsimd,
+ BicAdvsimdImm,
+ BicAdvsimdReg,
+ BicLogShift,
+ Bics,
+ BifAdvsimd,
+ BitAdvsimd,
+ Bl,
+ Blr,
+ Blra,
+ Br,
+ Bra,
+ Brk,
+ BslAdvsimd,
+ Bti,
+ BUncond,
+ Cas,
+ Casb,
+ Cash,
+ Casp,
+ Cbnz,
+ Cbz,
+ CcmnImm,
+ CcmnReg,
+ CcmpImm,
+ CcmpReg,
+ Cfinv,
+ Chkfeat,
+ Clrbhb,
+ Clrex,
+ ClsAdvsimd,
+ ClsInt,
+ ClzAdvsimd,
+ ClzInt,
+ CmeqAdvsimdRegS,
+ CmeqAdvsimdRegV,
+ CmeqAdvsimdZeroS,
+ CmeqAdvsimdZeroV,
+ CmgeAdvsimdRegS,
+ CmgeAdvsimdRegV,
+ CmgeAdvsimdZeroS,
+ CmgeAdvsimdZeroV,
+ CmgtAdvsimdRegS,
+ CmgtAdvsimdRegV,
+ CmgtAdvsimdZeroS,
+ CmgtAdvsimdZeroV,
+ CmhiAdvsimdS,
+ CmhiAdvsimdV,
+ CmhsAdvsimdS,
+ CmhsAdvsimdV,
+ CmleAdvsimdS,
+ CmleAdvsimdV,
+ CmltAdvsimdS,
+ CmltAdvsimdV,
+ CmtstAdvsimdS,
+ CmtstAdvsimdV,
+ Cnt,
+ CntAdvsimd,
+ Cpyfp,
+ Cpyfpn,
+ Cpyfprn,
+ Cpyfprt,
+ Cpyfprtn,
+ Cpyfprtrn,
+ Cpyfprtwn,
+ Cpyfpt,
+ Cpyfptn,
+ Cpyfptrn,
+ Cpyfptwn,
+ Cpyfpwn,
+ Cpyfpwt,
+ Cpyfpwtn,
+ Cpyfpwtrn,
+ Cpyfpwtwn,
+ Cpyp,
+ Cpypn,
+ Cpyprn,
+ Cpyprt,
+ Cpyprtn,
+ Cpyprtrn,
+ Cpyprtwn,
+ Cpypt,
+ Cpyptn,
+ Cpyptrn,
+ Cpyptwn,
+ Cpypwn,
+ Cpypwt,
+ Cpypwtn,
+ Cpypwtrn,
+ Cpypwtwn,
+ Crc32,
+ Crc32c,
+ Csdb,
+ Csel,
+ Csinc,
+ Csinv,
+ Csneg,
+ Ctz,
+ Dcps1,
+ Dcps2,
+ Dcps3,
+ Dgh,
+ Dmb,
+ Drps,
+ DsbDsbMemory,
+ DsbDsbNxs,
+ DupAdvsimdEltScalarFromElement,
+ DupAdvsimdEltVectorFromElement,
+ DupAdvsimdGen,
+ Eon,
+ Eor3Advsimd,
+ EorAdvsimd,
+ EorLogImm,
+ EorLogShift,
+ Eret,
+ Ereta,
+ Esb,
+ ExtAdvsimd,
+ Extr,
+ FabdAdvsimdS,
+ FabdAdvsimdSH,
+ FabdAdvsimdV,
+ FabdAdvsimdVH,
+ FabsAdvsimdHalf,
+ FabsAdvsimdSingleAndDouble,
+ FabsFloat,
+ FacgeAdvsimdS,
+ FacgeAdvsimdSH,
+ FacgeAdvsimdV,
+ FacgeAdvsimdVH,
+ FacgtAdvsimdS,
+ FacgtAdvsimdSH,
+ FacgtAdvsimdV,
+ FacgtAdvsimdVH,
+ FaddAdvsimdHalf,
+ FaddAdvsimdSingleAndDouble,
+ FaddFloat,
+ FaddpAdvsimdPairHalf,
+ FaddpAdvsimdPairSingleAndDouble,
+ FaddpAdvsimdVecHalf,
+ FaddpAdvsimdVecSingleAndDouble,
+ FcaddAdvsimdVec,
+ FccmpeFloat,
+ FccmpFloat,
+ FcmeqAdvsimdRegS,
+ FcmeqAdvsimdRegSH,
+ FcmeqAdvsimdRegV,
+ FcmeqAdvsimdRegVH,
+ FcmeqAdvsimdZeroS,
+ FcmeqAdvsimdZeroSH,
+ FcmeqAdvsimdZeroV,
+ FcmeqAdvsimdZeroVH,
+ FcmgeAdvsimdRegS,
+ FcmgeAdvsimdRegSH,
+ FcmgeAdvsimdRegV,
+ FcmgeAdvsimdRegVH,
+ FcmgeAdvsimdZeroS,
+ FcmgeAdvsimdZeroSH,
+ FcmgeAdvsimdZeroV,
+ FcmgeAdvsimdZeroVH,
+ FcmgtAdvsimdRegS,
+ FcmgtAdvsimdRegSH,
+ FcmgtAdvsimdRegV,
+ FcmgtAdvsimdRegVH,
+ FcmgtAdvsimdZeroS,
+ FcmgtAdvsimdZeroSH,
+ FcmgtAdvsimdZeroV,
+ FcmgtAdvsimdZeroVH,
+ FcmlaAdvsimdElt,
+ FcmlaAdvsimdVec,
+ FcmleAdvsimdS,
+ FcmleAdvsimdSH,
+ FcmleAdvsimdV,
+ FcmleAdvsimdVH,
+ FcmltAdvsimdS,
+ FcmltAdvsimdSH,
+ FcmltAdvsimdV,
+ FcmltAdvsimdVH,
+ FcmpeFloat,
+ FcmpFloat,
+ FcselFloat,
+ FcvtasAdvsimdS,
+ FcvtasAdvsimdSH,
+ FcvtasAdvsimdV,
+ FcvtasAdvsimdVH,
+ FcvtasFloat,
+ FcvtauAdvsimdS,
+ FcvtauAdvsimdSH,
+ FcvtauAdvsimdV,
+ FcvtauAdvsimdVH,
+ FcvtauFloat,
+ FcvtFloat,
+ FcvtlAdvsimd,
+ FcvtmsAdvsimdS,
+ FcvtmsAdvsimdSH,
+ FcvtmsAdvsimdV,
+ FcvtmsAdvsimdVH,
+ FcvtmsFloat,
+ FcvtmuAdvsimdS,
+ FcvtmuAdvsimdSH,
+ FcvtmuAdvsimdV,
+ FcvtmuAdvsimdVH,
+ FcvtmuFloat,
+ FcvtnAdvsimd,
+ FcvtnsAdvsimdS,
+ FcvtnsAdvsimdSH,
+ FcvtnsAdvsimdV,
+ FcvtnsAdvsimdVH,
+ FcvtnsFloat,
+ FcvtnuAdvsimdS,
+ FcvtnuAdvsimdSH,
+ FcvtnuAdvsimdV,
+ FcvtnuAdvsimdVH,
+ FcvtnuFloat,
+ FcvtpsAdvsimdS,
+ FcvtpsAdvsimdSH,
+ FcvtpsAdvsimdV,
+ FcvtpsAdvsimdVH,
+ FcvtpsFloat,
+ FcvtpuAdvsimdS,
+ FcvtpuAdvsimdSH,
+ FcvtpuAdvsimdV,
+ FcvtpuAdvsimdVH,
+ FcvtpuFloat,
+ FcvtxnAdvsimdS,
+ FcvtxnAdvsimdV,
+ FcvtzsAdvsimdFixS,
+ FcvtzsAdvsimdFixV,
+ FcvtzsAdvsimdIntS,
+ FcvtzsAdvsimdIntSH,
+ FcvtzsAdvsimdIntV,
+ FcvtzsAdvsimdIntVH,
+ FcvtzsFloatFix,
+ FcvtzsFloatInt,
+ FcvtzuAdvsimdFixS,
+ FcvtzuAdvsimdFixV,
+ FcvtzuAdvsimdIntS,
+ FcvtzuAdvsimdIntSH,
+ FcvtzuAdvsimdIntV,
+ FcvtzuAdvsimdIntVH,
+ FcvtzuFloatFix,
+ FcvtzuFloatInt,
+ FdivAdvsimdHalf,
+ FdivAdvsimdSingleAndDouble,
+ FdivFloat,
+ Fjcvtzs,
+ FmaddFloat,
+ FmaxAdvsimdHalf,
+ FmaxAdvsimdSingleAndDouble,
+ FmaxFloat,
+ FmaxnmAdvsimdHalf,
+ FmaxnmAdvsimdSingleAndDouble,
+ FmaxnmFloat,
+ FmaxnmpAdvsimdPairHalf,
+ FmaxnmpAdvsimdPairSingleAndDouble,
+ FmaxnmpAdvsimdVecHalf,
+ FmaxnmpAdvsimdVecSingleAndDouble,
+ FmaxnmvAdvsimdHalf,
+ FmaxnmvAdvsimdSingleAndDouble,
+ FmaxpAdvsimdPairHalf,
+ FmaxpAdvsimdPairSingleAndDouble,
+ FmaxpAdvsimdVecHalf,
+ FmaxpAdvsimdVecSingleAndDouble,
+ FmaxvAdvsimdHalf,
+ FmaxvAdvsimdSingleAndDouble,
+ FminAdvsimdHalf,
+ FminAdvsimdSingleAndDouble,
+ FminFloat,
+ FminnmAdvsimdHalf,
+ FminnmAdvsimdSingleAndDouble,
+ FminnmFloat,
+ FminnmpAdvsimdPairHalf,
+ FminnmpAdvsimdPairSingleAndDouble,
+ FminnmpAdvsimdVecHalf,
+ FminnmpAdvsimdVecSingleAndDouble,
+ FminnmvAdvsimdHalf,
+ FminnmvAdvsimdSingleAndDouble,
+ FminpAdvsimdPairHalf,
+ FminpAdvsimdPairSingleAndDouble,
+ FminpAdvsimdVecHalf,
+ FminpAdvsimdVecSingleAndDouble,
+ FminvAdvsimdHalf,
+ FminvAdvsimdSingleAndDouble,
+ FmlaAdvsimdElt2regElementHalf,
+ FmlaAdvsimdElt2regElementSingleAndDouble,
+ FmlaAdvsimdElt2regScalarHalf,
+ FmlaAdvsimdElt2regScalarSingleAndDouble,
+ FmlaAdvsimdVecHalf,
+ FmlaAdvsimdVecSingleAndDouble,
+ FmlalAdvsimdEltFmlal,
+ FmlalAdvsimdEltFmlal2,
+ FmlalAdvsimdVecFmlal,
+ FmlalAdvsimdVecFmlal2,
+ FmlsAdvsimdElt2regElementHalf,
+ FmlsAdvsimdElt2regElementSingleAndDouble,
+ FmlsAdvsimdElt2regScalarHalf,
+ FmlsAdvsimdElt2regScalarSingleAndDouble,
+ FmlsAdvsimdVecHalf,
+ FmlsAdvsimdVecSingleAndDouble,
+ FmlslAdvsimdEltFmlsl,
+ FmlslAdvsimdEltFmlsl2,
+ FmlslAdvsimdVecFmlsl,
+ FmlslAdvsimdVecFmlsl2,
+ FmovAdvsimdPerHalf,
+ FmovAdvsimdSingleAndDouble,
+ FmovFloat,
+ FmovFloatGen,
+ FmovFloatImm,
+ FmsubFloat,
+ FmulAdvsimdElt2regElementHalf,
+ FmulAdvsimdElt2regElementSingleAndDouble,
+ FmulAdvsimdElt2regScalarHalf,
+ FmulAdvsimdElt2regScalarSingleAndDouble,
+ FmulAdvsimdVecHalf,
+ FmulAdvsimdVecSingleAndDouble,
+ FmulFloat,
+ FmulxAdvsimdElt2regElementHalf,
+ FmulxAdvsimdElt2regElementSingleAndDouble,
+ FmulxAdvsimdElt2regScalarHalf,
+ FmulxAdvsimdElt2regScalarSingleAndDouble,
+ FmulxAdvsimdVecS,
+ FmulxAdvsimdVecSH,
+ FmulxAdvsimdVecV,
+ FmulxAdvsimdVecVH,
+ FnegAdvsimdHalf,
+ FnegAdvsimdSingleAndDouble,
+ FnegFloat,
+ FnmaddFloat,
+ FnmsubFloat,
+ FnmulFloat,
+ FrecpeAdvsimdS,
+ FrecpeAdvsimdSH,
+ FrecpeAdvsimdV,
+ FrecpeAdvsimdVH,
+ FrecpsAdvsimdS,
+ FrecpsAdvsimdSH,
+ FrecpsAdvsimdV,
+ FrecpsAdvsimdVH,
+ FrecpxAdvsimdHalf,
+ FrecpxAdvsimdSingleAndDouble,
+ Frint32xAdvsimd,
+ Frint32xFloat,
+ Frint32zAdvsimd,
+ Frint32zFloat,
+ Frint64xAdvsimd,
+ Frint64xFloat,
+ Frint64zAdvsimd,
+ Frint64zFloat,
+ FrintaAdvsimdHalf,
+ FrintaAdvsimdSingleAndDouble,
+ FrintaFloat,
+ FrintiAdvsimdHalf,
+ FrintiAdvsimdSingleAndDouble,
+ FrintiFloat,
+ FrintmAdvsimdHalf,
+ FrintmAdvsimdSingleAndDouble,
+ FrintmFloat,
+ FrintnAdvsimdHalf,
+ FrintnAdvsimdSingleAndDouble,
+ FrintnFloat,
+ FrintpAdvsimdHalf,
+ FrintpAdvsimdSingleAndDouble,
+ FrintpFloat,
+ FrintxAdvsimdHalf,
+ FrintxAdvsimdSingleAndDouble,
+ FrintxFloat,
+ FrintzAdvsimdHalf,
+ FrintzAdvsimdSingleAndDouble,
+ FrintzFloat,
+ FrsqrteAdvsimdS,
+ FrsqrteAdvsimdSH,
+ FrsqrteAdvsimdV,
+ FrsqrteAdvsimdVH,
+ FrsqrtsAdvsimdS,
+ FrsqrtsAdvsimdSH,
+ FrsqrtsAdvsimdV,
+ FrsqrtsAdvsimdVH,
+ FsqrtAdvsimdHalf,
+ FsqrtAdvsimdSingleAndDouble,
+ FsqrtFloat,
+ FsubAdvsimdHalf,
+ FsubAdvsimdSingleAndDouble,
+ FsubFloat,
+ Gcsb,
+ Gcsstr,
+ Gcssttr,
+ Gmi,
+ Hint,
+ Hlt,
+ Hvc,
+ InsAdvsimdElt,
+ InsAdvsimdGen,
+ Irg,
+ Isb,
+ Ld1AdvsimdMultAsNoPostIndex,
+ Ld1AdvsimdMultAsPostIndex,
+ Ld1AdvsimdSnglAsNoPostIndex,
+ Ld1AdvsimdSnglAsPostIndex,
+ Ld1rAdvsimdAsNoPostIndex,
+ Ld1rAdvsimdAsPostIndex,
+ Ld2AdvsimdMultAsNoPostIndex,
+ Ld2AdvsimdMultAsPostIndex,
+ Ld2AdvsimdSnglAsNoPostIndex,
+ Ld2AdvsimdSnglAsPostIndex,
+ Ld2rAdvsimdAsNoPostIndex,
+ Ld2rAdvsimdAsPostIndex,
+ Ld3AdvsimdMultAsNoPostIndex,
+ Ld3AdvsimdMultAsPostIndex,
+ Ld3AdvsimdSnglAsNoPostIndex,
+ Ld3AdvsimdSnglAsPostIndex,
+ Ld3rAdvsimdAsNoPostIndex,
+ Ld3rAdvsimdAsPostIndex,
+ Ld4AdvsimdMultAsNoPostIndex,
+ Ld4AdvsimdMultAsPostIndex,
+ Ld4AdvsimdSnglAsNoPostIndex,
+ Ld4AdvsimdSnglAsPostIndex,
+ Ld4rAdvsimdAsNoPostIndex,
+ Ld4rAdvsimdAsPostIndex,
+ Ld64b,
+ Ldadd,
+ Ldaddb,
+ Ldaddh,
+ Ldap1AdvsimdSngl,
+ Ldaprb,
+ LdaprBaseRegister,
+ Ldaprh,
+ LdaprPostIndexed,
+ Ldapurb,
+ LdapurFpsimd,
+ LdapurGen,
+ Ldapurh,
+ Ldapursb,
+ Ldapursh,
+ Ldapursw,
+ Ldar,
+ Ldarb,
+ Ldarh,
+ Ldaxp,
+ Ldaxr,
+ Ldaxrb,
+ Ldaxrh,
+ Ldclr,
+ Ldclrb,
+ Ldclrh,
+ Ldclrp,
+ Ldeor,
+ Ldeorb,
+ Ldeorh,
+ Ldg,
+ Ldgm,
+ Ldiapp,
+ Ldlar,
+ Ldlarb,
+ Ldlarh,
+ LdnpFpsimd,
+ LdnpGen,
+ LdpFpsimdPostIndexed,
+ LdpFpsimdPreIndexed,
+ LdpFpsimdSignedScaledOffset,
+ LdpGenPostIndexed,
+ LdpGenPreIndexed,
+ LdpGenSignedScaledOffset,
+ LdpswPostIndexed,
+ LdpswPreIndexed,
+ LdpswSignedScaledOffset,
+ Ldra,
+ LdrbImmPostIndexed,
+ LdrbImmPreIndexed,
+ LdrbImmUnsignedScaledOffset,
+ LdrbReg,
+ LdrhImmPostIndexed,
+ LdrhImmPreIndexed,
+ LdrhImmUnsignedScaledOffset,
+ LdrhReg,
+ LdrImmFpsimdPostIndexed,
+ LdrImmFpsimdPreIndexed,
+ LdrImmFpsimdUnsignedScaledOffset,
+ LdrImmGenPostIndexed,
+ LdrImmGenPreIndexed,
+ LdrImmGenUnsignedScaledOffset,
+ LdrLitFpsimd,
+ LdrLitGen,
+ LdrRegFpsimd,
+ LdrRegGen,
+ LdrsbImmPostIndexed,
+ LdrsbImmPreIndexed,
+ LdrsbImmUnsignedScaledOffset,
+ LdrsbReg,
+ LdrshImmPostIndexed,
+ LdrshImmPreIndexed,
+ LdrshImmUnsignedScaledOffset,
+ LdrshReg,
+ LdrswImmPostIndexed,
+ LdrswImmPreIndexed,
+ LdrswImmUnsignedScaledOffset,
+ LdrswLit,
+ LdrswReg,
+ Ldset,
+ Ldsetb,
+ Ldseth,
+ Ldsetp,
+ Ldsmax,
+ Ldsmaxb,
+ Ldsmaxh,
+ Ldsmin,
+ Ldsminb,
+ Ldsminh,
+ Ldtr,
+ Ldtrb,
+ Ldtrh,
+ Ldtrsb,
+ Ldtrsh,
+ Ldtrsw,
+ Ldumax,
+ Ldumaxb,
+ Ldumaxh,
+ Ldumin,
+ Lduminb,
+ Lduminh,
+ Ldurb,
+ LdurFpsimd,
+ LdurGen,
+ Ldurh,
+ Ldursb,
+ Ldursh,
+ Ldursw,
+ Ldxp,
+ Ldxr,
+ Ldxrb,
+ Ldxrh,
+ Lslv,
+ Lsrv,
+ Madd,
+ MlaAdvsimdElt,
+ MlaAdvsimdVec,
+ MlsAdvsimdElt,
+ MlsAdvsimdVec,
+ MoviAdvsimd,
+ Movk,
+ Movn,
+ Movz,
+ Mrrs,
+ Mrs,
+ MsrImm,
+ Msrr,
+ MsrReg,
+ Msub,
+ MulAdvsimdElt,
+ MulAdvsimdVec,
+ MvniAdvsimd,
+ NegAdvsimdS,
+ NegAdvsimdV,
+ Nop,
+ NotAdvsimd,
+ OrnAdvsimd,
+ OrnLogShift,
+ OrrAdvsimdImm,
+ OrrAdvsimdReg,
+ OrrLogImm,
+ OrrLogShift,
+ Pacda,
+ Pacdb,
+ Pacga,
+ PaciaGeneral,
+ PaciaSystem,
+ PacibGeneral,
+ PacibSystem,
+ PmulAdvsimd,
+ PmullAdvsimd,
+ PrfmImm,
+ PrfmLit,
+ PrfmReg,
+ Prfum,
+ Psb,
+ RaddhnAdvsimd,
+ Rax1Advsimd,
+ RbitAdvsimd,
+ RbitInt,
+ Rcwcas,
+ Rcwcasp,
+ Rcwclr,
+ Rcwclrp,
+ Rcwscas,
+ Rcwscasp,
+ Rcwsclr,
+ Rcwsclrp,
+ Rcwset,
+ Rcwsetp,
+ Rcwsset,
+ Rcwssetp,
+ Rcwsswp,
+ Rcwsswpp,
+ Rcwswp,
+ Rcwswpp,
+ Ret,
+ Reta,
+ Rev,
+ Rev16Advsimd,
+ Rev16Int,
+ Rev32Advsimd,
+ Rev32Int,
+ Rev64Advsimd,
+ Rmif,
+ Rorv,
+ RprfmReg,
+ RshrnAdvsimd,
+ RsubhnAdvsimd,
+ SabaAdvsimd,
+ SabalAdvsimd,
+ SabdAdvsimd,
+ SabdlAdvsimd,
+ SadalpAdvsimd,
+ SaddlAdvsimd,
+ SaddlpAdvsimd,
+ SaddlvAdvsimd,
+ SaddwAdvsimd,
+ Sb,
+ Sbc,
+ Sbcs,
+ Sbfm,
+ ScvtfAdvsimdFixS,
+ ScvtfAdvsimdFixV,
+ ScvtfAdvsimdIntS,
+ ScvtfAdvsimdIntSH,
+ ScvtfAdvsimdIntV,
+ ScvtfAdvsimdIntVH,
+ ScvtfFloatFix,
+ ScvtfFloatInt,
+ Sdiv,
+ SdotAdvsimdElt,
+ SdotAdvsimdVec,
+ Setf,
+ Setgp,
+ Setgpn,
+ Setgpt,
+ Setgptn,
+ Setp,
+ Setpn,
+ Setpt,
+ Setptn,
+ Sev,
+ Sevl,
+ Sha1cAdvsimd,
+ Sha1hAdvsimd,
+ Sha1mAdvsimd,
+ Sha1pAdvsimd,
+ Sha1su0Advsimd,
+ Sha1su1Advsimd,
+ Sha256h2Advsimd,
+ Sha256hAdvsimd,
+ Sha256su0Advsimd,
+ Sha256su1Advsimd,
+ Sha512h2Advsimd,
+ Sha512hAdvsimd,
+ Sha512su0Advsimd,
+ Sha512su1Advsimd,
+ ShaddAdvsimd,
+ ShlAdvsimdS,
+ ShlAdvsimdV,
+ ShllAdvsimd,
+ ShrnAdvsimd,
+ ShsubAdvsimd,
+ SliAdvsimdS,
+ SliAdvsimdV,
+ Sm3partw1Advsimd,
+ Sm3partw2Advsimd,
+ Sm3ss1Advsimd,
+ Sm3tt1aAdvsimd,
+ Sm3tt1bAdvsimd,
+ Sm3tt2aAdvsimd,
+ Sm3tt2bAdvsimd,
+ Sm4eAdvsimd,
+ Sm4ekeyAdvsimd,
+ Smaddl,
+ SmaxAdvsimd,
+ SmaxImm,
+ SmaxpAdvsimd,
+ SmaxReg,
+ SmaxvAdvsimd,
+ Smc,
+ SminAdvsimd,
+ SminImm,
+ SminpAdvsimd,
+ SminReg,
+ SminvAdvsimd,
+ SmlalAdvsimdElt,
+ SmlalAdvsimdVec,
+ SmlslAdvsimdElt,
+ SmlslAdvsimdVec,
+ SmmlaAdvsimdVec,
+ SmovAdvsimd,
+ Smsubl,
+ Smulh,
+ SmullAdvsimdElt,
+ SmullAdvsimdVec,
+ SqabsAdvsimdS,
+ SqabsAdvsimdV,
+ SqaddAdvsimdS,
+ SqaddAdvsimdV,
+ SqdmlalAdvsimdElt2regElement,
+ SqdmlalAdvsimdElt2regScalar,
+ SqdmlalAdvsimdVecS,
+ SqdmlalAdvsimdVecV,
+ SqdmlslAdvsimdElt2regElement,
+ SqdmlslAdvsimdElt2regScalar,
+ SqdmlslAdvsimdVecS,
+ SqdmlslAdvsimdVecV,
+ SqdmulhAdvsimdElt2regElement,
+ SqdmulhAdvsimdElt2regScalar,
+ SqdmulhAdvsimdVecS,
+ SqdmulhAdvsimdVecV,
+ SqdmullAdvsimdElt2regElement,
+ SqdmullAdvsimdElt2regScalar,
+ SqdmullAdvsimdVecS,
+ SqdmullAdvsimdVecV,
+ SqnegAdvsimdS,
+ SqnegAdvsimdV,
+ SqrdmlahAdvsimdElt2regElement,
+ SqrdmlahAdvsimdElt2regScalar,
+ SqrdmlahAdvsimdVecS,
+ SqrdmlahAdvsimdVecV,
+ SqrdmlshAdvsimdElt2regElement,
+ SqrdmlshAdvsimdElt2regScalar,
+ SqrdmlshAdvsimdVecS,
+ SqrdmlshAdvsimdVecV,
+ SqrdmulhAdvsimdElt2regElement,
+ SqrdmulhAdvsimdElt2regScalar,
+ SqrdmulhAdvsimdVecS,
+ SqrdmulhAdvsimdVecV,
+ SqrshlAdvsimdS,
+ SqrshlAdvsimdV,
+ SqrshrnAdvsimdS,
+ SqrshrnAdvsimdV,
+ SqrshrunAdvsimdS,
+ SqrshrunAdvsimdV,
+ SqshlAdvsimdImmS,
+ SqshlAdvsimdImmV,
+ SqshlAdvsimdRegS,
+ SqshlAdvsimdRegV,
+ SqshluAdvsimdS,
+ SqshluAdvsimdV,
+ SqshrnAdvsimdS,
+ SqshrnAdvsimdV,
+ SqshrunAdvsimdS,
+ SqshrunAdvsimdV,
+ SqsubAdvsimdS,
+ SqsubAdvsimdV,
+ SqxtnAdvsimdS,
+ SqxtnAdvsimdV,
+ SqxtunAdvsimdS,
+ SqxtunAdvsimdV,
+ SrhaddAdvsimd,
+ SriAdvsimdS,
+ SriAdvsimdV,
+ SrshlAdvsimdS,
+ SrshlAdvsimdV,
+ SrshrAdvsimdS,
+ SrshrAdvsimdV,
+ SrsraAdvsimdS,
+ SrsraAdvsimdV,
+ SshlAdvsimdS,
+ SshlAdvsimdV,
+ SshllAdvsimd,
+ SshrAdvsimdS,
+ SshrAdvsimdV,
+ SsraAdvsimdS,
+ SsraAdvsimdV,
+ SsublAdvsimd,
+ SsubwAdvsimd,
+ St1AdvsimdMultAsNoPostIndex,
+ St1AdvsimdMultAsPostIndex,
+ St1AdvsimdSnglAsNoPostIndex,
+ St1AdvsimdSnglAsPostIndex,
+ St2AdvsimdMultAsNoPostIndex,
+ St2AdvsimdMultAsPostIndex,
+ St2AdvsimdSnglAsNoPostIndex,
+ St2AdvsimdSnglAsPostIndex,
+ St2gPostIndexed,
+ St2gPreIndexed,
+ St2gSignedScaledOffset,
+ St3AdvsimdMultAsNoPostIndex,
+ St3AdvsimdMultAsPostIndex,
+ St3AdvsimdSnglAsNoPostIndex,
+ St3AdvsimdSnglAsPostIndex,
+ St4AdvsimdMultAsNoPostIndex,
+ St4AdvsimdMultAsPostIndex,
+ St4AdvsimdSnglAsNoPostIndex,
+ St4AdvsimdSnglAsPostIndex,
+ St64b,
+ St64bv,
+ St64bv0,
+ Stgm,
+ StgPostIndexed,
+ StgpPostIndexed,
+ StgpPreIndexed,
+ StgPreIndexed,
+ StgpSignedScaledOffset,
+ StgSignedScaledOffset,
+ Stilp,
+ Stl1AdvsimdSngl,
+ Stllr,
+ Stllrb,
+ Stllrh,
+ Stlrb,
+ StlrBaseRegister,
+ Stlrh,
+ StlrPreIndexed,
+ Stlurb,
+ StlurFpsimd,
+ StlurGen,
+ Stlurh,
+ Stlxp,
+ Stlxr,
+ Stlxrb,
+ Stlxrh,
+ StnpFpsimd,
+ StnpGen,
+ StpFpsimdPostIndexed,
+ StpFpsimdPreIndexed,
+ StpFpsimdSignedScaledOffset,
+ StpGenPostIndexed,
+ StpGenPreIndexed,
+ StpGenSignedScaledOffset,
+ StrbImmPostIndexed,
+ StrbImmPreIndexed,
+ StrbImmUnsignedScaledOffset,
+ StrbReg,
+ StrhImmPostIndexed,
+ StrhImmPreIndexed,
+ StrhImmUnsignedScaledOffset,
+ StrhReg,
+ StrImmFpsimdPostIndexed,
+ StrImmFpsimdPreIndexed,
+ StrImmFpsimdUnsignedScaledOffset,
+ StrImmGenPostIndexed,
+ StrImmGenPreIndexed,
+ StrImmGenUnsignedScaledOffset,
+ StrRegFpsimd,
+ StrRegGen,
+ Sttr,
+ Sttrb,
+ Sttrh,
+ Sturb,
+ SturFpsimd,
+ SturGen,
+ Sturh,
+ Stxp,
+ Stxr,
+ Stxrb,
+ Stxrh,
+ Stz2gPostIndexed,
+ Stz2gPreIndexed,
+ Stz2gSignedScaledOffset,
+ Stzgm,
+ StzgPostIndexed,
+ StzgPreIndexed,
+ StzgSignedScaledOffset,
+ SubAddsubExt,
+ SubAddsubImm,
+ SubAddsubShift,
+ SubAdvsimdS,
+ SubAdvsimdV,
+ Subg,
+ SubhnAdvsimd,
+ Subp,
+ Subps,
+ SubsAddsubExt,
+ SubsAddsubImm,
+ SubsAddsubShift,
+ SudotAdvsimdElt,
+ SuqaddAdvsimdS,
+ SuqaddAdvsimdV,
+ Svc,
+ Swp,
+ Swpb,
+ Swph,
+ Swpp,
+ Sys,
+ Sysl,
+ Sysp,
+ TblAdvsimd,
+ Tbnz,
+ TbxAdvsimd,
+ Tbz,
+ Tcancel,
+ Tcommit,
+ Trn1Advsimd,
+ Trn2Advsimd,
+ Tsb,
+ Tstart,
+ Ttest,
+ UabaAdvsimd,
+ UabalAdvsimd,
+ UabdAdvsimd,
+ UabdlAdvsimd,
+ UadalpAdvsimd,
+ UaddlAdvsimd,
+ UaddlpAdvsimd,
+ UaddlvAdvsimd,
+ UaddwAdvsimd,
+ Ubfm,
+ UcvtfAdvsimdFixS,
+ UcvtfAdvsimdFixV,
+ UcvtfAdvsimdIntS,
+ UcvtfAdvsimdIntSH,
+ UcvtfAdvsimdIntV,
+ UcvtfAdvsimdIntVH,
+ UcvtfFloatFix,
+ UcvtfFloatInt,
+ UdfPermUndef,
+ Udiv,
+ UdotAdvsimdElt,
+ UdotAdvsimdVec,
+ UhaddAdvsimd,
+ UhsubAdvsimd,
+ Umaddl,
+ UmaxAdvsimd,
+ UmaxImm,
+ UmaxpAdvsimd,
+ UmaxReg,
+ UmaxvAdvsimd,
+ UminAdvsimd,
+ UminImm,
+ UminpAdvsimd,
+ UminReg,
+ UminvAdvsimd,
+ UmlalAdvsimdElt,
+ UmlalAdvsimdVec,
+ UmlslAdvsimdElt,
+ UmlslAdvsimdVec,
+ UmmlaAdvsimdVec,
+ UmovAdvsimd,
+ Umsubl,
+ Umulh,
+ UmullAdvsimdElt,
+ UmullAdvsimdVec,
+ UqaddAdvsimdS,
+ UqaddAdvsimdV,
+ UqrshlAdvsimdS,
+ UqrshlAdvsimdV,
+ UqrshrnAdvsimdS,
+ UqrshrnAdvsimdV,
+ UqshlAdvsimdImmS,
+ UqshlAdvsimdImmV,
+ UqshlAdvsimdRegS,
+ UqshlAdvsimdRegV,
+ UqshrnAdvsimdS,
+ UqshrnAdvsimdV,
+ UqsubAdvsimdS,
+ UqsubAdvsimdV,
+ UqxtnAdvsimdS,
+ UqxtnAdvsimdV,
+ UrecpeAdvsimd,
+ UrhaddAdvsimd,
+ UrshlAdvsimdS,
+ UrshlAdvsimdV,
+ UrshrAdvsimdS,
+ UrshrAdvsimdV,
+ UrsqrteAdvsimd,
+ UrsraAdvsimdS,
+ UrsraAdvsimdV,
+ UsdotAdvsimdElt,
+ UsdotAdvsimdVec,
+ UshlAdvsimdS,
+ UshlAdvsimdV,
+ UshllAdvsimd,
+ UshrAdvsimdS,
+ UshrAdvsimdV,
+ UsmmlaAdvsimdVec,
+ UsqaddAdvsimdS,
+ UsqaddAdvsimdV,
+ UsraAdvsimdS,
+ UsraAdvsimdV,
+ UsublAdvsimd,
+ UsubwAdvsimd,
+ Uzp1Advsimd,
+ Uzp2Advsimd,
+ Wfe,
+ Wfet,
+ Wfi,
+ Wfit,
+ Xaflag,
+ XarAdvsimd,
+ XpacGeneral,
+ XpacSystem,
+ XtnAdvsimd,
+ Yield,
+ Zip1Advsimd,
+ Zip2Advsimd,
+ }
+
+ static class InstNameExtensions
+ {
+ public static bool IsCall(this InstName name)
+ {
+ return name == InstName.Bl || name == InstName.Blr;
+ }
+
+ public static bool IsControlFlowOrException(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.BUncond:
+ case InstName.BCond:
+ case InstName.Bl:
+ case InstName.Blr:
+ case InstName.Br:
+ case InstName.Brk:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Ret:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ case InstName.Svc:
+ case InstName.UdfPermUndef:
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool IsException(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Brk:
+ case InstName.Svc:
+ case InstName.UdfPermUndef:
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool IsSystem(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Mrs:
+ case InstName.MsrImm:
+ case InstName.MsrReg:
+ return true;
+ }
+
+ return name.IsException();
+ }
+
+ public static bool IsSystemOrCall(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Bl:
+ case InstName.Blr:
+ case InstName.Svc:
+ case InstName.Mrs:
+ case InstName.MsrImm:
+ case InstName.MsrReg:
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool IsPrivileged(this InstName name)
+ {
+ switch (name)
+ {
+ case InstName.Dcps1:
+ case InstName.Dcps2:
+ case InstName.Dcps3:
+ case InstName.Drps:
+ case InstName.Eret:
+ case InstName.Ereta:
+ case InstName.Hvc:
+ case InstName.MsrImm:
+ case InstName.Smc:
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs
new file mode 100644
index 00000000..8ac65059
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs
@@ -0,0 +1,64 @@
+using Ryujinx.Cpu.LightningJit.Graph;
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ class MultiBlock : IBlockList
+ {
+ public readonly List Blocks;
+ public readonly RegisterMask[] ReadMasks;
+ public readonly RegisterMask[] WriteMasks;
+ public readonly RegisterMask GlobalUseMask;
+ public readonly bool HasHostCall;
+ public readonly bool HasMemoryInstruction;
+ public readonly bool IsTruncated;
+
+ public int Count => Blocks.Count;
+
+ public IBlock this[int index] => Blocks[index];
+
+ public MultiBlock(List blocks, RegisterMask globalUseMask, bool hasHostCall, bool hasMemoryInstruction)
+ {
+ Blocks = blocks;
+
+ (ReadMasks, WriteMasks) = DataFlow.GetGlobalUses(this);
+
+ GlobalUseMask = globalUseMask;
+ HasHostCall = hasHostCall;
+ HasMemoryInstruction = hasMemoryInstruction;
+ IsTruncated = blocks[^1].IsTruncated;
+ }
+
+ public void PrintDebugInfo()
+ {
+ foreach (Block block in Blocks)
+ {
+ Console.WriteLine($"bb {block.Index}");
+
+ List predList = new();
+ List succList = new();
+
+ for (int index = 0; index < block.PredecessorsCount; index++)
+ {
+ predList.Add(block.GetPredecessor(index).Index);
+ }
+
+ for (int index = 0; index < block.SuccessorsCount; index++)
+ {
+ succList.Add(block.GetSuccessor(index).Index);
+ }
+
+ Console.WriteLine($" predecessors: {string.Join(' ', predList)}");
+ Console.WriteLine($" successors: {string.Join(' ', succList)}");
+ Console.WriteLine($" gpr read mask: 0x{ReadMasks[block.Index].GprMask:X} 0x{block.ComputeUseMasks().Read.GprMask:X}");
+ Console.WriteLine($" gpr write mask: 0x{WriteMasks[block.Index].GprMask:X}");
+
+ for (int index = 0; index < block.Instructions.Count; index++)
+ {
+ Console.WriteLine($" {index} 0x{block.Instructions[index].Encoding:X8} {block.Instructions[index].Name}");
+ }
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
new file mode 100644
index 00000000..c9a93209
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
@@ -0,0 +1,154 @@
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ class RegisterAllocator
+ {
+ public const int MaxTemps = 1;
+ public const int MaxTempsInclFixed = MaxTemps + 2;
+
+ private uint _gprMask;
+ private readonly uint _fpSimdMask;
+ private readonly uint _pStateMask;
+
+ private uint _tempGprsMask;
+
+ private readonly int[] _registerMap;
+
+ public int FixedContextRegister { get; }
+ public int FixedPageTableRegister { get; }
+
+ public uint AllGprMask => (_gprMask & ~RegisterUtils.ReservedRegsMask) | _tempGprsMask;
+ public uint AllFpSimdMask => _fpSimdMask;
+ public uint AllPStateMask => _pStateMask;
+
+ public RegisterAllocator(uint gprMask, uint fpSimdMask, uint pStateMask, bool hasHostCall)
+ {
+ _gprMask = gprMask;
+ _fpSimdMask = fpSimdMask;
+ _pStateMask = pStateMask;
+
+ if (hasHostCall)
+ {
+ // If the function has calls, we can avoid the need to spill those registers across
+ // calls by puting them on callee saved registers.
+
+ FixedContextRegister = AllocateAndMarkTempGprRegisterWithPreferencing();
+ FixedPageTableRegister = AllocateAndMarkTempGprRegisterWithPreferencing();
+ }
+ else
+ {
+ FixedContextRegister = AllocateAndMarkTempGprRegister();
+ FixedPageTableRegister = AllocateAndMarkTempGprRegister();
+ }
+
+ _tempGprsMask = (1u << FixedContextRegister) | (1u << FixedPageTableRegister);
+
+ _registerMap = new int[32];
+
+ for (int index = 0; index < _registerMap.Length; index++)
+ {
+ _registerMap[index] = index;
+ }
+
+ BuildRegisterMap(_registerMap);
+
+ Span tempRegisters = stackalloc int[MaxTemps];
+
+ for (int index = 0; index < tempRegisters.Length; index++)
+ {
+ tempRegisters[index] = AllocateAndMarkTempGprRegister();
+ }
+
+ for (int index = 0; index < tempRegisters.Length; index++)
+ {
+ FreeTempGprRegister(tempRegisters[index]);
+ }
+ }
+
+ private void BuildRegisterMap(Span map)
+ {
+ uint mask = _gprMask & RegisterUtils.ReservedRegsMask;
+
+ while (mask != 0)
+ {
+ int index = BitOperations.TrailingZeroCount(mask);
+ int remapIndex = AllocateAndMarkTempGprRegister();
+
+ map[index] = remapIndex;
+ _tempGprsMask |= 1u << remapIndex;
+
+ mask &= ~(1u << index);
+ }
+ }
+
+ public int RemapReservedGprRegister(int index)
+ {
+ return _registerMap[index];
+ }
+
+ private int AllocateAndMarkTempGprRegister()
+ {
+ int index = AllocateTempGprRegister();
+ _tempGprsMask |= 1u << index;
+
+ return index;
+ }
+
+ private int AllocateAndMarkTempGprRegisterWithPreferencing()
+ {
+ int index = AllocateTempRegisterWithPreferencing();
+ _tempGprsMask |= 1u << index;
+
+ return index;
+ }
+
+ public int AllocateTempGprRegister()
+ {
+ return AllocateTempRegister(ref _gprMask);
+ }
+
+ public void FreeTempGprRegister(int index)
+ {
+ FreeTempRegister(ref _gprMask, index);
+ }
+
+ private int AllocateTempRegisterWithPreferencing()
+ {
+ int firstCalleeSaved = BitOperations.TrailingZeroCount(~_gprMask & AbiConstants.GprCalleeSavedRegsMask);
+ if (firstCalleeSaved < 32)
+ {
+ uint regMask = 1u << firstCalleeSaved;
+ if ((regMask & RegisterUtils.ReservedRegsMask) == 0)
+ {
+ _gprMask |= regMask;
+
+ return firstCalleeSaved;
+ }
+ }
+
+ return AllocateTempRegister(ref _gprMask);
+ }
+
+ private static int AllocateTempRegister(ref uint mask)
+ {
+ int index = BitOperations.TrailingZeroCount(~(mask | RegisterUtils.ReservedRegsMask));
+ if (index == sizeof(uint) * 8)
+ {
+ throw new InvalidOperationException("No free registers.");
+ }
+
+ mask |= 1u << index;
+
+ return index;
+ }
+
+ private static void FreeTempRegister(ref uint mask, int index)
+ {
+ mask &= ~(1u << index);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs
new file mode 100644
index 00000000..eb3fc229
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs
@@ -0,0 +1,495 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64
+{
+ static class RegisterUtils
+ {
+ private const int RdRtBit = 0;
+ private const int RnBit = 5;
+ private const int RmRsBit = 16;
+ private const int RaRt2Bit = 10;
+
+ // Some of those register have specific roles and can't be used as general purpose registers.
+ // X18 - Reserved for platform specific usage.
+ // X29 - Frame pointer.
+ // X30 - Return address.
+ // X31 - Not an actual register, in some cases maps to SP, and in others to ZR.
+ public const uint ReservedRegsMask = (1u << 18) | (1u << 29) | (1u << 30) | (1u << 31);
+
+ public const int LrIndex = 30;
+ public const int SpIndex = 31;
+ public const int ZrIndex = 31;
+ public const int SpecialZrIndex = 32;
+
+ public static uint RemapRegisters(RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ if (flags.HasFlag(InstFlags.Rd) && (!flags.HasFlag(InstFlags.FpSimd) || IsFpToGpr(flags, encoding)))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RdRtBit, flags.HasFlag(InstFlags.RdSP));
+ }
+
+ if (flags.HasFlag(InstFlags.Rn) && (!flags.HasFlag(InstFlags.FpSimd) || IsFpFromGpr(flags, encoding) || flags.HasFlag(InstFlags.Memory)))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RnBit, flags.HasFlag(InstFlags.RnSP));
+ }
+
+ if (!flags.HasFlag(InstFlags.FpSimd))
+ {
+ if (flags.HasFlag(InstFlags.Rm) || flags.HasFlag(InstFlags.Rs))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RmRsBit);
+ }
+
+ if (flags.HasFlag(InstFlags.Ra) || flags.HasFlag(InstFlags.Rt2))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RaRt2Bit);
+ }
+
+ if (flags.HasFlag(InstFlags.Rt))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RdRtBit);
+ }
+ }
+ else if (flags.HasFlag(InstFlags.Rm) && flags.HasFlag(InstFlags.Memory))
+ {
+ encoding = ReplaceGprRegister(regAlloc, encoding, RmRsBit);
+ }
+
+ return encoding;
+ }
+
+ public static uint ReplaceRt(uint encoding, int newIndex)
+ {
+ return ReplaceRegister(encoding, newIndex, RdRtBit);
+ }
+
+ public static uint ReplaceRn(uint encoding, int newIndex)
+ {
+ return ReplaceRegister(encoding, newIndex, RnBit);
+ }
+
+ private static uint ReplaceRegister(uint encoding, int newIndex, int bit)
+ {
+ encoding &= ~(0x1fu << bit);
+ encoding |= (uint)newIndex << bit;
+
+ return encoding;
+ }
+
+ private static uint ReplaceGprRegister(RegisterAllocator regAlloc, uint encoding, int bit, bool hasSP = false)
+ {
+ int oldIndex = (int)(encoding >> bit) & 0x1f;
+ if (oldIndex == ZrIndex && !hasSP)
+ {
+ return encoding;
+ }
+
+ int newIndex = regAlloc.RemapReservedGprRegister(oldIndex);
+
+ encoding &= ~(0x1fu << bit);
+ encoding |= (uint)newIndex << bit;
+
+ return encoding;
+ }
+
+ public static (uint, uint) PopulateReadMasks(InstName name, InstFlags flags, uint encoding)
+ {
+ uint gprMask = 0;
+ uint fpSimdMask = 0;
+
+ if (flags.HasFlag(InstFlags.FpSimd))
+ {
+ if (flags.HasFlag(InstFlags.Rd) && flags.HasFlag(InstFlags.ReadRd))
+ {
+ uint mask = MaskFromIndex(ExtractRd(flags, encoding));
+
+ if (IsFpToGpr(flags, encoding))
+ {
+ gprMask |= mask;
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Rn))
+ {
+ uint mask = MaskFromIndex(ExtractRn(flags, encoding));
+
+ if (flags.HasFlag(InstFlags.RnSeq))
+ {
+ int count = GetRnSequenceCount(encoding);
+
+ for (int index = 0; index < count; index++, mask <<= 1)
+ {
+ fpSimdMask |= mask;
+ }
+ }
+ else if (IsFpFromGpr(flags, encoding) || flags.HasFlag(InstFlags.Memory))
+ {
+ gprMask |= mask;
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Rm))
+ {
+ uint mask = MaskFromIndex(ExtractRm(flags, encoding));
+
+ if (flags.HasFlag(InstFlags.Memory))
+ {
+ gprMask |= mask;
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Ra))
+ {
+ fpSimdMask |= MaskFromIndex(ExtractRa(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.ReadRt))
+ {
+ if (flags.HasFlag(InstFlags.Rt))
+ {
+ uint mask = MaskFromIndex(ExtractRt(flags, encoding));
+
+ if (flags.HasFlag(InstFlags.RtSeq))
+ {
+ int count = GetRtSequenceCount(name, encoding);
+
+ for (int index = 0; index < count; index++, mask <<= 1)
+ {
+ fpSimdMask |= mask;
+ }
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Rt2))
+ {
+ fpSimdMask |= MaskFromIndex(ExtractRt2(flags, encoding));
+ }
+ }
+ }
+ else
+ {
+ if (flags.HasFlag(InstFlags.Rd) && flags.HasFlag(InstFlags.ReadRd))
+ {
+ gprMask |= MaskFromIndex(ExtractRd(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.Rn))
+ {
+ gprMask |= MaskFromIndex(ExtractRn(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.Rm))
+ {
+ gprMask |= MaskFromIndex(ExtractRm(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.Ra))
+ {
+ gprMask |= MaskFromIndex(ExtractRa(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.ReadRt))
+ {
+ if (flags.HasFlag(InstFlags.Rt))
+ {
+ gprMask |= MaskFromIndex(ExtractRt(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.Rt2))
+ {
+ gprMask |= MaskFromIndex(ExtractRt2(flags, encoding));
+ }
+ }
+ }
+
+ return (gprMask, fpSimdMask);
+ }
+
+ public static (uint, uint) PopulateWriteMasks(InstName name, InstFlags flags, uint encoding)
+ {
+ uint gprMask = 0;
+ uint fpSimdMask = 0;
+
+ if (flags.HasFlag(InstFlags.MemWBack))
+ {
+ gprMask |= MaskFromIndex(ExtractRn(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.FpSimd))
+ {
+ if (flags.HasFlag(InstFlags.Rd))
+ {
+ uint mask = MaskFromIndex(ExtractRd(flags, encoding));
+
+ if (IsFpToGpr(flags, encoding))
+ {
+ gprMask |= mask;
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (!flags.HasFlag(InstFlags.ReadRt))
+ {
+ if (flags.HasFlag(InstFlags.Rt))
+ {
+ uint mask = MaskFromIndex(ExtractRt(flags, encoding));
+
+ if (flags.HasFlag(InstFlags.RtSeq))
+ {
+ int count = GetRtSequenceCount(name, encoding);
+
+ for (int index = 0; index < count; index++, mask <<= 1)
+ {
+ fpSimdMask |= mask;
+ }
+ }
+ else
+ {
+ fpSimdMask |= mask;
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Rt2))
+ {
+ fpSimdMask |= MaskFromIndex(ExtractRt2(flags, encoding));
+ }
+ }
+ }
+ else
+ {
+ if (flags.HasFlag(InstFlags.Rd))
+ {
+ gprMask |= MaskFromIndex(ExtractRd(flags, encoding));
+ }
+
+ if (!flags.HasFlag(InstFlags.ReadRt))
+ {
+ if (flags.HasFlag(InstFlags.Rt))
+ {
+ gprMask |= MaskFromIndex(ExtractRt(flags, encoding));
+ }
+
+ if (flags.HasFlag(InstFlags.Rt2))
+ {
+ gprMask |= MaskFromIndex(ExtractRt2(flags, encoding));
+ }
+ }
+
+ if (flags.HasFlag(InstFlags.Rs))
+ {
+ gprMask |= MaskFromIndex(ExtractRs(flags, encoding));
+ }
+ }
+
+ return (gprMask, fpSimdMask);
+ }
+
+ private static uint MaskFromIndex(int index)
+ {
+ if (index < SpecialZrIndex)
+ {
+ return 1u << index;
+ }
+
+ return 0u;
+ }
+
+ private static bool IsFpFromGpr(InstFlags flags, uint encoding)
+ {
+ InstFlags bothFlags = InstFlags.FpSimdFromGpr | InstFlags.FpSimdToGpr;
+
+ if ((flags & bothFlags) == bothFlags) // FMOV (general)
+ {
+ return (encoding & (1u << 16)) != 0;
+ }
+
+ return flags.HasFlag(InstFlags.FpSimdFromGpr);
+ }
+
+ private static bool IsFpToGpr(InstFlags flags, uint encoding)
+ {
+ InstFlags bothFlags = InstFlags.FpSimdFromGpr | InstFlags.FpSimdToGpr;
+
+ if ((flags & bothFlags) == bothFlags) // FMOV (general)
+ {
+ return (encoding & (1u << 16)) == 0;
+ }
+
+ return flags.HasFlag(InstFlags.FpSimdToGpr);
+ }
+
+ private static int GetRtSequenceCount(InstName name, uint encoding)
+ {
+ switch (name)
+ {
+ case InstName.Ld1AdvsimdMultAsNoPostIndex:
+ case InstName.Ld1AdvsimdMultAsPostIndex:
+ case InstName.St1AdvsimdMultAsNoPostIndex:
+ case InstName.St1AdvsimdMultAsPostIndex:
+ return ((encoding >> 12) & 0xf) switch
+ {
+ 0b0000 => 4,
+ 0b0010 => 4,
+ 0b0100 => 3,
+ 0b0110 => 3,
+ 0b0111 => 1,
+ 0b1000 => 2,
+ 0b1010 => 2,
+ _ => 1,
+ };
+ case InstName.Ld1rAdvsimdAsNoPostIndex:
+ case InstName.Ld1rAdvsimdAsPostIndex:
+ case InstName.Ld1AdvsimdSnglAsNoPostIndex:
+ case InstName.Ld1AdvsimdSnglAsPostIndex:
+ case InstName.St1AdvsimdSnglAsNoPostIndex:
+ case InstName.St1AdvsimdSnglAsPostIndex:
+ return 1;
+ case InstName.Ld2rAdvsimdAsNoPostIndex:
+ case InstName.Ld2rAdvsimdAsPostIndex:
+ case InstName.Ld2AdvsimdMultAsNoPostIndex:
+ case InstName.Ld2AdvsimdMultAsPostIndex:
+ case InstName.Ld2AdvsimdSnglAsNoPostIndex:
+ case InstName.Ld2AdvsimdSnglAsPostIndex:
+ case InstName.St2AdvsimdMultAsNoPostIndex:
+ case InstName.St2AdvsimdMultAsPostIndex:
+ case InstName.St2AdvsimdSnglAsNoPostIndex:
+ case InstName.St2AdvsimdSnglAsPostIndex:
+ return 2;
+ case InstName.Ld3rAdvsimdAsNoPostIndex:
+ case InstName.Ld3rAdvsimdAsPostIndex:
+ case InstName.Ld3AdvsimdMultAsNoPostIndex:
+ case InstName.Ld3AdvsimdMultAsPostIndex:
+ case InstName.Ld3AdvsimdSnglAsNoPostIndex:
+ case InstName.Ld3AdvsimdSnglAsPostIndex:
+ case InstName.St3AdvsimdMultAsNoPostIndex:
+ case InstName.St3AdvsimdMultAsPostIndex:
+ case InstName.St3AdvsimdSnglAsNoPostIndex:
+ case InstName.St3AdvsimdSnglAsPostIndex:
+ return 3;
+ case InstName.Ld4rAdvsimdAsNoPostIndex:
+ case InstName.Ld4rAdvsimdAsPostIndex:
+ case InstName.Ld4AdvsimdMultAsNoPostIndex:
+ case InstName.Ld4AdvsimdMultAsPostIndex:
+ case InstName.Ld4AdvsimdSnglAsNoPostIndex:
+ case InstName.Ld4AdvsimdSnglAsPostIndex:
+ case InstName.St4AdvsimdMultAsNoPostIndex:
+ case InstName.St4AdvsimdMultAsPostIndex:
+ case InstName.St4AdvsimdSnglAsNoPostIndex:
+ case InstName.St4AdvsimdSnglAsPostIndex:
+ return 4;
+ }
+
+ return 1;
+ }
+
+ private static int GetRnSequenceCount(uint encoding)
+ {
+ return ((int)(encoding >> 13) & 3) + 1;
+ }
+
+ public static int ExtractRd(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rd));
+ int index = (int)(encoding >> RdRtBit) & 0x1f;
+
+ if (!flags.HasFlag(InstFlags.RdSP) && index == ZrIndex)
+ {
+ return SpecialZrIndex;
+ }
+
+ return index;
+ }
+
+ public static int ExtractRn(uint encoding)
+ {
+ return (int)(encoding >> RnBit) & 0x1f;
+ }
+
+ public static int ExtractRn(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rn));
+ int index = ExtractRn(encoding);
+
+ if (!flags.HasFlag(InstFlags.RnSP) && index == ZrIndex)
+ {
+ return SpecialZrIndex;
+ }
+
+ return index;
+ }
+
+ public static int ExtractRm(uint encoding)
+ {
+ return (int)(encoding >> RmRsBit) & 0x1f;
+ }
+
+ public static int ExtractRm(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rm));
+ int index = ExtractRm(encoding);
+
+ return index == ZrIndex ? SpecialZrIndex : index;
+ }
+
+ public static int ExtractRs(uint encoding)
+ {
+ return (int)(encoding >> RmRsBit) & 0x1f;
+ }
+
+ public static int ExtractRs(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rs));
+ int index = ExtractRs(encoding);
+
+ return index == ZrIndex ? SpecialZrIndex : index;
+ }
+
+ public static int ExtractRa(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Ra));
+ int index = (int)(encoding >> RaRt2Bit) & 0x1f;
+
+ return index == ZrIndex ? SpecialZrIndex : index;
+ }
+
+ public static int ExtractRt(uint encoding)
+ {
+ return (int)(encoding >> RdRtBit) & 0x1f;
+ }
+
+ public static int ExtractRt(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rt));
+ int index = ExtractRt(encoding);
+
+ return index == ZrIndex ? SpecialZrIndex : index;
+ }
+
+ public static int ExtractRt2(InstFlags flags, uint encoding)
+ {
+ Debug.Assert(flags.HasFlag(InstFlags.Rt2));
+ int index = (int)(encoding >> RaRt2Bit) & 0x1f;
+
+ return index == ZrIndex ? SpecialZrIndex : index;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs
new file mode 100644
index 00000000..7ef3bf49
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs
@@ -0,0 +1,743 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using Ryujinx.Cpu.LightningJit.Graph;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
+{
+ static class Compiler
+ {
+ private const int Encodable26BitsOffsetLimit = 0x2000000;
+
+ private readonly struct Context
+ {
+ public readonly CodeWriter Writer;
+ public readonly RegisterAllocator RegisterAllocator;
+ public readonly TailMerger TailMerger;
+ public readonly AddressTable FuncTable;
+ public readonly IntPtr DispatchStubPointer;
+
+ private readonly MultiBlock _multiBlock;
+ private readonly RegisterSaveRestore _registerSaveRestore;
+ private readonly IntPtr _pageTablePointer;
+
+ public Context(
+ CodeWriter writer,
+ RegisterAllocator registerAllocator,
+ TailMerger tailMerger,
+ RegisterSaveRestore registerSaveRestore,
+ MultiBlock multiBlock,
+ AddressTable funcTable,
+ IntPtr dispatchStubPointer,
+ IntPtr pageTablePointer)
+ {
+ Writer = writer;
+ RegisterAllocator = registerAllocator;
+ TailMerger = tailMerger;
+ _registerSaveRestore = registerSaveRestore;
+ _multiBlock = multiBlock;
+ FuncTable = funcTable;
+ DispatchStubPointer = dispatchStubPointer;
+ _pageTablePointer = pageTablePointer;
+ }
+
+ public readonly int GetLrRegisterIndex()
+ {
+ return RemapGprRegister(RegisterUtils.LrIndex);
+ }
+
+ public readonly int RemapGprRegister(int index)
+ {
+ return RegisterAllocator.RemapReservedGprRegister(index);
+ }
+
+ public readonly int GetReservedStackOffset()
+ {
+ return _registerSaveRestore.GetReservedStackOffset();
+ }
+
+ public readonly void WritePrologue()
+ {
+ Assembler asm = new(Writer);
+
+ _registerSaveRestore.WritePrologue(ref asm);
+
+ // If needed, set up the fixed registers with the pointers we will use.
+ // First one is the context pointer (passed as first argument),
+ // second one is the page table or address space base, it is at a fixed memory location and considered constant.
+
+ if (RegisterAllocator.FixedContextRegister != 0)
+ {
+ asm.Mov(Register(RegisterAllocator.FixedContextRegister), Register(0));
+ }
+
+ if (_multiBlock.HasMemoryInstruction)
+ {
+ asm.Mov(Register(RegisterAllocator.FixedPageTableRegister), (ulong)_pageTablePointer);
+ }
+
+ // This assumes that the block with the index 0 is always the entry block.
+ LoadFromContext(ref asm, _multiBlock.ReadMasks[0]);
+ }
+
+ public readonly void WriteEpilogueWithoutContext()
+ {
+ Assembler asm = new(Writer);
+
+ _registerSaveRestore.WriteEpilogue(ref asm);
+ }
+
+ public void LoadFromContextAfterCall(int blockIndex)
+ {
+ Block block = _multiBlock.Blocks[blockIndex];
+
+ if (block.SuccessorsCount != 0)
+ {
+ Assembler asm = new(Writer);
+
+ RegisterMask readMask = _multiBlock.ReadMasks[block.GetSuccessor(0).Index];
+
+ for (int sIndex = 1; sIndex < block.SuccessorsCount; sIndex++)
+ {
+ IBlock successor = block.GetSuccessor(sIndex);
+
+ readMask |= _multiBlock.ReadMasks[successor.Index];
+ }
+
+ LoadFromContext(ref asm, readMask);
+ }
+ }
+
+ private void LoadFromContext(ref Assembler asm, RegisterMask readMask)
+ {
+ LoadGprFromContext(ref asm, readMask.GprMask, NativeContextOffsets.GprBaseOffset);
+ LoadFpSimdFromContext(ref asm, readMask.FpSimdMask, NativeContextOffsets.FpSimdBaseOffset);
+ LoadPStateFromContext(ref asm, readMask.PStateMask, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ public void StoreToContextBeforeCall(int blockIndex, ulong? newLrValue = null)
+ {
+ Assembler asm = new(Writer);
+
+ StoreToContext(ref asm, _multiBlock.WriteMasks[blockIndex], newLrValue);
+ }
+
+ private void StoreToContext(ref Assembler asm, RegisterMask writeMask, ulong? newLrValue)
+ {
+ StoreGprToContext(ref asm, writeMask.GprMask, NativeContextOffsets.GprBaseOffset, newLrValue);
+ StoreFpSimdToContext(ref asm, writeMask.FpSimdMask, NativeContextOffsets.FpSimdBaseOffset);
+ StorePStateToContext(ref asm, writeMask.PStateMask, NativeContextOffsets.FlagsBaseOffset);
+ }
+
+ private void LoadGprFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 8;
+
+ if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ mask &= ~(3u << reg);
+
+ asm.LdpRiUn(
+ Register(RegisterAllocator.RemapReservedGprRegister(reg)),
+ Register(RegisterAllocator.RemapReservedGprRegister(reg + 1)),
+ contextPtr,
+ offset);
+ }
+ else
+ {
+ mask &= ~(1u << reg);
+
+ asm.LdrRiUn(Register(RegisterAllocator.RemapReservedGprRegister(reg)), contextPtr, offset);
+ }
+ }
+ }
+
+ private void LoadFpSimdFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 16;
+
+ mask &= ~(1u << reg);
+
+ asm.LdrRiUn(Register(reg, OperandType.V128), contextPtr, offset);
+ }
+ }
+
+ private void LoadPStateFromContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ if (mask == 0)
+ {
+ return;
+ }
+
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ int tempRegister = RegisterAllocator.AllocateTempGprRegister();
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.LdrRiUn(rt, contextPtr, baseOffset);
+ asm.MsrNzcv(rt);
+
+ RegisterAllocator.FreeTempGprRegister(tempRegister);
+ }
+
+ private void StoreGprToContext(ref Assembler asm, uint mask, int baseOffset, ulong? newLrValue)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ int tempRegister = -1;
+
+ if (newLrValue.HasValue)
+ {
+ // This is required for BLR X30 instructions, where we need to get the target address
+ // before it is overwritten with the return address that the call would write there.
+
+ tempRegister = RegisterAllocator.AllocateTempGprRegister();
+
+ asm.Mov(Register(tempRegister), newLrValue.Value);
+ }
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 8;
+
+ if (reg < 31 && (mask & (2u << reg)) != 0 && offset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ mask &= ~(3u << reg);
+
+ asm.StpRiUn(
+ Register(RemapReservedGprRegister(reg, tempRegister)),
+ Register(RemapReservedGprRegister(reg + 1, tempRegister)),
+ contextPtr,
+ offset);
+ }
+ else
+ {
+ mask &= ~(1u << reg);
+
+ asm.StrRiUn(Register(RemapReservedGprRegister(reg, tempRegister)), contextPtr, offset);
+ }
+ }
+
+ if (tempRegister >= 0)
+ {
+ RegisterAllocator.FreeTempGprRegister(tempRegister);
+ }
+ }
+
+ private int RemapReservedGprRegister(int index, int tempRegister)
+ {
+ if (tempRegister >= 0 && index == RegisterUtils.LrIndex)
+ {
+ return tempRegister;
+ }
+
+ return RegisterAllocator.RemapReservedGprRegister(index);
+ }
+
+ private void StoreFpSimdToContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ while (mask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(mask);
+ int offset = baseOffset + reg * 16;
+
+ mask &= ~(1u << reg);
+
+ asm.StrRiUn(Register(reg, OperandType.V128), contextPtr, offset);
+ }
+ }
+
+ private void StorePStateToContext(ref Assembler asm, uint mask, int baseOffset)
+ {
+ if (mask == 0)
+ {
+ return;
+ }
+
+ Operand contextPtr = Register(RegisterAllocator.FixedContextRegister);
+
+ int tempRegister = RegisterAllocator.AllocateTempGprRegister();
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.MrsNzcv(rt);
+ asm.StrRiUn(rt, contextPtr, baseOffset);
+
+ RegisterAllocator.FreeTempGprRegister(tempRegister);
+ }
+ }
+
+ private readonly struct PendingBranch
+ {
+ public readonly int BlockIndex;
+ public readonly ulong Pc;
+ public readonly InstName Name;
+ public readonly uint Encoding;
+ public readonly int WriterPointer;
+
+ public PendingBranch(int blockIndex, ulong pc, InstName name, uint encoding, int writerPointer)
+ {
+ BlockIndex = blockIndex;
+ Pc = pc;
+ Name = name;
+ Encoding = encoding;
+ WriterPointer = writerPointer;
+ }
+ }
+
+ public static CompiledFunction Compile(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, AddressTable funcTable, IntPtr dispatchStubPtr)
+ {
+ MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address);
+
+ Dictionary targets = new();
+ List pendingBranches = new();
+
+ uint gprUseMask = multiBlock.GlobalUseMask.GprMask;
+ uint fpSimdUseMask = multiBlock.GlobalUseMask.FpSimdMask;
+ uint pStateUseMask = multiBlock.GlobalUseMask.PStateMask;
+
+ CodeWriter writer = new();
+ RegisterAllocator regAlloc = new(gprUseMask, fpSimdUseMask, pStateUseMask, multiBlock.HasHostCall);
+ RegisterSaveRestore rsr = new(
+ regAlloc.AllGprMask & AbiConstants.GprCalleeSavedRegsMask,
+ regAlloc.AllFpSimdMask & AbiConstants.FpSimdCalleeSavedRegsMask,
+ OperandType.FP64,
+ multiBlock.HasHostCall,
+ multiBlock.HasHostCall ? CalculateStackSizeForCallSpill(regAlloc.AllGprMask, regAlloc.AllFpSimdMask, regAlloc.AllPStateMask) : 0);
+
+ TailMerger tailMerger = new();
+
+ Context context = new(writer, regAlloc, tailMerger, rsr, multiBlock, funcTable, dispatchStubPtr, memoryManager.PageTablePointer);
+
+ context.WritePrologue();
+
+ ulong pc = address;
+
+ for (int blockIndex = 0; blockIndex < multiBlock.Blocks.Count; blockIndex++)
+ {
+ Block block = multiBlock.Blocks[blockIndex];
+
+ Debug.Assert(block.Address == pc);
+
+ targets.Add(pc, writer.InstructionPointer);
+
+ int instCount = block.EndsWithBranch ? block.Instructions.Count - 1 : block.Instructions.Count;
+
+ for (int index = 0; index < instCount; index++)
+ {
+ InstInfo instInfo = block.Instructions[index];
+
+ uint encoding = RegisterUtils.RemapRegisters(regAlloc, instInfo.Flags, instInfo.Encoding);
+
+ if (instInfo.AddressForm != AddressForm.None)
+ {
+ InstEmitMemory.RewriteInstruction(
+ memoryManager.AddressSpaceBits,
+ memoryManager.Type,
+ writer,
+ regAlloc,
+ instInfo.Name,
+ instInfo.Flags,
+ instInfo.AddressForm,
+ pc,
+ encoding);
+ }
+ else if (instInfo.Name == InstName.Sys)
+ {
+ InstEmitMemory.RewriteSysInstruction(memoryManager.AddressSpaceBits, memoryManager.Type, writer, regAlloc, encoding);
+ }
+ else if (instInfo.Name.IsSystem())
+ {
+ bool needsContextStoreLoad = InstEmitSystem.NeedsContextStoreLoad(instInfo.Name);
+
+ if (needsContextStoreLoad)
+ {
+ context.StoreToContextBeforeCall(blockIndex);
+ }
+
+ InstEmitSystem.RewriteInstruction(writer, regAlloc, tailMerger, instInfo.Name, pc, encoding, rsr.GetReservedStackOffset());
+
+ if (needsContextStoreLoad)
+ {
+ context.LoadFromContextAfterCall(blockIndex);
+ }
+ }
+ else
+ {
+ writer.WriteInstruction(encoding);
+ }
+
+ pc += 4UL;
+ }
+
+ if (block.IsLoopEnd)
+ {
+ // If this is a loop, the code might run for a long time uninterrupted.
+ // We insert a "sync point" here to ensure the loop can be interrupted if needed.
+
+ InstEmitSystem.WriteSyncPoint(writer, context.RegisterAllocator, tailMerger, context.GetReservedStackOffset());
+ }
+
+ if (blockIndex < multiBlock.Blocks.Count - 1)
+ {
+ InstInfo lastInstructionInfo = block.Instructions[^1];
+ InstName lastInstructionName = lastInstructionInfo.Name;
+ InstFlags lastInstructionFlags = lastInstructionInfo.Flags;
+ uint lastInstructionEncoding = lastInstructionInfo.Encoding;
+
+ lastInstructionEncoding = RegisterUtils.RemapRegisters(regAlloc, lastInstructionFlags, lastInstructionEncoding);
+
+ if (lastInstructionName.IsCall())
+ {
+ context.StoreToContextBeforeCall(blockIndex, pc + 4UL);
+
+ InstEmitSystem.RewriteCallInstruction(
+ writer,
+ regAlloc,
+ tailMerger,
+ context.WriteEpilogueWithoutContext,
+ funcTable,
+ dispatchStubPtr,
+ lastInstructionName,
+ pc,
+ lastInstructionEncoding,
+ context.GetReservedStackOffset());
+
+ context.LoadFromContextAfterCall(blockIndex);
+
+ pc += 4UL;
+ }
+ else if (lastInstructionName == InstName.Ret)
+ {
+ RewriteBranchInstruction(context, blockIndex, lastInstructionName, pc, lastInstructionEncoding);
+
+ pc += 4UL;
+ }
+ else if (block.EndsWithBranch)
+ {
+ pendingBranches.Add(new(blockIndex, pc, lastInstructionName, lastInstructionEncoding, writer.InstructionPointer));
+ writer.WriteInstruction(0u); // Placeholder.
+
+ pc += 4UL;
+ }
+ }
+ }
+
+ int lastBlockIndex = multiBlock.Blocks[^1].Index;
+
+ if (multiBlock.IsTruncated)
+ {
+ Assembler asm = new(writer);
+
+ WriteTailCallConstant(context, ref asm, lastBlockIndex, pc);
+ }
+ else
+ {
+ InstInfo lastInstructionInfo = multiBlock.Blocks[^1].Instructions[^1];
+ InstName lastInstructionName = lastInstructionInfo.Name;
+ InstFlags lastInstructionFlags = lastInstructionInfo.Flags;
+ uint lastInstructionEncoding = lastInstructionInfo.Encoding;
+
+ lastInstructionEncoding = RegisterUtils.RemapRegisters(regAlloc, lastInstructionFlags, lastInstructionEncoding);
+
+ RewriteBranchInstruction(context, lastBlockIndex, lastInstructionName, pc, lastInstructionEncoding);
+
+ pc += 4;
+ }
+
+ foreach (PendingBranch pendingBranch in pendingBranches)
+ {
+ RewriteBranchInstructionWithTarget(
+ context,
+ pendingBranch.BlockIndex,
+ pendingBranch.Name,
+ pendingBranch.Pc,
+ pendingBranch.Encoding,
+ pendingBranch.WriterPointer,
+ targets);
+ }
+
+ tailMerger.WriteReturn(writer, context.WriteEpilogueWithoutContext);
+
+ return new(writer.AsByteSpan(), (int)(pc - address));
+ }
+
+ private static int CalculateStackSizeForCallSpill(uint gprUseMask, uint fpSimdUseMask, uint pStateUseMask)
+ {
+ // Note that we don't discard callee saved FP/SIMD register because only the lower 64 bits is callee saved,
+ // so if the function is using the full register, that won't be enough.
+ // We could do better, but it's likely not worth it since this case happens very rarely in practice.
+
+ return BitOperations.PopCount(gprUseMask & ~AbiConstants.GprCalleeSavedRegsMask) * 8 +
+ BitOperations.PopCount(fpSimdUseMask) * 16 +
+ (pStateUseMask != 0 ? 8 : 0);
+ }
+
+ private static void RewriteBranchInstruction(in Context context, int blockIndex, InstName name, ulong pc, uint encoding)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ int originalOffset;
+ ulong nextAddress = pc + 4UL;
+ ulong targetAddress;
+
+ switch (name)
+ {
+ case InstName.BUncond:
+ originalOffset = ImmUtils.ExtractSImm26Times4(encoding);
+ targetAddress = pc + (ulong)originalOffset;
+
+ WriteTailCallConstant(context, ref asm, blockIndex, targetAddress);
+ break;
+
+ case InstName.Bl:
+ case InstName.Blr:
+ case InstName.Br:
+ if (name == InstName.Bl)
+ {
+ asm.Mov(Register(context.GetLrRegisterIndex()), nextAddress);
+
+ int imm = ImmUtils.ExtractSImm26Times4(encoding);
+
+ WriteTailCallConstant(context, ref asm, blockIndex, pc + (ulong)imm);
+ }
+ else
+ {
+ bool isCall = name == InstName.Blr;
+ if (isCall)
+ {
+ context.StoreToContextBeforeCall(blockIndex, nextAddress);
+ }
+ else
+ {
+ context.StoreToContextBeforeCall(blockIndex);
+ }
+
+ InstEmitSystem.RewriteCallInstruction(
+ context.Writer,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ name,
+ pc,
+ encoding,
+ context.GetReservedStackOffset(),
+ isTail: true);
+ }
+ break;
+
+ case InstName.Ret:
+ int rnIndex = RegisterUtils.ExtractRn(encoding);
+ if (rnIndex == RegisterUtils.ZrIndex)
+ {
+ WriteTailCallConstant(context, ref asm, blockIndex, 0UL);
+ }
+ else
+ {
+ rnIndex = context.RemapGprRegister(rnIndex);
+ context.StoreToContextBeforeCall(blockIndex);
+
+ if (rnIndex != 0)
+ {
+ asm.Mov(Register(0), Register(rnIndex));
+ }
+
+ context.TailMerger.AddUnconditionalReturn(writer, asm);
+ }
+ break;
+
+ case InstName.BCond:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ uint branchMask;
+
+ if (name == InstName.Tbnz || name == InstName.Tbz)
+ {
+ originalOffset = ImmUtils.ExtractSImm14Times4(encoding);
+ branchMask = 0x3fff;
+ }
+ else
+ {
+ originalOffset = ImmUtils.ExtractSImm19Times4(encoding);
+ branchMask = 0x7ffff;
+ }
+
+ targetAddress = pc + (ulong)originalOffset;
+
+ int branchIndex = writer.InstructionPointer;
+
+ writer.WriteInstruction(0u); // Reserved for branch.
+ WriteTailCallConstant(context, ref asm, blockIndex, nextAddress);
+
+ int targetIndex = writer.InstructionPointer;
+
+ writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)(((targetIndex - branchIndex) & branchMask) << 5));
+ WriteTailCallConstant(context, ref asm, blockIndex, targetAddress);
+ break;
+
+ default:
+ Debug.Fail($"Unknown branch instruction \"{name}\".");
+ break;
+ }
+ }
+
+ private static void RewriteBranchInstructionWithTarget(
+ in Context context,
+ int blockIndex,
+ InstName name,
+ ulong pc,
+ uint encoding,
+ int branchIndex,
+ Dictionary targets)
+ {
+ CodeWriter writer = context.Writer;
+ Assembler asm = new(writer);
+
+ int delta;
+ int targetIndex;
+ int originalOffset;
+ ulong targetAddress;
+
+ switch (name)
+ {
+ case InstName.BUncond:
+ originalOffset = ImmUtils.ExtractSImm26Times4(encoding);
+ targetAddress = pc + (ulong)originalOffset;
+
+ if (targets.TryGetValue(targetAddress, out targetIndex))
+ {
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -Encodable26BitsOffsetLimit && delta < Encodable26BitsOffsetLimit)
+ {
+ writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff));
+ break;
+ }
+ }
+
+ targetIndex = writer.InstructionPointer;
+ delta = targetIndex - branchIndex;
+
+ writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff));
+ WriteTailCallConstant(context, ref asm, blockIndex, targetAddress);
+ break;
+
+ case InstName.BCond:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ uint branchMask;
+
+ if (name == InstName.Tbnz || name == InstName.Tbz)
+ {
+ originalOffset = ImmUtils.ExtractSImm14Times4(encoding);
+ branchMask = 0x3fff;
+ }
+ else
+ {
+ originalOffset = ImmUtils.ExtractSImm19Times4(encoding);
+ branchMask = 0x7ffff;
+ }
+
+ int branchMax = (int)(branchMask + 1) / 2;
+
+ targetAddress = pc + (ulong)originalOffset;
+
+ if (targets.TryGetValue(targetAddress, out targetIndex))
+ {
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -branchMax && delta < branchMax)
+ {
+ writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5));
+ break;
+ }
+ }
+
+ targetIndex = writer.InstructionPointer;
+ delta = targetIndex - branchIndex;
+
+ if (delta >= -branchMax && delta < branchMax)
+ {
+ writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5));
+ WriteTailCallConstant(context, ref asm, blockIndex, targetAddress);
+ }
+ else
+ {
+ // If the branch target is too far away, we use a regular unconditional branch
+ // instruction instead which has a much higher range.
+ // We branch directly to the end of the function, where we put the conditional branch,
+ // and then branch back to the next instruction or return the branch target depending
+ // on the branch being taken or not.
+
+ uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff);
+ Debug.Assert(ImmUtils.ExtractSImm26Times4(branchInst) == delta * 4);
+
+ writer.WriteInstructionAt(branchIndex, branchInst);
+
+ int movedBranchIndex = writer.InstructionPointer;
+
+ writer.WriteInstruction(0u); // Placeholder
+ asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+
+ delta = writer.InstructionPointer - movedBranchIndex;
+
+ writer.WriteInstructionAt(movedBranchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5));
+ WriteTailCallConstant(context, ref asm, blockIndex, targetAddress);
+ }
+ break;
+
+ default:
+ Debug.Fail($"Unknown branch instruction \"{name}\".");
+ break;
+ }
+ }
+
+ private static void WriteTailCallConstant(in Context context, ref Assembler asm, int blockIndex, ulong address)
+ {
+ context.StoreToContextBeforeCall(blockIndex);
+ InstEmitSystem.WriteCallWithGuestAddress(
+ context.Writer,
+ ref asm,
+ context.RegisterAllocator,
+ context.TailMerger,
+ context.WriteEpilogueWithoutContext,
+ context.FuncTable,
+ context.DispatchStubPointer,
+ context.GetReservedStackOffset(),
+ 0UL,
+ new Operand(OperandKind.Constant, OperandType.I64, address),
+ isTail: true);
+ }
+
+ private static Operand Register(int register, OperandType type = OperandType.I64)
+ {
+ return new Operand(register, RegisterType.Integer, type);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs
new file mode 100644
index 00000000..738b8a32
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs
@@ -0,0 +1,384 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.Graph;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
+{
+ static class Decoder
+ {
+ private const int MaxInstructionsPerBlock = 1000;
+
+ private const uint NzcvFlags = 0xfu << 28;
+ private const uint CFlag = 0x1u << 29;
+
+ public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address)
+ {
+ List blocks = new();
+ List branchTargets = new();
+
+ RegisterMask useMask = RegisterMask.Zero;
+
+ bool hasHostCall = false;
+ bool hasMemoryInstruction = false;
+
+ while (true)
+ {
+ Block block = Decode(cpuPreset, memoryManager, address, ref useMask, ref hasHostCall, ref hasMemoryInstruction);
+
+ if (!block.IsTruncated && TryGetBranchTarget(block, out ulong targetAddress))
+ {
+ branchTargets.Add(targetAddress);
+ }
+
+ blocks.Add(block);
+
+ if (block.IsTruncated || !HasNextBlock(block, block.EndAddress - 4UL, branchTargets))
+ {
+ break;
+ }
+
+ address = block.EndAddress;
+ }
+
+ branchTargets.Sort();
+ SplitBlocks(blocks, branchTargets);
+ NumberAndLinkBlocks(blocks);
+
+ return new(blocks, useMask, hasHostCall, hasMemoryInstruction);
+ }
+
+ private static bool TryGetBranchTarget(Block block, out ulong targetAddress)
+ {
+ return TryGetBranchTarget(block.Instructions[^1].Name, block.EndAddress - 4UL, block.Instructions[^1].Encoding, out targetAddress);
+ }
+
+ private static bool TryGetBranchTarget(InstName name, ulong pc, uint encoding, out ulong targetAddress)
+ {
+ int originalOffset;
+
+ switch (name)
+ {
+ case InstName.BUncond:
+ originalOffset = ImmUtils.ExtractSImm26Times4(encoding);
+ targetAddress = pc + (ulong)originalOffset;
+
+ return true;
+
+ case InstName.BCond:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ if (name == InstName.Tbnz || name == InstName.Tbz)
+ {
+ originalOffset = ImmUtils.ExtractSImm14Times4(encoding);
+ }
+ else
+ {
+ originalOffset = ImmUtils.ExtractSImm19Times4(encoding);
+ }
+
+ targetAddress = pc + (ulong)originalOffset;
+
+ return true;
+ }
+
+ targetAddress = 0;
+
+ return false;
+ }
+
+ private static void SplitBlocks(List blocks, List branchTargets)
+ {
+ int btIndex = 0;
+
+ while (btIndex < branchTargets.Count)
+ {
+ for (int blockIndex = 0; blockIndex < blocks.Count && btIndex < branchTargets.Count; blockIndex++)
+ {
+ Block block = blocks[blockIndex];
+ ulong currentBranchTarget = branchTargets[btIndex];
+
+ while (currentBranchTarget >= block.Address && currentBranchTarget < block.EndAddress)
+ {
+ if (block.Address != currentBranchTarget)
+ {
+ (Block leftBlock, Block rightBlock) = block.SplitAtAddress(currentBranchTarget);
+
+ blocks.Insert(blockIndex, leftBlock);
+ blocks[blockIndex + 1] = rightBlock;
+
+ block = leftBlock;
+ }
+
+ btIndex++;
+
+ while (btIndex < branchTargets.Count && branchTargets[btIndex] == currentBranchTarget)
+ {
+ btIndex++;
+ }
+
+ if (btIndex >= branchTargets.Count)
+ {
+ break;
+ }
+
+ currentBranchTarget = branchTargets[btIndex];
+ }
+ }
+
+ Debug.Assert(btIndex < int.MaxValue);
+ btIndex++;
+ }
+ }
+
+ private static void NumberAndLinkBlocks(List blocks)
+ {
+ Dictionary blocksByAddress = new();
+
+ for (int blockIndex = 0; blockIndex < blocks.Count; blockIndex++)
+ {
+ Block block = blocks[blockIndex];
+
+ blocksByAddress.Add(block.Address, block);
+ }
+
+ for (int blockIndex = 0; blockIndex < blocks.Count; blockIndex++)
+ {
+ Block block = blocks[blockIndex];
+
+ block.Number(blockIndex);
+
+ if (!block.IsTruncated)
+ {
+ bool hasNext = !block.EndsWithBranch;
+ bool hasBranch = false;
+
+ switch (block.Instructions[^1].Name)
+ {
+ case InstName.BUncond:
+ hasBranch = true;
+ break;
+
+ case InstName.BCond:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ hasNext = true;
+ hasBranch = true;
+ break;
+
+ case InstName.Bl:
+ case InstName.Blr:
+ hasNext = true;
+ break;
+
+ case InstName.Ret:
+ hasNext = false;
+ hasBranch = false;
+ break;
+ }
+
+ if (hasNext && blocksByAddress.TryGetValue(block.EndAddress, out Block nextBlock))
+ {
+ block.AddSuccessor(nextBlock);
+ nextBlock.AddPredecessor(block);
+ }
+
+ if (hasBranch &&
+ TryGetBranchTarget(block, out ulong targetAddress) &&
+ blocksByAddress.TryGetValue(targetAddress, out Block branchBlock))
+ {
+ block.AddSuccessor(branchBlock);
+ branchBlock.AddPredecessor(block);
+ }
+ }
+ }
+ }
+
+ private static bool HasNextBlock(in Block block, ulong pc, List branchTargets)
+ {
+ switch (block.Instructions[^1].Name)
+ {
+ case InstName.BUncond:
+ return branchTargets.Contains(pc + 4UL) ||
+ (TryGetBranchTarget(block, out ulong targetAddress) && targetAddress >= pc && targetAddress < pc + 0x1000);
+
+ case InstName.BCond:
+ case InstName.Bl:
+ case InstName.Blr:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ return true;
+
+ case InstName.Br:
+ return false;
+
+ case InstName.Ret:
+ return branchTargets.Contains(pc + 4UL);
+ }
+
+ return !block.EndsWithBranch;
+ }
+
+ private static Block Decode(
+ CpuPreset cpuPreset,
+ IMemoryManager memoryManager,
+ ulong address,
+ ref RegisterMask useMask,
+ ref bool hasHostCall,
+ ref bool hasMemoryInstruction)
+ {
+ ulong startAddress = address;
+
+ List insts = new();
+
+ uint gprUseMask = useMask.GprMask;
+ uint fpSimdUseMask = useMask.FpSimdMask;
+ uint pStateUseMask = useMask.PStateMask;
+
+ uint encoding;
+ InstName name;
+ InstFlags flags;
+ bool isControlFlow;
+ bool isTruncated = false;
+
+ do
+ {
+ encoding = memoryManager.Read(address);
+ address += 4UL;
+
+ (name, flags, AddressForm addressForm) = InstTable.GetInstNameAndFlags(encoding, cpuPreset.Version, cpuPreset.Features);
+
+ if (name.IsPrivileged())
+ {
+ name = InstName.UdfPermUndef;
+ flags = InstFlags.None;
+ addressForm = AddressForm.None;
+ }
+
+ (uint instGprReadMask, uint instFpSimdReadMask) = RegisterUtils.PopulateReadMasks(name, flags, encoding);
+ (uint instGprWriteMask, uint instFpSimdWriteMask) = RegisterUtils.PopulateWriteMasks(name, flags, encoding);
+
+ if (name.IsCall())
+ {
+ instGprWriteMask |= 1u << RegisterUtils.LrIndex;
+ }
+
+ uint tempGprUseMask = gprUseMask | instGprReadMask | instGprWriteMask;
+
+ if (CalculateAvailableTemps(tempGprUseMask) < CalculateRequiredGprTemps(tempGprUseMask) || insts.Count >= MaxInstructionsPerBlock)
+ {
+ isTruncated = true;
+ address -= 4UL;
+
+ break;
+ }
+
+ gprUseMask = tempGprUseMask;
+
+ uint instPStateReadMask = 0;
+ uint instPStateWriteMask = 0;
+
+ if (flags.HasFlag(InstFlags.Nzcv) || IsMrsNzcv(encoding))
+ {
+ instPStateReadMask = NzcvFlags;
+ }
+ else if (flags.HasFlag(InstFlags.C))
+ {
+ instPStateReadMask = CFlag;
+ }
+
+ if (flags.HasFlag(InstFlags.S) || IsMsrNzcv(encoding))
+ {
+ instPStateWriteMask = NzcvFlags;
+ }
+
+ if (flags.HasFlag(InstFlags.Memory) || name == InstName.Sys)
+ {
+ hasMemoryInstruction = true;
+ }
+
+ fpSimdUseMask |= instFpSimdReadMask | instFpSimdWriteMask;
+ pStateUseMask |= instPStateReadMask | instPStateWriteMask;
+
+ if (name.IsSystemOrCall() && !hasHostCall)
+ {
+ hasHostCall = name.IsCall() || InstEmitSystem.NeedsCall(encoding);
+ }
+
+ isControlFlow = name.IsControlFlowOrException();
+
+ RegisterUse registerUse = new(
+ instGprReadMask,
+ instGprWriteMask,
+ instFpSimdReadMask,
+ instFpSimdWriteMask,
+ instPStateReadMask,
+ instPStateWriteMask);
+
+ insts.Add(new(encoding, name, flags, addressForm, registerUse));
+ }
+ while (!isControlFlow);
+
+ bool isLoopEnd = false;
+
+ if (!isTruncated && IsBackwardsBranch(name, encoding))
+ {
+ hasHostCall = true;
+ isLoopEnd = true;
+ }
+
+ useMask = new(gprUseMask, fpSimdUseMask, pStateUseMask);
+
+ return new(startAddress, address, insts, !isTruncated && !name.IsException(), isTruncated, isLoopEnd);
+ }
+
+ private static bool IsMrsNzcv(uint encoding)
+ {
+ return (encoding & ~0x1fu) == 0xd53b4200u;
+ }
+
+ private static bool IsMsrNzcv(uint encoding)
+ {
+ return (encoding & ~0x1fu) == 0xd51b4200u;
+ }
+
+ private static bool IsBackwardsBranch(InstName name, uint encoding)
+ {
+ switch (name)
+ {
+ case InstName.BUncond:
+ return ImmUtils.ExtractSImm26Times4(encoding) < 0;
+
+ case InstName.BCond:
+ case InstName.Cbnz:
+ case InstName.Cbz:
+ case InstName.Tbnz:
+ case InstName.Tbz:
+ int imm = name == InstName.Tbnz || name == InstName.Tbz
+ ? ImmUtils.ExtractSImm14Times4(encoding)
+ : ImmUtils.ExtractSImm19Times4(encoding);
+
+ return imm < 0;
+ }
+
+ return false;
+ }
+
+ private static int CalculateRequiredGprTemps(uint gprUseMask)
+ {
+ return BitOperations.PopCount(gprUseMask & RegisterUtils.ReservedRegsMask) + RegisterAllocator.MaxTempsInclFixed;
+ }
+
+ private static int CalculateAvailableTemps(uint gprUseMask)
+ {
+ return BitOperations.PopCount(~(gprUseMask | RegisterUtils.ReservedRegsMask));
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
new file mode 100644
index 00000000..ece1520f
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
@@ -0,0 +1,593 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
+{
+ static class InstEmitMemory
+ {
+ private const uint XMask = 0x3f808000u;
+ private const uint XValue = 0x8000000u;
+
+ public static void RewriteSysInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
+ {
+ int rtIndex = RegisterUtils.ExtractRt(encoding);
+ if (rtIndex == RegisterUtils.ZrIndex)
+ {
+ writer.WriteInstruction(encoding);
+
+ return;
+ }
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rt = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(rtIndex, RegisterType.Integer, OperandType.I64);
+
+ Assembler asm = new(writer);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rt, guestAddress);
+
+ encoding = RegisterUtils.ReplaceRt(encoding, tempRegister);
+
+ writer.WriteInstruction(encoding);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ public static void RewriteInstruction(
+ int asBits,
+ MemoryManagerType mmType,
+ CodeWriter writer,
+ RegisterAllocator regAlloc,
+ InstName name,
+ InstFlags flags,
+ AddressForm addressForm,
+ ulong pc,
+ uint encoding)
+ {
+ switch (addressForm)
+ {
+ case AddressForm.OffsetReg:
+ RewriteOffsetRegMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding);
+ break;
+ case AddressForm.PostIndexed:
+ RewritePostIndexedMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding);
+ break;
+ case AddressForm.PreIndexed:
+ RewritePreIndexedMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding);
+ break;
+ case AddressForm.SignedScaled:
+ RewriteSignedScaledMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding);
+ break;
+ case AddressForm.UnsignedScaled:
+ RewriteUnsignedScaledMemoryInstruction(asBits, mmType, writer, regAlloc, flags, encoding);
+ break;
+ case AddressForm.BaseRegister:
+ // Some applications uses unordered memory instructions in places where
+ // it does need proper ordering, and only work on some CPUs.
+ // To work around this, make all exclusive access operations ordered.
+
+ if ((encoding & XMask) == XValue)
+ {
+ // Set ordered flag.
+ encoding |= 1u << 15;
+ }
+
+ RewriteBaseRegisterMemoryInstruction(asBits, mmType, writer, regAlloc, encoding);
+ break;
+ case AddressForm.StructNoOffset:
+ RewriteBaseRegisterMemoryInstruction(asBits, mmType, writer, regAlloc, encoding);
+ break;
+ case AddressForm.BasePlusOffset:
+ RewriteBasePlusOffsetMemoryInstruction(asBits, mmType, writer, regAlloc, encoding);
+ break;
+ case AddressForm.Literal:
+ RewriteLiteralMemoryInstruction(asBits, mmType, writer, regAlloc, name, pc, encoding);
+ break;
+ case AddressForm.StructPostIndexedReg:
+ RewriteStructPostIndexedRegMemoryInstruction(asBits, mmType, writer, regAlloc, encoding);
+ break;
+ default:
+ writer.WriteInstruction(encoding);
+ break;
+ }
+ }
+
+ private static void RewriteOffsetRegMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ // TODO: Some unallocated encoding cases.
+
+ ArmExtensionType extensionType = (ArmExtensionType)((encoding >> 13) & 7);
+
+ uint size = encoding >> 30;
+
+ if (flags.HasFlag(InstFlags.FpSimd))
+ {
+ size |= (encoding >> 21) & 4u;
+ }
+
+ int shift = (encoding & (1u << 12)) != 0 ? (int)size : 0;
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64);
+ Operand guestOffset = new(RegisterUtils.ExtractRm(encoding), RegisterType.Integer, OperandType.I64);
+
+ Assembler asm = new(writer);
+
+ asm.Add(rn, guestAddress, guestOffset, extensionType, shift);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, rn);
+
+ encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
+ encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); // Register -> Unsigned offset
+
+ writer.WriteInstruction(encoding);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void RewritePostIndexedMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ bool isPair = flags.HasFlag(InstFlags.Rt2);
+ int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding);
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64);
+
+ Assembler asm = new(writer);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress);
+
+ encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
+
+ if (isPair)
+ {
+ // Post-index -> Signed offset
+ encoding &= ~(0x7fu << 15);
+ encoding ^= 3u << 23;
+ }
+ else
+ {
+ // Post-index -> Unsigned offset
+ encoding = (encoding & ~(0xfffu << 10)) | (1u << 24);
+ }
+
+ writer.WriteInstruction(encoding);
+
+ WriteAddConstant(ref asm, guestAddress, guestAddress, imm);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void RewritePreIndexedMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ bool isPair = flags.HasFlag(InstFlags.Rt2);
+ int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding);
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64);
+
+ Assembler asm = new(writer);
+
+ WriteAddConstant(ref asm, guestAddress, guestAddress, imm);
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress);
+
+ encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
+
+ if (isPair)
+ {
+ // Pre-index -> Signed offset
+ encoding &= ~(0x7fu << 15);
+ encoding &= ~(1u << 23);
+ }
+ else
+ {
+ // Pre-index -> Unsigned offset
+ encoding = (encoding & ~(0xfffu << 10)) | (1u << 24);
+ }
+
+ writer.WriteInstruction(encoding);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void RewriteSignedScaledMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractSImm7Scaled(flags, encoding), 0x7fu << 15);
+ }
+
+ private static void RewriteUnsignedScaledMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
+ {
+ RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractUImm12Scaled(flags, encoding), 0xfffu << 10);
+ }
+
+ private static void RewriteBaseRegisterMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
+ {
+ RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, 0, 0u);
+ }
+
+ private static void RewriteBasePlusOffsetMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
+ {
+ RewriteMemoryInstruction(asBits, mmType, writer, regAlloc, encoding, ExtractSImm9(encoding), 0x1ffu << 12);
+ }
+
+ private static void RewriteMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding, int imm, uint immMask)
+ {
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64);
+
+ Assembler asm = new(writer);
+
+ bool canFoldOffset = CanFoldOffset(mmType, imm);
+ if (canFoldOffset)
+ {
+ imm = 0;
+ }
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress, imm);
+
+ encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
+
+ if (!canFoldOffset)
+ {
+ encoding &= ~immMask; // Clear offset
+ }
+
+ writer.WriteInstruction(encoding);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void RewriteLiteralMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstName name, ulong pc, uint encoding)
+ {
+ Assembler asm = new(writer);
+
+ ulong targetAddress;
+ long imm;
+ int rtIndex = (int)(encoding & 0x1f);
+
+ if (rtIndex == RegisterUtils.ZrIndex && name != InstName.PrfmLit)
+ {
+ return;
+ }
+
+ Operand rt;
+
+ if (name == InstName.LdrLitFpsimd)
+ {
+ uint opc = encoding >> 30;
+
+ // TODO: Undefined if opc is invalid?
+
+ rt = new(rtIndex, RegisterType.Vector, opc switch
+ {
+ 0 => OperandType.FP32,
+ 1 => OperandType.FP64,
+ _ => OperandType.V128,
+ });
+ }
+ else
+ {
+ rt = new(rtIndex, RegisterType.Integer, OperandType.I64);
+ }
+
+ switch (name)
+ {
+ case InstName.Adr:
+ case InstName.Adrp:
+ imm = ((long)(encoding >> 29) & 3) | ((long)(encoding >> 3) & 0x1ffffc);
+ imm <<= 43;
+
+ if (name == InstName.Adrp)
+ {
+ imm >>= 31;
+ targetAddress = (pc & ~0xfffUL) + (ulong)imm;
+ }
+ else
+ {
+ imm >>= 43;
+ targetAddress = pc + (ulong)imm;
+ }
+
+ asm.Mov(rt, targetAddress);
+ break;
+ case InstName.LdrLitGen:
+ case InstName.LdrswLit:
+ case InstName.LdrLitFpsimd:
+ case InstName.PrfmLit:
+ imm = encoding & ~0x1fu;
+ imm <<= 40;
+ imm >>= 43;
+ targetAddress = pc + (ulong)imm;
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, targetAddress);
+
+ switch (name)
+ {
+ case InstName.LdrLitGen:
+ case InstName.LdrLitFpsimd:
+ asm.LdrRiUn(rt, rn, 0);
+ break;
+ case InstName.LdrswLit:
+ asm.LdrswRiUn(rt, rn, 0);
+ break;
+ case InstName.PrfmLit:
+ asm.PrfmR(rt, rn);
+ break;
+ }
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ break;
+ default:
+ Debug.Fail($"Invalid literal memory instruction '{name}'.");
+ break;
+ }
+ }
+
+ private static void RewriteStructPostIndexedRegMemoryInstruction(int asBits, MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
+ {
+ // TODO: Some unallocated encoding cases.
+
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+ Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
+ Operand guestAddress = new(RegisterUtils.ExtractRn(encoding), RegisterType.Integer, OperandType.I64);
+
+ int rmIndex = RegisterUtils.ExtractRm(encoding);
+
+ Assembler asm = new(writer);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, rn, guestAddress);
+
+ encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
+ encoding &= ~((0x1fu << 16) | (1u << 23)); // Post-index -> No offset
+
+ writer.WriteInstruction(encoding);
+
+ if (rmIndex == RegisterUtils.ZrIndex)
+ {
+ bool isSingleStruct = (encoding & (1u << 24)) != 0;
+ int offset;
+
+ if (isSingleStruct)
+ {
+ int sElems = (int)(((encoding >> 12) & 2u) | ((encoding >> 21) & 1u)) + 1;
+
+ int size = (int)(encoding >> 10) & 3;
+ int s = (int)(encoding >> 12) & 1;
+ int scale = (int)(encoding >> 14) & 3;
+ int l = (int)(encoding >> 22) & 1;
+
+ switch (scale)
+ {
+ case 1:
+ if ((size & 1) != 0)
+ {
+ // Undef.
+ }
+
+ break;
+
+ case 2:
+ if ((size & 2) != 0 ||
+ ((size & 1) != 0 && s != 0))
+ {
+ // Undef.
+ }
+
+ if ((size & 1) != 0)
+ {
+ scale = 3;
+ }
+
+ break;
+
+ case 3:
+ if (l == 0 || s != 0)
+ {
+ // Undef.
+ }
+
+ scale = size;
+
+ break;
+ }
+
+ int eBytes = 1 << scale;
+
+ offset = eBytes * sElems;
+ }
+ else
+ {
+ int reps;
+ int sElems;
+
+ switch ((encoding >> 12) & 0xf)
+ {
+ case 0b0000:
+ reps = 1;
+ sElems = 4;
+ break;
+ case 0b0010:
+ reps = 4;
+ sElems = 1;
+ break;
+ case 0b0100:
+ reps = 1;
+ sElems = 3;
+ break;
+ case 0b0110:
+ reps = 3;
+ sElems = 1;
+ break;
+ case 0b0111:
+ reps = 1;
+ sElems = 1;
+ break;
+ case 0b1000:
+ reps = 1;
+ sElems = 2;
+ break;
+ case 0b1010:
+ reps = 2;
+ sElems = 1;
+ break;
+
+ default:
+ // Undef.
+ reps = 0;
+ sElems = 0;
+ break;
+ }
+
+ int size = (int)(encoding >> 10) & 3;
+ bool q = (encoding & (1u << 30)) != 0;
+
+ if (!q && size == 3 && sElems != 1)
+ {
+ // Undef.
+ }
+
+ offset = reps * (q ? 16 : 8) * sElems;
+ }
+
+ asm.Add(guestAddress, guestAddress, new Operand(OperandKind.Constant, OperandType.I32, (ulong)offset));
+ }
+ else
+ {
+ Operand guestOffset = new(rmIndex, RegisterType.Integer, OperandType.I64);
+
+ asm.Add(guestAddress, guestAddress, guestOffset);
+ }
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ private static void WriteAddressTranslation(
+ int asBits,
+ MemoryManagerType mmType,
+ RegisterAllocator regAlloc,
+ ref Assembler asm,
+ Operand destination,
+ Operand guestAddress,
+ int offset)
+ {
+ if (offset != 0)
+ {
+ // They are assumed to be on different registers, otherwise this operation will thrash the address.
+ Debug.Assert(destination.Value != guestAddress.Value);
+
+ if (Math.Abs(offset) >= 0x1000)
+ {
+ // Too high to encode as 12-bit immediate, do a separate move.
+ asm.Mov(destination, (ulong)offset);
+ asm.Add(destination, destination, guestAddress);
+ }
+ else
+ {
+ // Encode as 12-bit immediate.
+ WriteAddConstant(ref asm, destination, guestAddress, offset);
+ }
+
+ guestAddress = destination;
+ }
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, destination, guestAddress);
+ }
+
+ private static void WriteAddressTranslation(int asBits, MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, ulong guestAddress)
+ {
+ asm.Mov(destination, guestAddress);
+
+ WriteAddressTranslation(asBits, mmType, regAlloc, ref asm, destination, destination);
+ }
+
+ private static void WriteAddressTranslation(int asBits, MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, Operand guestAddress)
+ {
+ Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);
+
+ if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe)
+ {
+ if (mmType == MemoryManagerType.HostMapped)
+ {
+ asm.And(destination, guestAddress, new Operand(OperandKind.Constant, OperandType.I64, ulong.MaxValue >> (64 - asBits)));
+ guestAddress = destination;
+ }
+
+ asm.Add(destination, basePointer, guestAddress);
+ }
+ else
+ {
+ throw new NotImplementedException(mmType.ToString());
+ }
+ }
+
+ private static void WriteAddConstant(ref Assembler asm, Operand rd, Operand rn, int value)
+ {
+ if (value < 0)
+ {
+ asm.Sub(rd, rn, new Operand(OperandKind.Constant, OperandType.I32, (ulong)-value));
+ }
+ else
+ {
+ asm.Add(rd, rn, new Operand(OperandKind.Constant, OperandType.I32, (ulong)value));
+ }
+ }
+
+ private static bool CanFoldOffset(MemoryManagerType mmType, int offset)
+ {
+ return mmType == MemoryManagerType.HostMappedUnsafe;
+ }
+
+ private static int ExtractSImm7Scaled(InstFlags flags, uint encoding)
+ {
+ uint opc = flags.HasFlag(InstFlags.FpSimd) ? encoding >> 30 : encoding >> 31;
+ return ExtractSImm7(encoding) << (int)(2 + opc);
+ }
+
+ private static int ExtractSImm7(uint encoding)
+ {
+ int imm = (int)(encoding >> 15);
+
+ imm <<= 25;
+ imm >>= 25;
+
+ return imm;
+ }
+
+ private static int ExtractSImm9(uint encoding)
+ {
+ int imm = (int)(encoding >> 12);
+
+ imm <<= 23;
+ imm >>= 23;
+
+ return imm;
+ }
+
+ private static int ExtractUImm12Scaled(InstFlags flags, uint encoding)
+ {
+ uint size = encoding >> 30;
+
+ if (flags.HasFlag(InstFlags.FpSimd))
+ {
+ size |= (encoding >> 21) & 4u;
+ }
+
+ return ExtractUImm12(encoding) << (int)size;
+ }
+
+ private static int ExtractUImm12(uint encoding)
+ {
+ return (int)(encoding >> 10) & 0xfff;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
new file mode 100644
index 00000000..3d4204fc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
@@ -0,0 +1,610 @@
+using ARMeilleure.Common;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using System;
+using System.Diagnostics;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
+{
+ static class InstEmitSystem
+ {
+ private delegate void SoftwareInterruptHandler(ulong address, int imm);
+ private delegate ulong Get64();
+ private delegate bool GetBool();
+
+ public static void RewriteInstruction(
+ CodeWriter writer,
+ RegisterAllocator regAlloc,
+ TailMerger tailMerger,
+ InstName name,
+ ulong pc,
+ uint encoding,
+ int spillBaseOffset)
+ {
+ if (name == InstName.Brk)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetBrkHandlerPtr(), spillBaseOffset, null, pc, encoding);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
+ }
+ else if (name == InstName.Svc)
+ {
+ uint svcId = (ushort)(encoding >> 5);
+
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetSvcHandlerPtr(), spillBaseOffset, null, pc, svcId);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
+ }
+ else if (name == InstName.UdfPermUndef)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetUdfHandlerPtr(), spillBaseOffset, null, pc, encoding);
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
+ }
+ else if ((encoding & ~0x1f) == 0xd53bd060) // mrs x0, tpidrro_el0
+ {
+ uint rd = encoding & 0x1f;
+
+ if (rd != RegisterUtils.ZrIndex)
+ {
+ Assembler asm = new(writer);
+
+ asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrroEl0Offset);
+ }
+ }
+ else if ((encoding & ~0x1f) == 0xd53bd040) // mrs x0, tpidr_el0
+ {
+ uint rd = encoding & 0x1f;
+
+ if (rd != RegisterUtils.ZrIndex)
+ {
+ Assembler asm = new(writer);
+
+ asm.LdrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset);
+ }
+ }
+ else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0
+ {
+ uint rd = encoding & 0x1f;
+
+ if (rd != RegisterUtils.ZrIndex)
+ {
+ Assembler asm = new(writer);
+
+ // TODO: Use host value? But that register can't be accessed on macOS...
+ asm.Mov(Register((int)rd, OperandType.I32), 0x8444c004);
+ }
+ }
+ else if ((encoding & ~0x1f) == 0xd53be020) // mrs x0, cntpct_el0
+ {
+ uint rd = encoding & 0x1f;
+
+ if (rd != RegisterUtils.ZrIndex)
+ {
+ Assembler asm = new(writer);
+
+ WriteCall(ref asm, regAlloc, GetCntpctEl0Ptr(), spillBaseOffset, (int)rd);
+ }
+ }
+ else if ((encoding & ~0x1f) == 0xd51bd040) // msr tpidr_el0, x0
+ {
+ uint rd = encoding & 0x1f;
+
+ if (rd != RegisterUtils.ZrIndex)
+ {
+ Assembler asm = new(writer);
+
+ asm.StrRiUn(Register((int)rd), Register(regAlloc.FixedContextRegister), NativeContextOffsets.TpidrEl0Offset);
+ }
+ }
+ else
+ {
+ writer.WriteInstruction(encoding);
+ }
+ }
+
+ public static bool NeedsCall(uint encoding)
+ {
+ if ((encoding & ~(0xffffu << 5)) == 0xd4000001u) // svc #0
+ {
+ return true;
+ }
+ else if ((encoding & ~0x1f) == 0xd53b0020 && IsAppleOS()) // mrs x0, ctr_el0
+ {
+ return true;
+ }
+ else if ((encoding & ~0x1f) == 0xd53be020) // mrs x0, cntpct_el0
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool IsAppleOS()
+ {
+ return OperatingSystem.IsMacOS() || OperatingSystem.IsIOS();
+ }
+
+ public static bool NeedsContextStoreLoad(InstName name)
+ {
+ return name == InstName.Svc;
+ }
+
+ private static IntPtr GetBrkHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.Break);
+ }
+
+ private static IntPtr GetSvcHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.SupervisorCall);
+ }
+
+ private static IntPtr GetUdfHandlerPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.Undefined);
+ }
+
+ private static IntPtr GetCntpctEl0Ptr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.GetCntpctEl0);
+ }
+
+ private static IntPtr CheckSynchronizationPtr()
+ {
+ return Marshal.GetFunctionPointerForDelegate(NativeInterface.CheckSynchronization);
+ }
+
+ public static void WriteSyncPoint(CodeWriter writer, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset)
+ {
+ Assembler asm = new(writer);
+
+ WriteSyncPoint(writer, ref asm, regAlloc, tailMerger, spillBaseOffset);
+ }
+
+ private static void WriteSyncPoint(CodeWriter writer, ref Assembler asm, RegisterAllocator regAlloc, TailMerger tailMerger, int spillBaseOffset)
+ {
+ int tempRegister = regAlloc.AllocateTempGprRegister();
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ int branchIndex = writer.InstructionPointer;
+ asm.Cbnz(rt, 0);
+
+ WriteSpill(ref asm, regAlloc, 1u << tempRegister, spillBaseOffset, tempRegister);
+
+ Operand rn = Register(tempRegister == 0 ? 1 : 0);
+
+ asm.Mov(rn, (ulong)CheckSynchronizationPtr());
+ asm.Blr(rn);
+
+ tailMerger.AddConditionalZeroReturn(writer, asm, Register(0, OperandType.I32));
+
+ WriteFill(ref asm, regAlloc, 1u << tempRegister, spillBaseOffset, tempRegister);
+
+ asm.LdrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ uint branchInst = writer.ReadInstructionAt(branchIndex);
+ writer.WriteInstructionAt(branchIndex, branchInst | (((uint)(writer.InstructionPointer - branchIndex) & 0x7ffff) << 5));
+
+ asm.Sub(rt, rt, new Operand(OperandKind.Constant, OperandType.I32, 1));
+ asm.StrRiUn(rt, Register(regAlloc.FixedContextRegister), NativeContextOffsets.CounterOffset);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+
+ public static void RewriteCallInstruction(
+ CodeWriter writer,
+ RegisterAllocator regAlloc,
+ TailMerger tailMerger,
+ Action writeEpilogue,
+ AddressTable funcTable,
+ IntPtr dispatchStubPtr,
+ InstName name,
+ ulong pc,
+ uint encoding,
+ int spillBaseOffset,
+ bool isTail = false)
+ {
+ Assembler asm = new(writer);
+
+ switch (name)
+ {
+ case InstName.BUncond:
+ case InstName.Bl:
+ case InstName.Blr:
+ case InstName.Br:
+ if (name == InstName.BUncond || name == InstName.Bl)
+ {
+ int imm = ImmUtils.ExtractSImm26Times4(encoding);
+
+ WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ regAlloc,
+ tailMerger,
+ writeEpilogue,
+ funcTable,
+ dispatchStubPtr,
+ spillBaseOffset,
+ pc,
+ new(OperandKind.Constant, OperandType.I64, pc + (ulong)imm),
+ isTail);
+ }
+ else
+ {
+ int rnIndex = RegisterUtils.ExtractRn(encoding);
+ if (rnIndex == RegisterUtils.ZrIndex)
+ {
+ WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ regAlloc,
+ tailMerger,
+ writeEpilogue,
+ funcTable,
+ dispatchStubPtr,
+ spillBaseOffset,
+ pc,
+ new(OperandKind.Constant, OperandType.I64, 0UL),
+ isTail);
+ }
+ else
+ {
+ rnIndex = regAlloc.RemapReservedGprRegister(rnIndex);
+
+ WriteCallWithGuestAddress(
+ writer,
+ ref asm,
+ regAlloc,
+ tailMerger,
+ writeEpilogue,
+ funcTable,
+ dispatchStubPtr,
+ spillBaseOffset,
+ pc,
+ Register(rnIndex),
+ isTail);
+ }
+ }
+ break;
+
+ default:
+ Debug.Fail($"Unknown branch instruction \"{name}\".");
+ break;
+ }
+ }
+
+ public unsafe static void WriteCallWithGuestAddress(
+ CodeWriter writer,
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ TailMerger tailMerger,
+ Action writeEpilogue,
+ AddressTable funcTable,
+ IntPtr funcPtr,
+ int spillBaseOffset,
+ ulong pc,
+ Operand guestAddress,
+ bool isTail = false)
+ {
+ int tempRegister;
+
+ if (guestAddress.Kind == OperandKind.Constant)
+ {
+ tempRegister = regAlloc.AllocateTempGprRegister();
+
+ asm.Mov(Register(tempRegister), guestAddress.Value);
+ asm.StrRiUn(Register(tempRegister), Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+
+ regAlloc.FreeTempGprRegister(tempRegister);
+ }
+ else
+ {
+ asm.StrRiUn(guestAddress, Register(regAlloc.FixedContextRegister), NativeContextOffsets.DispatchAddressOffset);
+ }
+
+ tempRegister = regAlloc.FixedContextRegister == 1 ? 2 : 1;
+
+ if (!isTail)
+ {
+ WriteSpillSkipContext(ref asm, regAlloc, spillBaseOffset);
+ }
+
+ Operand rn = Register(tempRegister);
+
+ if (regAlloc.FixedContextRegister != 0)
+ {
+ asm.Mov(Register(0), Register(regAlloc.FixedContextRegister));
+ }
+
+ if (guestAddress.Kind == OperandKind.Constant && funcTable != null)
+ {
+ ulong funcPtrLoc = (ulong)Unsafe.AsPointer(ref funcTable.GetValue(guestAddress.Value));
+
+ asm.Mov(rn, funcPtrLoc & ~0xfffUL);
+ asm.LdrRiUn(rn, rn, (int)(funcPtrLoc & 0xfffUL));
+ }
+ else
+ {
+ asm.Mov(rn, (ulong)funcPtr);
+ }
+
+ if (isTail)
+ {
+ writeEpilogue();
+ asm.Br(rn);
+ }
+ else
+ {
+ asm.Blr(rn);
+
+ ulong nextAddress = pc + 4UL;
+
+ asm.Mov(rn, nextAddress);
+ asm.Cmp(Register(0), rn);
+
+ tailMerger.AddConditionalReturn(writer, asm, ArmCondition.Ne);
+
+ WriteFillSkipContext(ref asm, regAlloc, spillBaseOffset);
+ }
+ }
+
+ private static void WriteCall(
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ IntPtr funcPtr,
+ int spillBaseOffset,
+ int? resultRegister,
+ params ulong[] callArgs)
+ {
+ uint resultMask = 0u;
+
+ if (resultRegister.HasValue)
+ {
+ resultMask = 1u << resultRegister.Value;
+ }
+
+ int tempRegister = callArgs.Length;
+
+ if (resultRegister.HasValue && tempRegister == resultRegister.Value)
+ {
+ tempRegister++;
+ }
+
+ WriteSpill(ref asm, regAlloc, resultMask, spillBaseOffset, tempRegister);
+
+ // We only support up to 7 arguments right now.
+ // ABI defines the first 8 integer arguments to be passed on registers X0-X7.
+ // We need at least one register to put the function address on, so that reduces the number of
+ // registers we can use for that by one.
+
+ Debug.Assert(callArgs.Length < 8);
+
+ for (int index = 0; index < callArgs.Length; index++)
+ {
+ asm.Mov(Register(index), callArgs[index]);
+ }
+
+ Operand rn = Register(tempRegister);
+
+ asm.Mov(rn, (ulong)funcPtr);
+ asm.Blr(rn);
+
+ if (resultRegister.HasValue && resultRegister.Value != 0)
+ {
+ asm.Mov(Register(resultRegister.Value), Register(0));
+ }
+
+ WriteFill(ref asm, regAlloc, resultMask, spillBaseOffset, tempRegister);
+ }
+
+ private static void WriteSpill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, int spillOffset, int tempRegister)
+ {
+ WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: true);
+ }
+
+ private static void WriteFill(ref Assembler asm, RegisterAllocator regAlloc, uint exceptMask, int spillOffset, int tempRegister)
+ {
+ WriteSpillOrFill(ref asm, regAlloc, exceptMask, spillOffset, tempRegister, spill: false);
+ }
+
+ private static void WriteSpillOrFill(
+ ref Assembler asm,
+ RegisterAllocator regAlloc,
+ uint exceptMask,
+ int spillOffset,
+ int tempRegister,
+ bool spill)
+ {
+ uint gprMask = regAlloc.AllGprMask & ~(AbiConstants.GprCalleeSavedRegsMask | exceptMask);
+
+ if (regAlloc.AllPStateMask != 0 && !spill)
+ {
+ // We must reload the status register before reloading the GPRs,
+ // since we might otherwise trash one of them by using it as temp register.
+
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.LdrRiUn(rt, Register(RegisterUtils.SpIndex), spillOffset + BitOperations.PopCount(gprMask) * 8);
+ asm.MsrNzcv(rt);
+ }
+
+ while (gprMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(gprMask);
+
+ if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(
+ Register(regAlloc.RemapReservedGprRegister(reg)),
+ Register(regAlloc.RemapReservedGprRegister(reg + 1)),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(
+ Register(regAlloc.RemapReservedGprRegister(reg)),
+ Register(regAlloc.RemapReservedGprRegister(reg + 1)),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+
+ gprMask &= ~(3u << reg);
+ spillOffset += 16;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(1u << reg);
+ spillOffset += 8;
+ }
+ }
+
+ if (regAlloc.AllPStateMask != 0)
+ {
+ if (spill)
+ {
+ Operand rt = Register(tempRegister, OperandType.I32);
+
+ asm.MrsNzcv(rt);
+ asm.StrRiUn(rt, Register(RegisterUtils.SpIndex), spillOffset);
+ }
+
+ spillOffset += 8;
+ }
+
+ if ((spillOffset & 8) != 0)
+ {
+ spillOffset += 8;
+ }
+
+ uint fpSimdMask = regAlloc.AllFpSimdMask;
+
+ while (fpSimdMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(fpSimdMask);
+
+ if (reg < 31 && (fpSimdMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(
+ Register(reg, OperandType.V128),
+ Register(reg + 1, OperandType.V128),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(
+ Register(reg, OperandType.V128),
+ Register(reg + 1, OperandType.V128),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+
+ fpSimdMask &= ~(3u << reg);
+ spillOffset += 32;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(reg, OperandType.V128), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(reg, OperandType.V128), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+
+ fpSimdMask &= ~(1u << reg);
+ spillOffset += 16;
+ }
+ }
+ }
+
+ private static void WriteSpillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
+ {
+ WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: true);
+ }
+
+ private static void WriteFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset)
+ {
+ WriteSpillOrFillSkipContext(ref asm, regAlloc, spillOffset, spill: false);
+ }
+
+ private static void WriteSpillOrFillSkipContext(ref Assembler asm, RegisterAllocator regAlloc, int spillOffset, bool spill)
+ {
+ uint gprMask = regAlloc.AllGprMask & ((1u << regAlloc.FixedContextRegister) | (1u << regAlloc.FixedPageTableRegister));
+ gprMask &= ~AbiConstants.GprCalleeSavedRegsMask;
+
+ while (gprMask != 0)
+ {
+ int reg = BitOperations.TrailingZeroCount(gprMask);
+
+ if (reg < 31 && (gprMask & (2u << reg)) != 0 && spillOffset < RegisterSaveRestore.Encodable9BitsOffsetLimit)
+ {
+ if (spill)
+ {
+ asm.StpRiUn(
+ Register(regAlloc.RemapReservedGprRegister(reg)),
+ Register(regAlloc.RemapReservedGprRegister(reg + 1)),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+ else
+ {
+ asm.LdpRiUn(
+ Register(regAlloc.RemapReservedGprRegister(reg)),
+ Register(regAlloc.RemapReservedGprRegister(reg + 1)),
+ Register(RegisterUtils.SpIndex),
+ spillOffset);
+ }
+
+ gprMask &= ~(3u << reg);
+ spillOffset += 16;
+ }
+ else
+ {
+ if (spill)
+ {
+ asm.StrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+ else
+ {
+ asm.LdrRiUn(Register(regAlloc.RemapReservedGprRegister(reg)), Register(RegisterUtils.SpIndex), spillOffset);
+ }
+
+ gprMask &= ~(1u << reg);
+ spillOffset += 8;
+ }
+ }
+ }
+
+ private static Operand Register(int register, OperandType type = OperandType.I64)
+ {
+ return new Operand(register, RegisterType.Integer, type);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs
new file mode 100644
index 00000000..88718afb
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs
@@ -0,0 +1,1605 @@
+using Ryujinx.Cpu.LightningJit.Table;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
+{
+ static class InstTable
+ {
+ private static readonly InstTableLevel _table;
+
+ private readonly struct InstInfo : IInstInfo
+ {
+ public uint Encoding { get; }
+ public uint EncodingMask { get; }
+ public InstEncoding[] Constraints { get; }
+ public InstName Name { get; }
+ public IsaVersion Version { get; }
+ public IsaFeature Feature { get; }
+ public InstFlags Flags { get; }
+ public AddressForm AddressForm { get; }
+
+ public InstInfo(
+ uint encoding,
+ uint encodingMask,
+ InstEncoding[] constraints,
+ InstName name,
+ IsaVersion isaVersion,
+ IsaFeature isaFeature,
+ InstFlags flags,
+ AddressForm addressForm = AddressForm.None)
+ {
+ if (addressForm != AddressForm.None)
+ {
+ flags |= InstFlags.Memory;
+ }
+
+ Encoding = encoding;
+ EncodingMask = encodingMask;
+ Constraints = constraints;
+ Name = name;
+ Version = isaVersion;
+ Feature = isaFeature;
+ Flags = flags;
+ AddressForm = addressForm;
+ }
+
+ public InstInfo(
+ uint encoding,
+ uint encodingMask,
+ InstEncoding[] constraints,
+ InstName name,
+ IsaVersion isaVersion,
+ InstFlags flags,
+ AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, constraints, name, isaVersion, IsaFeature.None, flags, addressForm)
+ {
+ }
+
+ public InstInfo(
+ uint encoding,
+ uint encodingMask,
+ InstName name,
+ IsaVersion isaVersion,
+ IsaFeature isaFeature,
+ InstFlags flags,
+ AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, null, name, isaVersion, isaFeature, flags, addressForm)
+ {
+ }
+
+ public InstInfo(
+ uint encoding,
+ uint encodingMask,
+ InstName name,
+ IsaVersion isaVersion,
+ InstFlags flags,
+ AddressForm addressForm = AddressForm.None) : this(encoding, encodingMask, null, name, isaVersion, IsaFeature.None, flags, addressForm)
+ {
+ }
+
+ public bool IsConstrained(uint encoding)
+ {
+ if (Constraints != null)
+ {
+ foreach (InstEncoding constraint in Constraints)
+ {
+ if ((encoding & constraint.EncodingMask) == constraint.Encoding)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ static InstTable()
+ {
+ InstEncoding[] qsizeConstraints = new InstEncoding[]
+ {
+ new(0x00C00000, 0x40C00000),
+ };
+
+ InstEncoding[] sizeConstraints = new InstEncoding[]
+ {
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] opuOpuOpuConstraints = new InstEncoding[]
+ {
+ new(0x00001400, 0x00001C00),
+ new(0x00001800, 0x00001C00),
+ new(0x00001C00, 0x00001C00),
+ };
+
+ InstEncoding[] shiftSfimm6Constraints = new InstEncoding[]
+ {
+ new(0x00C00000, 0x00C00000),
+ new(0x00008000, 0x80008000),
+ };
+
+ InstEncoding[] qsizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00800000, 0x40C00000),
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints = new InstEncoding[]
+ {
+ new(0x0040FC00, 0x0040FC00),
+ new(0x00007C00, 0x0040FC00),
+ new(0x0000BC00, 0x0040FC00),
+ new(0x0000DC00, 0x0040FC00),
+ new(0x0000EC00, 0x0040FC00),
+ new(0x0000F400, 0x0040FC00),
+ new(0x0000F800, 0x0040FC00),
+ new(0x0000FC00, 0x0040FC00),
+ new(0x00400000, 0x80400000),
+ };
+
+ InstEncoding[] sfimm6Constraints = new InstEncoding[]
+ {
+ new(0x00008000, 0x80008000),
+ };
+
+ InstEncoding[] sfnSfnSfimmr5Sfimms5Constraints = new InstEncoding[]
+ {
+ new(0x80000000, 0x80400000),
+ new(0x00400000, 0x80400000),
+ new(0x00200000, 0x80200000),
+ new(0x00008000, 0x80008000),
+ };
+
+ InstEncoding[] cmodeopqConstraints = new InstEncoding[]
+ {
+ new(0x2000F000, 0x6000F000),
+ };
+
+ InstEncoding[] rsRtConstraints = new InstEncoding[]
+ {
+ new(0x00010000, 0x00010000),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] sfszSfszSfszSfszConstraints = new InstEncoding[]
+ {
+ new(0x80000000, 0x80000C00),
+ new(0x80000400, 0x80000C00),
+ new(0x80000800, 0x80000C00),
+ new(0x00000C00, 0x80000C00),
+ };
+
+ InstEncoding[] imm5Constraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x000F0000),
+ };
+
+ InstEncoding[] imm5Imm5qConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x000F0000),
+ new(0x00080000, 0x400F0000),
+ };
+
+ InstEncoding[] nsfNsfSfimmsConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x80400000),
+ new(0x80000000, 0x80400000),
+ new(0x00008000, 0x80008000),
+ };
+
+ InstEncoding[] qimm4Constraints = new InstEncoding[]
+ {
+ new(0x00004000, 0x40004000),
+ };
+
+ InstEncoding[] qszConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x40400000),
+ };
+
+ InstEncoding[] euacEuacEuacConstraints = new InstEncoding[]
+ {
+ new(0x00000800, 0x20800800),
+ new(0x00800000, 0x20800800),
+ new(0x00800800, 0x20800800),
+ };
+
+ InstEncoding[] qszEuacEuacEuacConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x40400000),
+ new(0x00000800, 0x20800800),
+ new(0x00800000, 0x20800800),
+ new(0x00800800, 0x20800800),
+ };
+
+ InstEncoding[] szConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x00400000),
+ };
+
+ InstEncoding[] sizeQsizeConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00C00000),
+ new(0x00C00000, 0x40C00000),
+ };
+
+ InstEncoding[] sizeSizeSizelSizeqSizehqConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00C00000),
+ new(0x00C00000, 0x00C00000),
+ new(0x00A00000, 0x00E00000),
+ new(0x00800000, 0x40C00000),
+ new(0x00400800, 0x40C00800),
+ };
+
+ InstEncoding[] szConstraints2 = new InstEncoding[]
+ {
+ new(0x00000000, 0x00400000),
+ };
+
+ InstEncoding[] immhConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00780000),
+ };
+
+ InstEncoding[] immhQimmhConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00780000),
+ new(0x00400000, 0x40400000),
+ };
+
+ InstEncoding[] sfscaleConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x80008000),
+ };
+
+ InstEncoding[] ftypeopcFtypeopcFtypeopcFtypeopcFtypeOpcConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00C18000),
+ new(0x00408000, 0x00C18000),
+ new(0x00810000, 0x00C18000),
+ new(0x00C18000, 0x00C18000),
+ new(0x00800000, 0x00C00000),
+ new(0x00010000, 0x00018000),
+ };
+
+ InstEncoding[] szlConstraints = new InstEncoding[]
+ {
+ new(0x00600000, 0x00600000),
+ };
+
+ InstEncoding[] szlQszConstraints = new InstEncoding[]
+ {
+ new(0x00600000, 0x00600000),
+ new(0x00400000, 0x40400000),
+ };
+
+ InstEncoding[] qConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x40000000),
+ };
+
+ InstEncoding[] sfftypermodeSfftypermodeConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x80C80000),
+ new(0x80000000, 0x80C80000),
+ };
+
+ InstEncoding[] uo1o2Constraints = new InstEncoding[]
+ {
+ new(0x20800000, 0x20801000),
+ };
+
+ InstEncoding[] qszUo1o2Constraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x40400000),
+ new(0x20800000, 0x20801000),
+ };
+
+ InstEncoding[] sConstraints = new InstEncoding[]
+ {
+ new(0x00001000, 0x00001000),
+ };
+
+ InstEncoding[] opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints = new InstEncoding[]
+ {
+ new(0x00004400, 0x0000C400),
+ new(0x00008800, 0x0000C800),
+ new(0x00009400, 0x0000D400),
+ new(0x0000C000, 0x0000C000),
+ };
+
+ InstEncoding[] qsizeConstraints2 = new InstEncoding[]
+ {
+ new(0x00000C00, 0x40000C00),
+ };
+
+ InstEncoding[] rtRtConstraints = new InstEncoding[]
+ {
+ new(0x00000018, 0x00000018),
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] opc1sizeOpc1sizeOpc1sizeConstraints = new InstEncoding[]
+ {
+ new(0x40800000, 0xC0800000),
+ new(0x80800000, 0xC0800000),
+ new(0xC0800000, 0xC0800000),
+ };
+
+ InstEncoding[] rtRt2Constraints = new InstEncoding[]
+ {
+ new(0x0000001F, 0x0000001F),
+ new(0x001F0000, 0x001F0000),
+ };
+
+ InstEncoding[] opcConstraints = new InstEncoding[]
+ {
+ new(0xC0000000, 0xC0000000),
+ };
+
+ InstEncoding[] opcConstraints2 = new InstEncoding[]
+ {
+ new(0x40000000, 0x40000000),
+ };
+
+ InstEncoding[] opclOpcConstraints = new InstEncoding[]
+ {
+ new(0x40000000, 0x40400000),
+ new(0xC0000000, 0xC0000000),
+ };
+
+ InstEncoding[] optionConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00004000),
+ };
+
+ InstEncoding[] opc1sizeOpc1sizeOpc1sizeOptionConstraints = new InstEncoding[]
+ {
+ new(0x40800000, 0xC0800000),
+ new(0x80800000, 0xC0800000),
+ new(0xC0800000, 0xC0800000),
+ new(0x00000000, 0x00004000),
+ };
+
+ InstEncoding[] sizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00C00000),
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] sfhwConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x80400000),
+ };
+
+ InstEncoding[] rtConstraints = new InstEncoding[]
+ {
+ new(0x00000001, 0x00000001),
+ };
+
+ InstEncoding[] usizeUsizeUsizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x20400000, 0x20C00000),
+ new(0x20800000, 0x20C00000),
+ new(0x20C00000, 0x20C00000),
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] sizeSizeConstraints2 = new InstEncoding[]
+ {
+ new(0x00400000, 0x00C00000),
+ new(0x00800000, 0x00C00000),
+ };
+
+ InstEncoding[] rtConstraints2 = new InstEncoding[]
+ {
+ new(0x00000018, 0x00000018),
+ };
+
+ InstEncoding[] sfopcConstraints = new InstEncoding[]
+ {
+ new(0x00000400, 0x80000400),
+ };
+
+ InstEncoding[] sizeSizeSizeConstraints = new InstEncoding[]
+ {
+ new(0x00400000, 0x00C00000),
+ new(0x00800000, 0x00C00000),
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] sizeSizeConstraints3 = new InstEncoding[]
+ {
+ new(0x00800000, 0x00C00000),
+ new(0x00C00000, 0x00C00000),
+ };
+
+ InstEncoding[] sfConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x80000000),
+ };
+
+ InstEncoding[] immhImmhConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00780000),
+ new(0x00400000, 0x00400000),
+ };
+
+ InstEncoding[] sizeSizeConstraints4 = new InstEncoding[]
+ {
+ new(0x00C00000, 0x00C00000),
+ new(0x00000000, 0x00C00000),
+ };
+
+ InstEncoding[] ssizeSsizeSsizeConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00C00800),
+ new(0x00400000, 0x00C00800),
+ new(0x00800000, 0x00C00800),
+ };
+
+ InstEncoding[] immhOpuConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00780000),
+ new(0x00000000, 0x20001000),
+ };
+
+ InstEncoding[] immhQimmhOpuConstraints = new InstEncoding[]
+ {
+ new(0x00000000, 0x00780000),
+ new(0x00400000, 0x40400000),
+ new(0x00000000, 0x20001000),
+ };
+
+ List insts = new()
+ {
+ new(0x5AC02000, 0x7FFFFC00, InstName.Abs, IsaVersion.v89, InstFlags.RdRn),
+ new(0x5EE0B800, 0xFFFFFC00, InstName.AbsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E20B800, 0xBF3FFC00, qsizeConstraints, InstName.AbsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1A000000, 0x7FE0FC00, InstName.Adc, IsaVersion.v80, InstFlags.RdRnRmC),
+ new(0x3A000000, 0x7FE0FC00, InstName.Adcs, IsaVersion.v80, InstFlags.RdRnRmCS),
+ new(0x91800000, 0xFFC0C000, InstName.Addg, IsaVersion.v85, InstFlags.None),
+ new(0x0E204000, 0xBF20FC00, sizeConstraints, InstName.AddhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5EF1B800, 0xFFFFFC00, InstName.AddpAdvsimdPair, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E20BC00, 0xBF20FC00, qsizeConstraints, InstName.AddpAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.AddsAddsubExt, IsaVersion.v80, InstFlags.RdRnSPRmS),
+ new(0x31000000, 0x7F800000, InstName.AddsAddsubImm, IsaVersion.v80, InstFlags.RdRnSPS),
+ new(0x2B000000, 0x7F200000, shiftSfimm6Constraints, InstName.AddsAddsubShift, IsaVersion.v80, InstFlags.RdRnRmS),
+ new(0x0E31B800, 0xBF3FFC00, qsizeSizeConstraints, InstName.AddvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.AddAddsubExt, IsaVersion.v80, InstFlags.RdSPRnSPRm),
+ new(0x11000000, 0x7F800000, InstName.AddAddsubImm, IsaVersion.v80, InstFlags.RdSPRnSP),
+ new(0x0B000000, 0x7F200000, shiftSfimm6Constraints, InstName.AddAddsubShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x5EE08400, 0xFFE0FC00, InstName.AddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E208400, 0xBF20FC00, qsizeConstraints, InstName.AddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x10000000, 0x9F000000, InstName.Adr, IsaVersion.v80, InstFlags.Rd, AddressForm.Literal),
+ new(0x90000000, 0x9F000000, InstName.Adrp, IsaVersion.v80, InstFlags.Rd, AddressForm.Literal),
+ new(0x4E285800, 0xFFFFFC00, InstName.AesdAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x4E284800, 0xFFFFFC00, InstName.AeseAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x4E287800, 0xFFFFFC00, InstName.AesimcAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x4E286800, 0xFFFFFC00, InstName.AesmcAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x72000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.AndsLogImm, IsaVersion.v80, InstFlags.RdRnS),
+ new(0x6A000000, 0x7F200000, sfimm6Constraints, InstName.AndsLogShift, IsaVersion.v80, InstFlags.RdRnRmS),
+ new(0x0E201C00, 0xBFE0FC00, InstName.AndAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x12000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.AndLogImm, IsaVersion.v80, InstFlags.RdSPRn),
+ new(0x0A000000, 0x7F200000, sfimm6Constraints, InstName.AndLogShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x1AC02800, 0x7FE0FC00, InstName.Asrv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xDAC11800, 0xFFFFDC00, InstName.Autda, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xDAC11C00, 0xFFFFDC00, InstName.Autdb, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xDAC11000, 0xFFFFDC00, InstName.AutiaGeneral, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xD503219F, 0xFFFFFDDF, InstName.AutiaSystem, IsaVersion.v83, InstFlags.None),
+ new(0xDAC11400, 0xFFFFDC00, InstName.AutibGeneral, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xD50321DF, 0xFFFFFDDF, InstName.AutibSystem, IsaVersion.v83, InstFlags.None),
+ new(0xD500405F, 0xFFFFFFFF, InstName.Axflag, IsaVersion.v85, InstFlags.C),
+ new(0xCE200000, 0xFFE08000, InstName.BcaxAdvsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd),
+ new(0x54000010, 0xFF000010, InstName.BcCond, IsaVersion.v88, InstFlags.Nzcv),
+ new(0x0EA16800, 0xBFFFFC00, InstName.BfcvtnAdvsimd, IsaVersion.v86, InstFlags.RdRnFpSimd),
+ new(0x1E634000, 0xFFFFFC00, InstName.BfcvtFloat, IsaVersion.v86, InstFlags.RdRnFpSimd),
+ new(0x0F40F000, 0xBFC0F400, InstName.BfdotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E40FC00, 0xBFE0FC00, InstName.BfdotAdvsimdVec, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x33000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Bfm, IsaVersion.v80, InstFlags.RdReadRdRn),
+ new(0x0FC0F000, 0xBFC0F400, InstName.BfmlalAdvsimdElt, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x2EC0FC00, 0xBFE0FC00, InstName.BfmlalAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x6E40EC00, 0xFFE0FC00, InstName.BfmmlaAdvsimd, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x6A200000, 0x7F200000, sfimm6Constraints, InstName.Bics, IsaVersion.v80, InstFlags.RdRnRmS),
+ new(0x2F001400, 0xBFF81C00, cmodeopqConstraints, InstName.BicAdvsimdImm, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x0E601C00, 0xBFE0FC00, InstName.BicAdvsimdReg, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0A200000, 0x7F200000, sfimm6Constraints, InstName.BicLogShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x2EE01C00, 0xBFE0FC00, InstName.BifAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2EA01C00, 0xBFE0FC00, InstName.BitAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x94000000, 0xFC000000, InstName.Bl, IsaVersion.v80, InstFlags.None),
+ new(0xD63F0000, 0xFFFFFC1F, InstName.Blr, IsaVersion.v80, InstFlags.Rn),
+ new(0xD63F0800, 0xFEFFF800, InstName.Blra, IsaVersion.v83, InstFlags.RnRm),
+ new(0xD61F0000, 0xFFFFFC1F, InstName.Br, IsaVersion.v80, InstFlags.Rn),
+ new(0xD61F0800, 0xFEFFF800, InstName.Bra, IsaVersion.v83, InstFlags.RnRm),
+ new(0xD4200000, 0xFFE0001F, InstName.Brk, IsaVersion.v80, InstFlags.None),
+ new(0x2E601C00, 0xBFE0FC00, InstName.BslAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0xD503241F, 0xFFFFFF3F, InstName.Bti, IsaVersion.v85, InstFlags.None),
+ new(0x54000000, 0xFF000010, InstName.BCond, IsaVersion.v80, InstFlags.Nzcv),
+ new(0x14000000, 0xFC000000, InstName.BUncond, IsaVersion.v80, InstFlags.None),
+ new(0x88A07C00, 0xBFA07C00, InstName.Cas, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x08A07C00, 0xFFA07C00, InstName.Casb, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x48A07C00, 0xFFA07C00, InstName.Cash, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x08207C00, 0xBFA07C00, rsRtConstraints, InstName.Casp, IsaVersion.v81, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x35000000, 0x7F000000, InstName.Cbnz, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0x34000000, 0x7F000000, InstName.Cbz, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0x3A400800, 0x7FE00C10, InstName.CcmnImm, IsaVersion.v80, InstFlags.RnNzcvS),
+ new(0x3A400000, 0x7FE00C10, InstName.CcmnReg, IsaVersion.v80, InstFlags.RnRmNzcvS),
+ new(0x7A400800, 0x7FE00C10, InstName.CcmpImm, IsaVersion.v80, InstFlags.RnNzcvS),
+ new(0x7A400000, 0x7FE00C10, InstName.CcmpReg, IsaVersion.v80, InstFlags.RnRmNzcvS),
+ new(0xD500401F, 0xFFFFFFFF, InstName.Cfinv, IsaVersion.v84, InstFlags.C),
+ new(0xD503251F, 0xFFFFFFFF, InstName.Chkfeat, IsaVersion.None, InstFlags.None),
+ new(0xD50322DF, 0xFFFFFFFF, InstName.Clrbhb, IsaVersion.v89, InstFlags.None),
+ new(0xD503305F, 0xFFFFF0FF, InstName.Clrex, IsaVersion.v80, InstFlags.None),
+ new(0x0E204800, 0xBF3FFC00, sizeConstraints, InstName.ClsAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5AC01400, 0x7FFFFC00, InstName.ClsInt, IsaVersion.v80, InstFlags.RdRn),
+ new(0x2E204800, 0xBF3FFC00, sizeConstraints, InstName.ClzAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5AC01000, 0x7FFFFC00, InstName.ClzInt, IsaVersion.v80, InstFlags.RdRn),
+ new(0x7EE08C00, 0xFFE0FC00, InstName.CmeqAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E208C00, 0xBF20FC00, qsizeConstraints, InstName.CmeqAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EE09800, 0xFFFFFC00, InstName.CmeqAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E209800, 0xBF3FFC00, qsizeConstraints, InstName.CmeqAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EE03C00, 0xFFE0FC00, InstName.CmgeAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E203C00, 0xBF20FC00, qsizeConstraints, InstName.CmgeAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EE08800, 0xFFFFFC00, InstName.CmgeAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E208800, 0xBF3FFC00, qsizeConstraints, InstName.CmgeAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EE03400, 0xFFE0FC00, InstName.CmgtAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E203400, 0xBF20FC00, qsizeConstraints, InstName.CmgtAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EE08800, 0xFFFFFC00, InstName.CmgtAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E208800, 0xBF3FFC00, qsizeConstraints, InstName.CmgtAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7EE03400, 0xFFE0FC00, InstName.CmhiAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E203400, 0xBF20FC00, qsizeConstraints, InstName.CmhiAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EE03C00, 0xFFE0FC00, InstName.CmhsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E203C00, 0xBF20FC00, qsizeConstraints, InstName.CmhsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EE09800, 0xFFFFFC00, InstName.CmleAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E209800, 0xBF3FFC00, qsizeConstraints, InstName.CmleAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EE0A800, 0xFFFFFC00, InstName.CmltAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E20A800, 0xBF3FFC00, qsizeConstraints, InstName.CmltAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EE08C00, 0xFFE0FC00, InstName.CmtstAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E208C00, 0xBF20FC00, qsizeConstraints, InstName.CmtstAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5AC01C00, 0x7FFFFC00, InstName.Cnt, IsaVersion.v89, InstFlags.RdRn),
+ new(0x0E205800, 0xBFFFFC00, InstName.CntAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x19000400, 0x3F20FC00, InstName.Cpyfp, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900C400, 0x3F20FC00, InstName.Cpyfpn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19008400, 0x3F20FC00, InstName.Cpyfprn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19002400, 0x3F20FC00, InstName.Cpyfprt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900E400, 0x3F20FC00, InstName.Cpyfprtn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900A400, 0x3F20FC00, InstName.Cpyfprtrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19006400, 0x3F20FC00, InstName.Cpyfprtwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19003400, 0x3F20FC00, InstName.Cpyfpt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900F400, 0x3F20FC00, InstName.Cpyfptn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900B400, 0x3F20FC00, InstName.Cpyfptrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19007400, 0x3F20FC00, InstName.Cpyfptwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19004400, 0x3F20FC00, InstName.Cpyfpwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19001400, 0x3F20FC00, InstName.Cpyfpwt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1900D400, 0x3F20FC00, InstName.Cpyfpwtn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19009400, 0x3F20FC00, InstName.Cpyfpwtrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19005400, 0x3F20FC00, InstName.Cpyfpwtwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D000400, 0x3F20FC00, InstName.Cpyp, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00C400, 0x3F20FC00, InstName.Cpypn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D008400, 0x3F20FC00, InstName.Cpyprn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D002400, 0x3F20FC00, InstName.Cpyprt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00E400, 0x3F20FC00, InstName.Cpyprtn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00A400, 0x3F20FC00, InstName.Cpyprtrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D006400, 0x3F20FC00, InstName.Cpyprtwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D003400, 0x3F20FC00, InstName.Cpypt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00F400, 0x3F20FC00, InstName.Cpyptn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00B400, 0x3F20FC00, InstName.Cpyptrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D007400, 0x3F20FC00, InstName.Cpyptwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D004400, 0x3F20FC00, InstName.Cpypwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D001400, 0x3F20FC00, InstName.Cpypwt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D00D400, 0x3F20FC00, InstName.Cpypwtn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D009400, 0x3F20FC00, InstName.Cpypwtrn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1D005400, 0x3F20FC00, InstName.Cpypwtwn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1AC04000, 0x7FE0F000, sfszSfszSfszSfszConstraints, InstName.Crc32, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x1AC05000, 0x7FE0F000, sfszSfszSfszSfszConstraints, InstName.Crc32c, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xD503229F, 0xFFFFFFFF, InstName.Csdb, IsaVersion.v80, InstFlags.None),
+ new(0x1A800000, 0x7FE00C00, InstName.Csel, IsaVersion.v80, InstFlags.RdRnRmNzcv),
+ new(0x1A800400, 0x7FE00C00, InstName.Csinc, IsaVersion.v80, InstFlags.RdRnRmNzcv),
+ new(0x5A800000, 0x7FE00C00, InstName.Csinv, IsaVersion.v80, InstFlags.RdRnRmNzcv),
+ new(0x5A800400, 0x7FE00C00, InstName.Csneg, IsaVersion.v80, InstFlags.RdRnRmNzcv),
+ new(0x5AC01800, 0x7FFFFC00, InstName.Ctz, IsaVersion.v89, InstFlags.RdRn),
+ new(0xD4A00001, 0xFFE0001F, InstName.Dcps1, IsaVersion.v80, InstFlags.None),
+ new(0xD4A00002, 0xFFE0001F, InstName.Dcps2, IsaVersion.v80, InstFlags.None),
+ new(0xD4A00003, 0xFFE0001F, InstName.Dcps3, IsaVersion.v80, InstFlags.None),
+ new(0xD50320DF, 0xFFFFFFFF, InstName.Dgh, IsaVersion.v84, InstFlags.None),
+ new(0xD50330BF, 0xFFFFF0FF, InstName.Dmb, IsaVersion.v80, InstFlags.None),
+ new(0xD6BF03E0, 0xFFFFFFFF, InstName.Drps, IsaVersion.v80, InstFlags.None),
+ new(0xD503309F, 0xFFFFF0FF, InstName.DsbDsbMemory, IsaVersion.v80, InstFlags.None),
+ new(0xD503323F, 0xFFFFF3FF, InstName.DsbDsbNxs, IsaVersion.v87, InstFlags.None),
+ new(0x5E000400, 0xFFE0FC00, imm5Constraints, InstName.DupAdvsimdEltScalarFromElement, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E000400, 0xBFE0FC00, imm5Imm5qConstraints, InstName.DupAdvsimdEltVectorFromElement, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E000C00, 0xBFE0FC00, imm5Imm5qConstraints, InstName.DupAdvsimdGen, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x4A200000, 0x7F200000, sfimm6Constraints, InstName.Eon, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xCE000000, 0xFFE08000, InstName.Eor3Advsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd),
+ new(0x2E201C00, 0xBFE0FC00, InstName.EorAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x52000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.EorLogImm, IsaVersion.v80, InstFlags.RdSPRn),
+ new(0x4A000000, 0x7F200000, sfimm6Constraints, InstName.EorLogShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xD69F03E0, 0xFFFFFFFF, InstName.Eret, IsaVersion.v80, InstFlags.None),
+ new(0xD69F0BFF, 0xFFFFFBFF, InstName.Ereta, IsaVersion.v83, InstFlags.None),
+ new(0xD503221F, 0xFFFFFFFF, InstName.Esb, IsaVersion.v82, InstFlags.None),
+ new(0x13800000, 0x7FA00000, nsfNsfSfimmsConstraints, InstName.Extr, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x2E000000, 0xBFE08400, qimm4Constraints, InstName.ExtAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EC01400, 0xFFE0FC00, InstName.FabdAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7EA0D400, 0xFFA0FC00, InstName.FabdAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2EC01400, 0xBFE0FC00, InstName.FabdAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2EA0D400, 0xBFA0FC00, qszConstraints, InstName.FabdAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0EF8F800, 0xBFFFFC00, InstName.FabsAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA0F800, 0xBFBFFC00, qszConstraints, InstName.FabsAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E20C000, 0xFFBFFC00, InstName.FabsFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE0C000, 0xFFFFFC00, InstName.FabsFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7E402C00, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7E20EC00, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E402C00, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FacgeAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20EC00, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FacgeAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EC02C00, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7EA0EC00, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2EC02C00, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FacgtAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2EA0EC00, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FacgtAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E30D800, 0xFFBFFC00, szConstraints, InstName.FaddpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E30D800, 0xFFBFFC00, InstName.FaddpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E401400, 0xBFE0FC00, InstName.FaddpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20D400, 0xBFA0FC00, qszConstraints, InstName.FaddpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E401400, 0xBFE0FC00, InstName.FaddAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20D400, 0xBFA0FC00, qszConstraints, InstName.FaddAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E202800, 0xFFA0FC00, InstName.FaddFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE02800, 0xFFE0FC00, InstName.FaddFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E80E400, 0xBFA0EC00, sizeQsizeConstraints, InstName.FcaddAdvsimdVec, IsaVersion.v83, InstFlags.RdRnRmFpSimd),
+ new(0x2E40E400, 0xBFE0EC00, sizeQsizeConstraints, InstName.FcaddAdvsimdVec, IsaVersion.v83, InstFlags.RdRnRmFpSimd),
+ new(0x1E200410, 0xFFA00C10, InstName.FccmpeFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd),
+ new(0x1EE00410, 0xFFE00C10, InstName.FccmpeFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd),
+ new(0x1E200400, 0xFFA00C10, InstName.FccmpFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd),
+ new(0x1EE00400, 0xFFE00C10, InstName.FccmpFloat, IsaVersion.v80, InstFlags.RnRmNzcvSFpSimd),
+ new(0x5E402400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x5E20E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E402400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmeqAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmeqAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EF8D800, 0xFFFFFC00, InstName.FcmeqAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA0D800, 0xFFBFFC00, InstName.FcmeqAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF8D800, 0xBFFFFC00, InstName.FcmeqAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA0D800, 0xBFBFFC00, qszConstraints, InstName.FcmeqAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7E402400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7E20E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E402400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmgeAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmgeAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7EF8C800, 0xFFFFFC00, InstName.FcmgeAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EA0C800, 0xFFBFFC00, InstName.FcmgeAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF8C800, 0xBFFFFC00, InstName.FcmgeAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA0C800, 0xBFBFFC00, qszConstraints, InstName.FcmgeAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7EC02400, 0xFFE0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7EA0E400, 0xFFA0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2EC02400, 0xBFE0FC00, euacEuacEuacConstraints, InstName.FcmgtAdvsimdRegVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2EA0E400, 0xBFA0FC00, qszEuacEuacEuacConstraints, InstName.FcmgtAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EF8C800, 0xFFFFFC00, InstName.FcmgtAdvsimdZeroSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA0C800, 0xFFBFFC00, InstName.FcmgtAdvsimdZeroS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF8C800, 0xBFFFFC00, InstName.FcmgtAdvsimdZeroVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA0C800, 0xBFBFFC00, qszConstraints, InstName.FcmgtAdvsimdZeroV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F801000, 0xBF809400, sizeSizeSizelSizeqSizehqConstraints, InstName.FcmlaAdvsimdElt, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2F401000, 0xBFC09400, sizeSizeSizelSizeqSizehqConstraints, InstName.FcmlaAdvsimdElt, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E80C400, 0xBFA0E400, sizeQsizeConstraints, InstName.FcmlaAdvsimdVec, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E40C400, 0xBFE0E400, sizeQsizeConstraints, InstName.FcmlaAdvsimdVec, IsaVersion.v83, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x7EF8D800, 0xFFFFFC00, InstName.FcmleAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EA0D800, 0xFFBFFC00, InstName.FcmleAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF8D800, 0xBFFFFC00, InstName.FcmleAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA0D800, 0xBFBFFC00, qszConstraints, InstName.FcmleAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EF8E800, 0xFFFFFC00, InstName.FcmltAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA0E800, 0xFFBFFC00, InstName.FcmltAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF8E800, 0xBFFFFC00, InstName.FcmltAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA0E800, 0xBFBFFC00, qszConstraints, InstName.FcmltAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E202010, 0xFFA0FC17, InstName.FcmpeFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd),
+ new(0x1EE02010, 0xFFE0FC17, InstName.FcmpeFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd),
+ new(0x1E202000, 0xFFA0FC17, InstName.FcmpFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd),
+ new(0x1EE02000, 0xFFE0FC17, InstName.FcmpFloat, IsaVersion.v80, InstFlags.RnRmSFpSimd),
+ new(0x1E200C00, 0xFFA00C00, InstName.FcselFloat, IsaVersion.v80, InstFlags.RdRnRmNzcvFpSimd),
+ new(0x1EE00C00, 0xFFE00C00, InstName.FcselFloat, IsaVersion.v80, InstFlags.RdRnRmNzcvFpSimd),
+ new(0x5E79C800, 0xFFFFFC00, InstName.FcvtasAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5E21C800, 0xFFBFFC00, InstName.FcvtasAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E79C800, 0xBFFFFC00, InstName.FcvtasAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E21C800, 0xBFBFFC00, qszConstraints, InstName.FcvtasAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E240000, 0x7FBFFC00, InstName.FcvtasFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE40000, 0x7FFFFC00, InstName.FcvtasFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7E79C800, 0xFFFFFC00, InstName.FcvtauAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E21C800, 0xFFBFFC00, InstName.FcvtauAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E79C800, 0xBFFFFC00, InstName.FcvtauAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E21C800, 0xBFBFFC00, qszConstraints, InstName.FcvtauAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E250000, 0x7FBFFC00, InstName.FcvtauFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE50000, 0x7FFFFC00, InstName.FcvtauFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x0E217800, 0xBFBFFC00, InstName.FcvtlAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E79B800, 0xFFFFFC00, InstName.FcvtmsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5E21B800, 0xFFBFFC00, InstName.FcvtmsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E79B800, 0xBFFFFC00, InstName.FcvtmsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E21B800, 0xBFBFFC00, qszConstraints, InstName.FcvtmsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E300000, 0x7FBFFC00, InstName.FcvtmsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EF00000, 0x7FFFFC00, InstName.FcvtmsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7E79B800, 0xFFFFFC00, InstName.FcvtmuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E21B800, 0xFFBFFC00, InstName.FcvtmuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E79B800, 0xBFFFFC00, InstName.FcvtmuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E21B800, 0xBFBFFC00, qszConstraints, InstName.FcvtmuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E310000, 0x7FBFFC00, InstName.FcvtmuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EF10000, 0x7FFFFC00, InstName.FcvtmuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x5E79A800, 0xFFFFFC00, InstName.FcvtnsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5E21A800, 0xFFBFFC00, InstName.FcvtnsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E79A800, 0xBFFFFC00, InstName.FcvtnsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E21A800, 0xBFBFFC00, qszConstraints, InstName.FcvtnsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E200000, 0x7FBFFC00, InstName.FcvtnsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE00000, 0x7FFFFC00, InstName.FcvtnsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7E79A800, 0xFFFFFC00, InstName.FcvtnuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E21A800, 0xFFBFFC00, InstName.FcvtnuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E79A800, 0xBFFFFC00, InstName.FcvtnuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E21A800, 0xBFBFFC00, qszConstraints, InstName.FcvtnuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E210000, 0x7FBFFC00, InstName.FcvtnuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE10000, 0x7FFFFC00, InstName.FcvtnuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x0E216800, 0xBFBFFC00, InstName.FcvtnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x5EF9A800, 0xFFFFFC00, InstName.FcvtpsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA1A800, 0xFFBFFC00, InstName.FcvtpsAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF9A800, 0xBFFFFC00, InstName.FcvtpsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA1A800, 0xBFBFFC00, qszConstraints, InstName.FcvtpsAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E280000, 0x7FBFFC00, InstName.FcvtpsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE80000, 0x7FFFFC00, InstName.FcvtpsFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7EF9A800, 0xFFFFFC00, InstName.FcvtpuAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EA1A800, 0xFFBFFC00, InstName.FcvtpuAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF9A800, 0xBFFFFC00, InstName.FcvtpuAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA1A800, 0xBFBFFC00, qszConstraints, InstName.FcvtpuAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E290000, 0x7FBFFC00, InstName.FcvtpuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EE90000, 0x7FFFFC00, InstName.FcvtpuFloat, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7E216800, 0xFFBFFC00, szConstraints2, InstName.FcvtxnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2E216800, 0xBFBFFC00, szConstraints2, InstName.FcvtxnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x5F40FC00, 0xFFC0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F10FC00, 0xFFF0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F20FC00, 0xFFE0FC00, immhConstraints, InstName.FcvtzsAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F40FC00, 0xBFC0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F10FC00, 0xBFF0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F20FC00, 0xBFE0FC00, immhQimmhConstraints, InstName.FcvtzsAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EF9B800, 0xFFFFFC00, InstName.FcvtzsAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA1B800, 0xFFBFFC00, InstName.FcvtzsAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF9B800, 0xBFFFFC00, InstName.FcvtzsAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA1B800, 0xBFBFFC00, qszConstraints, InstName.FcvtzsAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E180000, 0x7FBF0000, sfscaleConstraints, InstName.FcvtzsFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1ED80000, 0x7FFF0000, sfscaleConstraints, InstName.FcvtzsFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1E380000, 0x7FBFFC00, InstName.FcvtzsFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EF80000, 0x7FFFFC00, InstName.FcvtzsFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x7F40FC00, 0xFFC0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7F10FC00, 0xFFF0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7F20FC00, 0xFFE0FC00, immhConstraints, InstName.FcvtzuAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F40FC00, 0xBFC0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F10FC00, 0xBFF0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F20FC00, 0xBFE0FC00, immhQimmhConstraints, InstName.FcvtzuAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7EF9B800, 0xFFFFFC00, InstName.FcvtzuAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EA1B800, 0xFFBFFC00, InstName.FcvtzuAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF9B800, 0xBFFFFC00, InstName.FcvtzuAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA1B800, 0xBFBFFC00, qszConstraints, InstName.FcvtzuAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E190000, 0x7FBF0000, sfscaleConstraints, InstName.FcvtzuFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1ED90000, 0x7FFF0000, sfscaleConstraints, InstName.FcvtzuFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1E390000, 0x7FBFFC00, InstName.FcvtzuFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1EF90000, 0x7FFFFC00, InstName.FcvtzuFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x1E224000, 0xFF3E7C00, ftypeopcFtypeopcFtypeopcFtypeopcFtypeOpcConstraints, InstName.FcvtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E403C00, 0xBFE0FC00, InstName.FdivAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20FC00, 0xBFA0FC00, qszConstraints, InstName.FdivAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E201800, 0xFFA0FC00, InstName.FdivFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE01800, 0xFFE0FC00, InstName.FdivFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E7E0000, 0xFFFFFC00, InstName.Fjcvtzs, IsaVersion.v83, InstFlags.RdRnSFpSimd),
+ new(0x1F000000, 0xFFA08000, InstName.FmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1FC00000, 0xFFE08000, InstName.FmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x5E30C800, 0xFFBFFC00, szConstraints, InstName.FmaxnmpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E30C800, 0xFFBFFC00, InstName.FmaxnmpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E400400, 0xBFE0FC00, InstName.FmaxnmpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20C400, 0xBFA0FC00, qszConstraints, InstName.FmaxnmpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E30C800, 0xBFFFFC00, InstName.FmaxnmvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x6E30C800, 0xFFFFFC00, InstName.FmaxnmvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E400400, 0xBFE0FC00, InstName.FmaxnmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20C400, 0xBFA0FC00, qszConstraints, InstName.FmaxnmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E206800, 0xFFA0FC00, InstName.FmaxnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE06800, 0xFFE0FC00, InstName.FmaxnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E30F800, 0xFFBFFC00, szConstraints, InstName.FmaxpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E30F800, 0xFFBFFC00, InstName.FmaxpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E403400, 0xBFE0FC00, InstName.FmaxpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20F400, 0xBFA0FC00, qszConstraints, InstName.FmaxpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E30F800, 0xBFFFFC00, InstName.FmaxvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x6E30F800, 0xFFFFFC00, InstName.FmaxvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E403400, 0xBFE0FC00, InstName.FmaxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20F400, 0xBFA0FC00, qszConstraints, InstName.FmaxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E204800, 0xFFA0FC00, InstName.FmaxFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE04800, 0xFFE0FC00, InstName.FmaxFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EB0C800, 0xFFBFFC00, szConstraints, InstName.FminnmpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EB0C800, 0xFFBFFC00, InstName.FminnmpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EC00400, 0xBFE0FC00, InstName.FminnmpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2EA0C400, 0xBFA0FC00, qszConstraints, InstName.FminnmpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0EB0C800, 0xBFFFFC00, InstName.FminnmvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x6EB0C800, 0xFFFFFC00, InstName.FminnmvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EC00400, 0xBFE0FC00, InstName.FminnmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0EA0C400, 0xBFA0FC00, qszConstraints, InstName.FminnmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E207800, 0xFFA0FC00, InstName.FminnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE07800, 0xFFE0FC00, InstName.FminnmFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EB0F800, 0xFFBFFC00, szConstraints, InstName.FminpAdvsimdPairHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EB0F800, 0xFFBFFC00, InstName.FminpAdvsimdPairSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EC03400, 0xBFE0FC00, InstName.FminpAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2EA0F400, 0xBFA0FC00, qszConstraints, InstName.FminpAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0EB0F800, 0xBFFFFC00, InstName.FminvAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x6EB0F800, 0xFFFFFC00, InstName.FminvAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EC03400, 0xBFE0FC00, InstName.FminAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0EA0F400, 0xBFA0FC00, qszConstraints, InstName.FminAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E205800, 0xFFA0FC00, InstName.FminFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE05800, 0xFFE0FC00, InstName.FminFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0F800000, 0xBFC0F400, szConstraints, InstName.FmlalAdvsimdEltFmlal, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2F808000, 0xBFC0F400, szConstraints, InstName.FmlalAdvsimdEltFmlal2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E20EC00, 0xBFE0FC00, szConstraints, InstName.FmlalAdvsimdVecFmlal, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E20CC00, 0xBFE0FC00, szConstraints, InstName.FmlalAdvsimdVecFmlal2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5F001000, 0xFFC0F400, InstName.FmlaAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5F801000, 0xFF80F400, szlConstraints, InstName.FmlaAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F001000, 0xBFC0F400, InstName.FmlaAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F801000, 0xBF80F400, szlQszConstraints, InstName.FmlaAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E400C00, 0xBFE0FC00, InstName.FmlaAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E20CC00, 0xBFA0FC00, qszConstraints, InstName.FmlaAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F804000, 0xBFC0F400, szConstraints, InstName.FmlslAdvsimdEltFmlsl, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2F80C000, 0xBFC0F400, szConstraints, InstName.FmlslAdvsimdEltFmlsl2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0EA0EC00, 0xBFE0FC00, szConstraints, InstName.FmlslAdvsimdVecFmlsl, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2EA0CC00, 0xBFE0FC00, szConstraints, InstName.FmlslAdvsimdVecFmlsl2, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5F005000, 0xFFC0F400, InstName.FmlsAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5F805000, 0xFF80F400, szlConstraints, InstName.FmlsAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F005000, 0xBFC0F400, InstName.FmlsAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F805000, 0xBF80F400, szlQszConstraints, InstName.FmlsAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0EC00C00, 0xBFE0FC00, InstName.FmlsAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0EA0CC00, 0xBFA0FC00, qszConstraints, InstName.FmlsAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F00FC00, 0xBFF8FC00, InstName.FmovAdvsimdPerHalf, IsaVersion.v82, InstFlags.RdFpSimd),
+ new(0x0F00F400, 0x9FF8FC00, qConstraints, InstName.FmovAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x1E204000, 0xFFBFFC00, InstName.FmovFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE04000, 0xFFFFFC00, InstName.FmovFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E260000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr),
+ new(0x9E660000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr),
+ new(0x9EAE0000, 0xFFFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr),
+ new(0x1EE60000, 0x7FFEFC00, sfftypermodeSfftypermodeConstraints, InstName.FmovFloatGen, IsaVersion.v80, InstFlags.RdRnSFpSimdFromToGpr),
+ new(0x1E201000, 0xFFA01FE0, InstName.FmovFloatImm, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x1EE01000, 0xFFE01FE0, InstName.FmovFloatImm, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x1F008000, 0xFFA08000, InstName.FmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1FC08000, 0xFFE08000, InstName.FmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x7F009000, 0xFFC0F400, InstName.FmulxAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x7F809000, 0xFF80F400, szlConstraints, InstName.FmulxAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2F009000, 0xBFC0F400, InstName.FmulxAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2F809000, 0xBF80F400, szlQszConstraints, InstName.FmulxAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E401C00, 0xFFE0FC00, InstName.FmulxAdvsimdVecSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x5E20DC00, 0xFFA0FC00, InstName.FmulxAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E401C00, 0xBFE0FC00, InstName.FmulxAdvsimdVecVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20DC00, 0xBFA0FC00, qszConstraints, InstName.FmulxAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5F009000, 0xFFC0F400, InstName.FmulAdvsimdElt2regScalarHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x5F809000, 0xFF80F400, szlConstraints, InstName.FmulAdvsimdElt2regScalarSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0F009000, 0xBFC0F400, InstName.FmulAdvsimdElt2regElementHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0F809000, 0xBF80F400, szlQszConstraints, InstName.FmulAdvsimdElt2regElementSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E401C00, 0xBFE0FC00, InstName.FmulAdvsimdVecHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E20DC00, 0xBFA0FC00, qszConstraints, InstName.FmulAdvsimdVecSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E200800, 0xFFA0FC00, InstName.FmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE00800, 0xFFE0FC00, InstName.FmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2EF8F800, 0xBFFFFC00, InstName.FnegAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA0F800, 0xBFBFFC00, qszConstraints, InstName.FnegAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E214000, 0xFFBFFC00, InstName.FnegFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE14000, 0xFFFFFC00, InstName.FnegFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1F200000, 0xFFA08000, InstName.FnmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1FE00000, 0xFFE08000, InstName.FnmaddFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1F208000, 0xFFA08000, InstName.FnmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1FE08000, 0xFFE08000, InstName.FnmsubFloat, IsaVersion.v80, InstFlags.RdRnRmRaFpSimd),
+ new(0x1E208800, 0xFFA0FC00, InstName.FnmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE08800, 0xFFE0FC00, InstName.FnmulFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EF9D800, 0xFFFFFC00, InstName.FrecpeAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA1D800, 0xFFBFFC00, InstName.FrecpeAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF9D800, 0xBFFFFC00, InstName.FrecpeAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA1D800, 0xBFBFFC00, qszConstraints, InstName.FrecpeAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E403C00, 0xFFE0FC00, InstName.FrecpsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x5E20FC00, 0xFFA0FC00, InstName.FrecpsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E403C00, 0xBFE0FC00, InstName.FrecpsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E20FC00, 0xBFA0FC00, qszConstraints, InstName.FrecpsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5EF9F800, 0xFFFFFC00, InstName.FrecpxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5EA1F800, 0xFFBFFC00, InstName.FrecpxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E21E800, 0xBFBFFC00, qszConstraints, InstName.Frint32xAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x1E28C000, 0xFFBFFC00, InstName.Frint32xFloat, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x0E21E800, 0xBFBFFC00, qszConstraints, InstName.Frint32zAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x1E284000, 0xFFBFFC00, InstName.Frint32zFloat, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x2E21F800, 0xBFBFFC00, qszConstraints, InstName.Frint64xAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x1E29C000, 0xFFBFFC00, InstName.Frint64xFloat, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x0E21F800, 0xBFBFFC00, qszConstraints, InstName.Frint64zAdvsimd, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x1E294000, 0xFFBFFC00, InstName.Frint64zFloat, IsaVersion.v85, InstFlags.RdRnFpSimd),
+ new(0x2E798800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintaAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E218800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintaAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E264000, 0xFFBFFC00, InstName.FrintaFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE64000, 0xFFFFFC00, InstName.FrintaFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF99800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintiAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA19800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintiAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E27C000, 0xFFBFFC00, InstName.FrintiFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE7C000, 0xFFFFFC00, InstName.FrintiFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E799800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintmAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E219800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintmAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E254000, 0xFFBFFC00, InstName.FrintmFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE54000, 0xFFFFFC00, InstName.FrintmFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E798800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintnAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E218800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintnAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E244000, 0xFFBFFC00, InstName.FrintnFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE44000, 0xFFFFFC00, InstName.FrintnFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF98800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintpAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA18800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintpAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E24C000, 0xFFBFFC00, InstName.FrintpFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE4C000, 0xFFFFFC00, InstName.FrintpFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E799800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintxAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E219800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintxAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E274000, 0xFFBFFC00, InstName.FrintxFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE74000, 0xFFFFFC00, InstName.FrintxFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EF99800, 0xBFFFFC00, uo1o2Constraints, InstName.FrintzAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0EA19800, 0xBFBFFC00, qszUo1o2Constraints, InstName.FrintzAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E25C000, 0xFFBFFC00, InstName.FrintzFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE5C000, 0xFFFFFC00, InstName.FrintzFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7EF9D800, 0xFFFFFC00, InstName.FrsqrteAdvsimdSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7EA1D800, 0xFFBFFC00, InstName.FrsqrteAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EF9D800, 0xBFFFFC00, InstName.FrsqrteAdvsimdVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA1D800, 0xBFBFFC00, qszConstraints, InstName.FrsqrteAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5EC03C00, 0xFFE0FC00, InstName.FrsqrtsAdvsimdSH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x5EA0FC00, 0xFFA0FC00, InstName.FrsqrtsAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0EC03C00, 0xBFE0FC00, InstName.FrsqrtsAdvsimdVH, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0EA0FC00, 0xBFA0FC00, qszConstraints, InstName.FrsqrtsAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2EF9F800, 0xBFFFFC00, InstName.FsqrtAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2EA1F800, 0xBFBFFC00, qszConstraints, InstName.FsqrtAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E21C000, 0xFFBFFC00, InstName.FsqrtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1EE1C000, 0xFFFFFC00, InstName.FsqrtFloat, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EC01400, 0xBFE0FC00, InstName.FsubAdvsimdHalf, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0EA0D400, 0xBFA0FC00, qszConstraints, InstName.FsubAdvsimdSingleAndDouble, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1E203800, 0xFFA0FC00, InstName.FsubFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x1EE03800, 0xFFE0FC00, InstName.FsubFloat, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xD503227F, 0xFFFFFFFF, InstName.Gcsb, IsaVersion.None, InstFlags.None),
+ new(0xD91F0C00, 0xFFFFFC00, InstName.Gcsstr, IsaVersion.None, InstFlags.RtReadRtRnSP),
+ new(0xD91F1C00, 0xFFFFFC00, InstName.Gcssttr, IsaVersion.None, InstFlags.RtReadRtRnSP),
+ new(0x9AC01400, 0xFFE0FC00, InstName.Gmi, IsaVersion.v85, InstFlags.None),
+ new(0xD503201F, 0xFFFFF01F, InstName.Hint, IsaVersion.v80, InstFlags.None),
+ new(0xD4400000, 0xFFE0001F, InstName.Hlt, IsaVersion.v80, InstFlags.None),
+ new(0xD4000002, 0xFFE0001F, InstName.Hvc, IsaVersion.v80, InstFlags.None),
+ new(0x6E000400, 0xFFE08400, imm5Constraints, InstName.InsAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x4E001C00, 0xFFE0FC00, imm5Constraints, InstName.InsAdvsimdGen, IsaVersion.v80, InstFlags.RdReadRdRnFpSimdFromGpr),
+ new(0x9AC01000, 0xFFE0FC00, InstName.Irg, IsaVersion.v85, InstFlags.None),
+ new(0xD50330DF, 0xFFFFF0FF, InstName.Isb, IsaVersion.v80, InstFlags.None),
+ new(0x0D40C000, 0xBFFFF000, sConstraints, InstName.Ld1rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DC0C000, 0xBFE0F000, sConstraints, InstName.Ld1rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C402000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C406000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C407000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C40A000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C406000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C407000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C40A000, 0xBFFFF000, InstName.Ld1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0CC02000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC06000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC07000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC0A000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC06000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC07000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0CC0A000, 0xBFE0F000, InstName.Ld1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D400000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld1AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DC00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld1AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D60C000, 0xBFFFF000, sConstraints, InstName.Ld2rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DE0C000, 0xBFE0F000, sConstraints, InstName.Ld2rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C408000, 0xBFFFF000, qsizeConstraints2, InstName.Ld2AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0CC08000, 0xBFE0F000, qsizeConstraints2, InstName.Ld2AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D600000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld2AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DE00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld2AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D40E000, 0xBFFFF000, sConstraints, InstName.Ld3rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DC0E000, 0xBFE0F000, sConstraints, InstName.Ld3rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C404000, 0xBFFFF000, qsizeConstraints2, InstName.Ld3AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0CC04000, 0xBFE0F000, qsizeConstraints2, InstName.Ld3AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D402000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld3AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DC02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld3AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D60E000, 0xBFFFF000, sConstraints, InstName.Ld4rAdvsimdAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DE0E000, 0xBFE0F000, sConstraints, InstName.Ld4rAdvsimdAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C400000, 0xBFFFF000, qsizeConstraints2, InstName.Ld4AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0CC00000, 0xBFE0F000, qsizeConstraints2, InstName.Ld4AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D602000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld4AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DE02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ld4AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0xF83FD000, 0xFFFFFC00, rtRtConstraints, InstName.Ld64b, IsaVersion.v87, InstFlags.RtRnSP),
+ new(0xB8200000, 0xBF20FC00, InstName.Ldadd, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38200000, 0xFF20FC00, InstName.Ldaddb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78200000, 0xFF20FC00, InstName.Ldaddh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x0D418400, 0xBFFFFC00, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Ldap1AdvsimdSngl, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0xB8BFC000, 0xBFFFFC00, InstName.LdaprBaseRegister, IsaVersion.v83, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x99C00800, 0xBFFFFC00, InstName.LdaprPostIndexed, IsaVersion.v82, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x38BFC000, 0xFFFFFC00, InstName.Ldaprb, IsaVersion.v83, InstFlags.RtRnSP),
+ new(0x78BFC000, 0xFFFFFC00, InstName.Ldaprh, IsaVersion.v83, InstFlags.RtRnSP),
+ new(0x19400000, 0xFFE00C00, InstName.Ldapurb, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x59400000, 0xFFE00C00, InstName.Ldapurh, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x19800000, 0xFFA00C00, InstName.Ldapursb, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x59800000, 0xFFA00C00, InstName.Ldapursh, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x99800000, 0xFFE00C00, InstName.Ldapursw, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x1D400800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdapurFpsimd, IsaVersion.v82, InstFlags.RtRnSPFpSimd, AddressForm.BasePlusOffset),
+ new(0x99400000, 0xBFE00C00, InstName.LdapurGen, IsaVersion.v84, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x88DFFC00, 0xBFFFFC00, InstName.Ldar, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x08DFFC00, 0xFFFFFC00, InstName.Ldarb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x48DFFC00, 0xFFFFFC00, InstName.Ldarh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x887F8000, 0xBFFF8000, InstName.Ldaxp, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.BaseRegister),
+ new(0x885FFC00, 0xBFFFFC00, InstName.Ldaxr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x085FFC00, 0xFFFFFC00, InstName.Ldaxrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x485FFC00, 0xFFFFFC00, InstName.Ldaxrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0xB8201000, 0xBF20FC00, InstName.Ldclr, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38201000, 0xFF20FC00, InstName.Ldclrb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78201000, 0xFF20FC00, InstName.Ldclrh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x19201000, 0xFF20FC00, rtRt2Constraints, InstName.Ldclrp, IsaVersion.None, InstFlags.RtRt2RnSP),
+ new(0xB8202000, 0xBF20FC00, InstName.Ldeor, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38202000, 0xFF20FC00, InstName.Ldeorb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78202000, 0xFF20FC00, InstName.Ldeorh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0xD9600000, 0xFFE00C00, InstName.Ldg, IsaVersion.v85, InstFlags.None),
+ new(0xD9E00000, 0xFFFFFC00, InstName.Ldgm, IsaVersion.v85, InstFlags.None),
+ new(0x99400800, 0xBFE0EC00, InstName.Ldiapp, IsaVersion.v82, InstFlags.RtRt2RnSP),
+ new(0x88DF7C00, 0xBFFFFC00, InstName.Ldlar, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x08DF7C00, 0xFFFFFC00, InstName.Ldlarb, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x48DF7C00, 0xFFFFFC00, InstName.Ldlarh, IsaVersion.v81, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x2C400000, 0x3FC00000, opcConstraints, InstName.LdnpFpsimd, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimd, AddressForm.SignedScaled),
+ new(0x28400000, 0x7FC00000, opcConstraints2, InstName.LdnpGen, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled),
+ new(0x68C00000, 0xFFC00000, InstName.LdpswPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PostIndexed),
+ new(0x69C00000, 0xFFC00000, InstName.LdpswPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PreIndexed),
+ new(0x69400000, 0xFFC00000, InstName.LdpswSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled),
+ new(0x2CC00000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimdMemWBack, AddressForm.PostIndexed),
+ new(0x2DC00000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimdMemWBack, AddressForm.PreIndexed),
+ new(0x2D400000, 0x3FC00000, opcConstraints, InstName.LdpFpsimdSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSPFpSimd, AddressForm.SignedScaled),
+ new(0x28C00000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenPostIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PostIndexed),
+ new(0x29C00000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenPreIndexed, IsaVersion.v80, InstFlags.RtRt2RnSPMemWBack, AddressForm.PreIndexed),
+ new(0x29400000, 0x7FC00000, opclOpcConstraints, InstName.LdpGenSignedScaledOffset, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.SignedScaled),
+ new(0xF8200400, 0xFF200400, InstName.Ldra, IsaVersion.v83, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x38400400, 0xFFE00C00, InstName.LdrbImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x38400C00, 0xFFE00C00, InstName.LdrbImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x39400000, 0xFFC00000, InstName.LdrbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x38600800, 0xFFE00C00, optionConstraints, InstName.LdrbReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0x78400400, 0xFFE00C00, InstName.LdrhImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x78400C00, 0xFFE00C00, InstName.LdrhImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x79400000, 0xFFC00000, InstName.LdrhImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x78600800, 0xFFE00C00, optionConstraints, InstName.LdrhReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0x38800400, 0xFFA00C00, InstName.LdrsbImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x38800C00, 0xFFA00C00, InstName.LdrsbImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x39800000, 0xFF800000, InstName.LdrsbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x38A00800, 0xFFA00C00, optionConstraints, InstName.LdrsbReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0x78800400, 0xFFA00C00, InstName.LdrshImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x78800C00, 0xFFA00C00, InstName.LdrshImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x79800000, 0xFF800000, InstName.LdrshImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x78A00800, 0xFFA00C00, optionConstraints, InstName.LdrshReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0xB8800400, 0xFFE00C00, InstName.LdrswImmPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0xB8800C00, 0xFFE00C00, InstName.LdrswImmPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0xB9800000, 0xFFC00000, InstName.LdrswImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x98000000, 0xFF000000, InstName.LdrswLit, IsaVersion.v80, InstFlags.Rt, AddressForm.Literal),
+ new(0xB8A00800, 0xFFE00C00, optionConstraints, InstName.LdrswReg, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0x3C400400, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtRnSPFpSimdMemWBack, AddressForm.PostIndexed),
+ new(0x3C400C00, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtRnSPFpSimdMemWBack, AddressForm.PreIndexed),
+ new(0x3D400000, 0x3F400000, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdrImmFpsimdUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.UnsignedScaled),
+ new(0xB8400400, 0xBFE00C00, InstName.LdrImmGenPostIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0xB8400C00, 0xBFE00C00, InstName.LdrImmGenPreIndexed, IsaVersion.v80, InstFlags.RtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0xB9400000, 0xBFC00000, InstName.LdrImmGenUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.UnsignedScaled),
+ new(0x1C000000, 0x3F000000, opcConstraints, InstName.LdrLitFpsimd, IsaVersion.v80, InstFlags.RtFpSimd, AddressForm.Literal),
+ new(0x18000000, 0xBF000000, InstName.LdrLitGen, IsaVersion.v80, InstFlags.Rt, AddressForm.Literal),
+ new(0x3C600800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeOptionConstraints, InstName.LdrRegFpsimd, IsaVersion.v80, InstFlags.RtRnSPRmFpSimd, AddressForm.OffsetReg),
+ new(0xB8600800, 0xBFE00C00, optionConstraints, InstName.LdrRegGen, IsaVersion.v80, InstFlags.RtRnSPRm, AddressForm.OffsetReg),
+ new(0xB8203000, 0xBF20FC00, InstName.Ldset, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38203000, 0xFF20FC00, InstName.Ldsetb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78203000, 0xFF20FC00, InstName.Ldseth, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x19203000, 0xFF20FC00, rtRt2Constraints, InstName.Ldsetp, IsaVersion.None, InstFlags.RtRt2RnSP),
+ new(0xB8204000, 0xBF20FC00, InstName.Ldsmax, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38204000, 0xFF20FC00, InstName.Ldsmaxb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78204000, 0xFF20FC00, InstName.Ldsmaxh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0xB8205000, 0xBF20FC00, InstName.Ldsmin, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38205000, 0xFF20FC00, InstName.Ldsminb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78205000, 0xFF20FC00, InstName.Ldsminh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0xB8400800, 0xBFE00C00, InstName.Ldtr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x38400800, 0xFFE00C00, InstName.Ldtrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x78400800, 0xFFE00C00, InstName.Ldtrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x38800800, 0xFFA00C00, InstName.Ldtrsb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x78800800, 0xFFA00C00, InstName.Ldtrsh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0xB8800800, 0xFFE00C00, InstName.Ldtrsw, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0xB8206000, 0xBF20FC00, InstName.Ldumax, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38206000, 0xFF20FC00, InstName.Ldumaxb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78206000, 0xFF20FC00, InstName.Ldumaxh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0xB8207000, 0xBF20FC00, InstName.Ldumin, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38207000, 0xFF20FC00, InstName.Lduminb, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x78207000, 0xFF20FC00, InstName.Lduminh, IsaVersion.v81, InstFlags.RtRnSPRs),
+ new(0x38400000, 0xFFE00C00, InstName.Ldurb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x78400000, 0xFFE00C00, InstName.Ldurh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x38800000, 0xFFA00C00, InstName.Ldursb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x78800000, 0xFFA00C00, InstName.Ldursh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0xB8800000, 0xFFE00C00, InstName.Ldursw, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x3C400000, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.LdurFpsimd, IsaVersion.v80, InstFlags.RtRnSPFpSimd, AddressForm.BasePlusOffset),
+ new(0xB8400000, 0xBFE00C00, InstName.LdurGen, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BasePlusOffset),
+ new(0x887F0000, 0xBFFF8000, InstName.Ldxp, IsaVersion.v80, InstFlags.RtRt2RnSP, AddressForm.BaseRegister),
+ new(0x885F7C00, 0xBFFFFC00, InstName.Ldxr, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x085F7C00, 0xFFFFFC00, InstName.Ldxrb, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x485F7C00, 0xFFFFFC00, InstName.Ldxrh, IsaVersion.v80, InstFlags.RtRnSP, AddressForm.BaseRegister),
+ new(0x1AC02000, 0x7FE0FC00, InstName.Lslv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x1AC02400, 0x7FE0FC00, InstName.Lsrv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x1B000000, 0x7FE08000, InstName.Madd, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x2F000000, 0xBF00F400, sizeSizeConstraints, InstName.MlaAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E209400, 0xBF20FC00, sizeConstraints, InstName.MlaAdvsimdVec, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2F004000, 0xBF00F400, sizeSizeConstraints, InstName.MlsAdvsimdElt, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E209400, 0xBF20FC00, sizeConstraints, InstName.MlsAdvsimdVec, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0F000400, 0x9FF80C00, cmodeopqConstraints, InstName.MoviAdvsimd, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x72800000, 0x7F800000, sfhwConstraints, InstName.Movk, IsaVersion.v80, InstFlags.RdReadRd),
+ new(0x12800000, 0x7F800000, sfhwConstraints, InstName.Movn, IsaVersion.v80, InstFlags.Rd),
+ new(0x52800000, 0x7F800000, sfhwConstraints, InstName.Movz, IsaVersion.v80, InstFlags.Rd),
+ new(0xD5700000, 0xFFF00000, rtConstraints, InstName.Mrrs, IsaVersion.None, InstFlags.RtReadRt),
+ new(0xD5300000, 0xFFF00000, InstName.Mrs, IsaVersion.v80, InstFlags.Rt),
+ new(0xD5500000, 0xFFF00000, rtConstraints, InstName.Msrr, IsaVersion.None, InstFlags.RtReadRt),
+ new(0xD500401F, 0xFFF8F01F, InstName.MsrImm, IsaVersion.v80, InstFlags.None),
+ new(0xD5100000, 0xFFF00000, InstName.MsrReg, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0x1B008000, 0x7FE08000, InstName.Msub, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x0F008000, 0xBF00F400, sizeSizeConstraints, InstName.MulAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E209C00, 0xBF20FC00, usizeUsizeUsizeSizeConstraints, InstName.MulAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2F000400, 0xBFF80C00, cmodeopqConstraints, InstName.MvniAdvsimd, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x7EE0B800, 0xFFFFFC00, InstName.NegAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E20B800, 0xBF3FFC00, qsizeConstraints, InstName.NegAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0xD503201F, 0xFFFFFFFF, InstName.Nop, IsaVersion.v80, InstFlags.None),
+ new(0x2E205800, 0xBFFFFC00, InstName.NotAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0EE01C00, 0xBFE0FC00, InstName.OrnAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2A200000, 0x7F200000, sfimm6Constraints, InstName.OrnLogShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x0F001400, 0xBFF81C00, InstName.OrrAdvsimdImm, IsaVersion.v80, InstFlags.RdFpSimd),
+ new(0x0EA01C00, 0xBFE0FC00, InstName.OrrAdvsimdReg, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x32000000, 0x7F800000, nimmsNimmsNimmsNimmsNimmsNimmsNimmsNimmsSfnConstraints, InstName.OrrLogImm, IsaVersion.v80, InstFlags.RdSPRn),
+ new(0x2A000000, 0x7F200000, sfimm6Constraints, InstName.OrrLogShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xDAC10800, 0xFFFFDC00, InstName.Pacda, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xDAC10C00, 0xFFFFDC00, InstName.Pacdb, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0x9AC03000, 0xFFE0FC00, InstName.Pacga, IsaVersion.v83, InstFlags.RdRnRm),
+ new(0xDAC10000, 0xFFFFDC00, InstName.PaciaGeneral, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xD503211F, 0xFFFFFDDF, InstName.PaciaSystem, IsaVersion.v83, InstFlags.None),
+ new(0xDAC10400, 0xFFFFDC00, InstName.PacibGeneral, IsaVersion.v83, InstFlags.RdRnSP),
+ new(0xD503215F, 0xFFFFFDDF, InstName.PacibSystem, IsaVersion.v83, InstFlags.None),
+ new(0x0E20E000, 0xBFE0FC00, sizeSizeConstraints2, InstName.PmullAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0EE0E000, 0xBFE0FC00, sizeSizeConstraints2, InstName.PmullAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E209C00, 0xBF20FC00, usizeUsizeUsizeSizeConstraints, InstName.PmulAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xF9800000, 0xFFC00000, InstName.PrfmImm, IsaVersion.v80, InstFlags.RnSP, AddressForm.UnsignedScaled),
+ new(0xD8000000, 0xFF000000, InstName.PrfmLit, IsaVersion.v80, InstFlags.None, AddressForm.Literal),
+ new(0xF8A04800, 0xFFE04C00, rtConstraints2, InstName.PrfmReg, IsaVersion.v80, InstFlags.RnSPRm, AddressForm.OffsetReg),
+ new(0xF8800000, 0xFFE00C00, InstName.Prfum, IsaVersion.v80, InstFlags.RnSP, AddressForm.BasePlusOffset),
+ new(0xD503223F, 0xFFFFFFFF, InstName.Psb, IsaVersion.v82, InstFlags.None),
+ new(0x2E204000, 0xBF20FC00, sizeConstraints, InstName.RaddhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0xCE608C00, 0xFFE0FC00, InstName.Rax1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x2E605800, 0xBFFFFC00, InstName.RbitAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5AC00000, 0x7FFFFC00, InstName.RbitInt, IsaVersion.v80, InstFlags.RdRn),
+ new(0x19200800, 0xFF20FC00, InstName.Rcwcas, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x19200C00, 0xFF20FC00, rsRtConstraints, InstName.Rcwcasp, IsaVersion.None, InstFlags.RtReadRtRnSPRsS),
+ new(0x38209000, 0xFF20FC00, InstName.Rcwclr, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x19209000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwclrp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0x59200800, 0xFF20FC00, InstName.Rcwscas, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x59200C00, 0xFF20FC00, rsRtConstraints, InstName.Rcwscasp, IsaVersion.None, InstFlags.RtReadRtRnSPRsS),
+ new(0x78209000, 0xFF20FC00, InstName.Rcwsclr, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x59209000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsclrp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0x3820B000, 0xFF20FC00, InstName.Rcwset, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x1920B000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsetp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0x7820B000, 0xFF20FC00, InstName.Rcwsset, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x5920B000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwssetp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0x7820A000, 0xFF20FC00, InstName.Rcwsswp, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x5920A000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwsswpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0x3820A000, 0xFF20FC00, InstName.Rcwswp, IsaVersion.v89, InstFlags.RtReadRtRnSPRsS),
+ new(0x1920A000, 0xFF20FC00, rtRt2Constraints, InstName.Rcwswpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSPS),
+ new(0xD65F0000, 0xFFFFFC1F, InstName.Ret, IsaVersion.v80, InstFlags.Rn),
+ new(0xD65F0BFF, 0xFFFFFBFF, InstName.Reta, IsaVersion.v83, InstFlags.None),
+ new(0x5AC00800, 0x7FFFF800, sfopcConstraints, InstName.Rev, IsaVersion.v80, InstFlags.RdRn),
+ new(0x0E201800, 0xBF3FFC00, sizeSizeSizeConstraints, InstName.Rev16Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5AC00400, 0x7FFFFC00, InstName.Rev16Int, IsaVersion.v80, InstFlags.RdRn),
+ new(0x2E200800, 0xBF3FFC00, sizeSizeConstraints3, InstName.Rev32Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0xDAC00800, 0xFFFFFC00, sfConstraints, InstName.Rev32Int, IsaVersion.v80, InstFlags.RdRn),
+ new(0x0E200800, 0xBF3FFC00, sizeConstraints, InstName.Rev64Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0xBA000400, 0xFFE07C10, InstName.Rmif, IsaVersion.v84, InstFlags.RnC),
+ new(0x1AC02C00, 0x7FE0FC00, InstName.Rorv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0xF8A04818, 0xFFE04C18, InstName.RprfmReg, IsaVersion.v80, InstFlags.RnSPRm, AddressForm.OffsetReg),
+ new(0x0F008C00, 0xBF80FC00, immhImmhConstraints, InstName.RshrnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2E206000, 0xBF20FC00, sizeConstraints, InstName.RsubhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E205000, 0xBF20FC00, sizeConstraints, InstName.SabalAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E207C00, 0xBF20FC00, sizeConstraints, InstName.SabaAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E207000, 0xBF20FC00, sizeConstraints, InstName.SabdlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E207400, 0xBF20FC00, sizeConstraints, InstName.SabdAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E206800, 0xBF3FFC00, sizeConstraints, InstName.SadalpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x0E202800, 0xBF3FFC00, sizeConstraints, InstName.SaddlpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x0E303800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SaddlvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E200000, 0xBF20FC00, sizeConstraints, InstName.SaddlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E201000, 0xBF20FC00, sizeConstraints, InstName.SaddwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xD50330FF, 0xFFFFFFFF, InstName.Sb, IsaVersion.v85, InstFlags.None),
+ new(0x5A000000, 0x7FE0FC00, InstName.Sbc, IsaVersion.v80, InstFlags.RdRnRmC),
+ new(0x7A000000, 0x7FE0FC00, InstName.Sbcs, IsaVersion.v80, InstFlags.RdRnRmCS),
+ new(0x13000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Sbfm, IsaVersion.v80, InstFlags.RdRn),
+ new(0x5F40E400, 0xFFC0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F10E400, 0xFFF0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F20E400, 0xFFE0FC00, immhConstraints, InstName.ScvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F40E400, 0xBFC0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F10E400, 0xBFF0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F20E400, 0xBFE0FC00, immhQimmhConstraints, InstName.ScvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E79D800, 0xFFFFFC00, InstName.ScvtfAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x5E21D800, 0xFFBFFC00, InstName.ScvtfAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E79D800, 0xBFFFFC00, InstName.ScvtfAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x0E21D800, 0xBFBFFC00, qszConstraints, InstName.ScvtfAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E020000, 0x7FBF0000, sfscaleConstraints, InstName.ScvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1EC20000, 0x7FFF0000, sfscaleConstraints, InstName.ScvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1E220000, 0x7FBFFC00, InstName.ScvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1EE20000, 0x7FFFFC00, InstName.ScvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1AC00C00, 0x7FE0FC00, InstName.Sdiv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x0F80E000, 0xBFC0F400, InstName.SdotAdvsimdElt, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E809400, 0xBFE0FC00, InstName.SdotAdvsimdVec, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x3A00080D, 0xFFFFBC1F, InstName.Setf, IsaVersion.v84, InstFlags.RnC),
+ new(0x1DC00400, 0x3FE03C00, InstName.Setgp, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1DC02400, 0x3FE03C00, InstName.Setgpn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1DC01400, 0x3FE03C00, InstName.Setgpt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x1DC03400, 0x3FE03C00, InstName.Setgptn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19C00400, 0x3FE03C00, InstName.Setp, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19C02400, 0x3FE03C00, InstName.Setpn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19C01400, 0x3FE03C00, InstName.Setpt, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0x19C03400, 0x3FE03C00, InstName.Setptn, IsaVersion.v88, InstFlags.RdRnRsS),
+ new(0xD503209F, 0xFFFFFFFF, InstName.Sev, IsaVersion.v80, InstFlags.None),
+ new(0xD50320BF, 0xFFFFFFFF, InstName.Sevl, IsaVersion.v80, InstFlags.None),
+ new(0x5E000000, 0xFFE0FC00, InstName.Sha1cAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E280800, 0xFFFFFC00, InstName.Sha1hAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E002000, 0xFFE0FC00, InstName.Sha1mAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E001000, 0xFFE0FC00, InstName.Sha1pAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E003000, 0xFFE0FC00, InstName.Sha1su0Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E281800, 0xFFFFFC00, InstName.Sha1su1Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E005000, 0xFFE0FC00, InstName.Sha256h2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E004000, 0xFFE0FC00, InstName.Sha256hAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E282800, 0xFFFFFC00, InstName.Sha256su0Advsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E006000, 0xFFE0FC00, InstName.Sha256su1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xCE608400, 0xFFE0FC00, InstName.Sha512h2Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE608000, 0xFFE0FC00, InstName.Sha512hAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCEC08000, 0xFFFFFC00, InstName.Sha512su0Advsimd, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0xCE608800, 0xFFE0FC00, InstName.Sha512su1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0x0E200400, 0xBF20FC00, sizeConstraints, InstName.ShaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E213800, 0xBF3FFC00, sizeConstraints, InstName.ShllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F405400, 0xFFC0FC00, immhConstraints, InstName.ShlAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F005400, 0xBF80FC00, immhQimmhConstraints, InstName.ShlAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F008400, 0xBF80FC00, immhImmhConstraints, InstName.ShrnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x0E202400, 0xBF20FC00, sizeConstraints, InstName.ShsubAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7F405400, 0xFFC0FC00, immhConstraints, InstName.SliAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2F005400, 0xBF80FC00, immhQimmhConstraints, InstName.SliAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0xCE60C000, 0xFFE0FC00, InstName.Sm3partw1Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE60C400, 0xFFE0FC00, InstName.Sm3partw2Advsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE400000, 0xFFE08000, InstName.Sm3ss1Advsimd, IsaVersion.v82, InstFlags.RdRnRmRaFpSimd),
+ new(0xCE408000, 0xFFE0CC00, InstName.Sm3tt1aAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE408400, 0xFFE0CC00, InstName.Sm3tt1bAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE408800, 0xFFE0CC00, InstName.Sm3tt2aAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE408C00, 0xFFE0CC00, InstName.Sm3tt2bAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCE60C800, 0xFFE0FC00, InstName.Sm4ekeyAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xCEC08400, 0xFFFFFC00, InstName.Sm4eAdvsimd, IsaVersion.v82, InstFlags.RdReadRdRnFpSimd),
+ new(0x9B200000, 0xFFE08000, InstName.Smaddl, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x0E20A400, 0xBF20FC00, sizeConstraints, InstName.SmaxpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E30A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SmaxvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E206400, 0xBF20FC00, sizeConstraints, InstName.SmaxAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x11C00000, 0x7FFC0000, InstName.SmaxImm, IsaVersion.v89, InstFlags.RdRn),
+ new(0x1AC06000, 0x7FE0FC00, InstName.SmaxReg, IsaVersion.v89, InstFlags.RdRnRm),
+ new(0xD4000003, 0xFFE0001F, InstName.Smc, IsaVersion.v80, InstFlags.None),
+ new(0x0E20AC00, 0xBF20FC00, sizeConstraints, InstName.SminpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E31A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.SminvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E206C00, 0xBF20FC00, sizeConstraints, InstName.SminAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x11C80000, 0x7FFC0000, InstName.SminImm, IsaVersion.v89, InstFlags.RdRn),
+ new(0x1AC06800, 0x7FE0FC00, InstName.SminReg, IsaVersion.v89, InstFlags.RdRnRm),
+ new(0x0F002000, 0xBF00F400, sizeSizeConstraints, InstName.SmlalAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E208000, 0xBF20FC00, sizeConstraints, InstName.SmlalAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0F006000, 0xBF00F400, sizeSizeConstraints, InstName.SmlslAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E20A000, 0xBF20FC00, sizeConstraints, InstName.SmlslAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x4E80A400, 0xFFE0FC00, InstName.SmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x0E012C00, 0xBFE1FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x0E022C00, 0xBFE3FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x4E042C00, 0xFFE7FC00, InstName.SmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x9B208000, 0xFFE08000, InstName.Smsubl, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x9B407C00, 0xFFE0FC00, InstName.Smulh, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x0F00A000, 0xBF00F400, sizeSizeConstraints, InstName.SmullAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E20C000, 0xBF20FC00, sizeConstraints, InstName.SmullAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E207800, 0xFF3FFC00, InstName.SqabsAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x0E207800, 0xBF3FFC00, qsizeConstraints, InstName.SqabsAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x5E200C00, 0xFF20FC00, InstName.SqaddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E200C00, 0xBF20FC00, qsizeConstraints, InstName.SqaddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F003000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmlalAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0F003000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmlalAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5E209000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmlalAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E209000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmlalAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F007000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmlslAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0F007000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmlslAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5E20B000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmlslAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E20B000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmlslAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F00C000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmulhAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0F00C000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmulhAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5E20B400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqdmulhAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E20B400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqdmulhAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F00B000, 0xFF00F400, sizeSizeConstraints, InstName.SqdmullAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0F00B000, 0xBF00F400, sizeSizeConstraints, InstName.SqdmullAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5E20D000, 0xFF20FC00, sizeSizeConstraints, InstName.SqdmullAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E20D000, 0xBF20FC00, sizeSizeConstraints, InstName.SqdmullAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7E207800, 0xFF3FFC00, InstName.SqnegAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x2E207800, 0xBF3FFC00, qsizeConstraints, InstName.SqnegAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x7F00D000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmlahAdvsimdElt2regScalar, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x2F00D000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmlahAdvsimdElt2regElement, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x7E008400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmlahAdvsimdVecS, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x2E008400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmlahAdvsimdVecV, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x7F00F000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmlshAdvsimdElt2regScalar, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x2F00F000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmlshAdvsimdElt2regElement, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x7E008C00, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmlshAdvsimdVecS, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x2E008C00, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmlshAdvsimdVecV, IsaVersion.v81, InstFlags.RdReadRdRnRmQcFpSimd),
+ new(0x5F00D000, 0xFF00F400, sizeSizeConstraints, InstName.SqrdmulhAdvsimdElt2regScalar, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0F00D000, 0xBF00F400, sizeSizeConstraints, InstName.SqrdmulhAdvsimdElt2regElement, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7E20B400, 0xFF20FC00, sizeSizeConstraints4, InstName.SqrdmulhAdvsimdVecS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x2E20B400, 0xBF20FC00, sizeSizeConstraints4, InstName.SqrdmulhAdvsimdVecV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5E205C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SqrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E205C00, 0xBF20FC00, qsizeConstraints, InstName.SqrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F009C00, 0xFF80FC00, immhImmhConstraints, InstName.SqrshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0F009C00, 0xBF80FC00, immhImmhConstraints, InstName.SqrshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7F008C00, 0xFF80FC00, immhImmhConstraints, InstName.SqrshrunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2F008C00, 0xBF80FC00, immhImmhConstraints, InstName.SqrshrunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7F006400, 0xFF80FC00, immhOpuConstraints, InstName.SqshluAdvsimdS, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x2F006400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.SqshluAdvsimdV, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x5F007400, 0xFF80FC00, immhOpuConstraints, InstName.SqshlAdvsimdImmS, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x0F007400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.SqshlAdvsimdImmV, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x5E204C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SqshlAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E204C00, 0xBF20FC00, qsizeConstraints, InstName.SqshlAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5F009400, 0xFF80FC00, immhImmhConstraints, InstName.SqshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0F009400, 0xBF80FC00, immhImmhConstraints, InstName.SqshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7F008400, 0xFF80FC00, immhImmhConstraints, InstName.SqshrunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2F008400, 0xBF80FC00, immhImmhConstraints, InstName.SqshrunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x5E202C00, 0xFF20FC00, InstName.SqsubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x0E202C00, 0xBF20FC00, qsizeConstraints, InstName.SqsubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x5E214800, 0xFF3FFC00, sizeConstraints, InstName.SqxtnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0E214800, 0xBF3FFC00, sizeConstraints, InstName.SqxtnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7E212800, 0xFF3FFC00, sizeConstraints, InstName.SqxtunAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2E212800, 0xBF3FFC00, sizeConstraints, InstName.SqxtunAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0E201400, 0xBF20FC00, sizeConstraints, InstName.SrhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7F404400, 0xFFC0FC00, immhConstraints, InstName.SriAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2F004400, 0xBF80FC00, immhQimmhConstraints, InstName.SriAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x5E205400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E205400, 0xBF20FC00, qsizeConstraints, InstName.SrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5F402400, 0xFFC0FC00, immhConstraints, InstName.SrshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F002400, 0xBF80FC00, immhQimmhConstraints, InstName.SrshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F403400, 0xFFC0FC00, immhConstraints, InstName.SrsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F003400, 0xBF80FC00, immhQimmhConstraints, InstName.SrsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F00A400, 0xBF80FC00, immhImmhConstraints, InstName.SshllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5E204400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.SshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E204400, 0xBF20FC00, qsizeConstraints, InstName.SshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x5F400400, 0xFFC0FC00, immhConstraints, InstName.SshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F000400, 0xBF80FC00, immhQimmhConstraints, InstName.SshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x5F401400, 0xFFC0FC00, immhConstraints, InstName.SsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F001400, 0xBF80FC00, immhQimmhConstraints, InstName.SsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0E202000, 0xBF20FC00, sizeConstraints, InstName.SsublAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E203000, 0xBF20FC00, sizeConstraints, InstName.SsubwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0C002000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C006000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C007000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C00A000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C006000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C007000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C00A000, 0xBFFFF000, InstName.St1AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C802000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C806000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C807000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C80A000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C806000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C807000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C80A000, 0xBFE0F000, InstName.St1AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D000000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St1AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0D800000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St1AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0xD9A00400, 0xFFE00C00, InstName.St2gPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed),
+ new(0xD9A00C00, 0xFFE00C00, InstName.St2gPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed),
+ new(0xD9A00800, 0xFFE00C00, InstName.St2gSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled),
+ new(0x0C008000, 0xBFFFF000, qsizeConstraints2, InstName.St2AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C808000, 0xBFE0F000, qsizeConstraints2, InstName.St2AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D200000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St2AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DA00000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St2AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C004000, 0xBFFFF000, qsizeConstraints2, InstName.St3AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C804000, 0xBFE0F000, qsizeConstraints2, InstName.St3AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D002000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St3AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0D802000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St3AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0C000000, 0xBFFFF000, qsizeConstraints2, InstName.St4AdvsimdMultAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0C800000, 0xBFE0F000, qsizeConstraints2, InstName.St4AdvsimdMultAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0x0D202000, 0xBFFF2000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St4AdvsimdSnglAsNoPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x0DA02000, 0xBFE02000, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.St4AdvsimdSnglAsPostIndex, IsaVersion.v80, InstFlags.RtSeqReadRtRnSPRmFpSimdMemWBack, AddressForm.StructPostIndexedReg),
+ new(0xF83F9000, 0xFFFFFC00, rtRtConstraints, InstName.St64b, IsaVersion.v87, InstFlags.RtReadRtRnSP),
+ new(0xF820B000, 0xFFE0FC00, rtRtConstraints, InstName.St64bv, IsaVersion.v87, InstFlags.RtReadRtRnSPRs),
+ new(0xF820A000, 0xFFE0FC00, rtRtConstraints, InstName.St64bv0, IsaVersion.v87, InstFlags.RtReadRtRnSPRs),
+ new(0xD9200400, 0xFFE00C00, InstName.StgPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed),
+ new(0xD9200C00, 0xFFE00C00, InstName.StgPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed),
+ new(0xD9200800, 0xFFE00C00, InstName.StgSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled),
+ new(0xD9A00000, 0xFFFFFC00, InstName.Stgm, IsaVersion.v85, InstFlags.None),
+ new(0x68800000, 0xFFC00000, InstName.StgpPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed),
+ new(0x69800000, 0xFFC00000, InstName.StgpPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed),
+ new(0x69000000, 0xFFC00000, InstName.StgpSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled),
+ new(0x99000800, 0xBFE0EC00, InstName.Stilp, IsaVersion.v82, InstFlags.RtReadRtRt2RnSP),
+ new(0x0D018400, 0xBFFFFC00, opcodesizeOpcodesizeOpcodesizesOpcodesizeConstraints, InstName.Stl1AdvsimdSngl, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.StructNoOffset),
+ new(0x889F7C00, 0xBFFFFC00, InstName.Stllr, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x089F7C00, 0xFFFFFC00, InstName.Stllrb, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x489F7C00, 0xFFFFFC00, InstName.Stllrh, IsaVersion.v81, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x889FFC00, 0xBFFFFC00, InstName.StlrBaseRegister, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x99800800, 0xBFFFFC00, InstName.StlrPreIndexed, IsaVersion.v82, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x089FFC00, 0xFFFFFC00, InstName.Stlrb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x489FFC00, 0xFFFFFC00, InstName.Stlrh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BaseRegister),
+ new(0x19000000, 0xFFE00C00, InstName.Stlurb, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x59000000, 0xFFE00C00, InstName.Stlurh, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x1D000800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StlurFpsimd, IsaVersion.v82, InstFlags.RtReadRtRnSPFpSimd, AddressForm.BasePlusOffset),
+ new(0x99000000, 0xBFE00C00, InstName.StlurGen, IsaVersion.v84, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x88208000, 0xBFE08000, InstName.Stlxp, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPRs, AddressForm.BaseRegister),
+ new(0x8800FC00, 0xBFE0FC00, InstName.Stlxr, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x0800FC00, 0xFFE0FC00, InstName.Stlxrb, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x4800FC00, 0xFFE0FC00, InstName.Stlxrh, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x2C000000, 0x3FC00000, opcConstraints, InstName.StnpFpsimd, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimd, AddressForm.SignedScaled),
+ new(0x28000000, 0x7FC00000, opcConstraints2, InstName.StnpGen, IsaVersion.v80, InstFlags.RtReadRtRt2RnSP, AddressForm.SignedScaled),
+ new(0x2C800000, 0x3FC00000, opcConstraints, InstName.StpFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimdMemWBack, AddressForm.PostIndexed),
+ new(0x2D800000, 0x3FC00000, opcConstraints, InstName.StpFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimdMemWBack, AddressForm.PreIndexed),
+ new(0x2D000000, 0x3FC00000, opcConstraints, InstName.StpFpsimdSignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPFpSimd, AddressForm.SignedScaled),
+ new(0x28800000, 0x7FC00000, opclOpcConstraints, InstName.StpGenPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPMemWBack, AddressForm.PostIndexed),
+ new(0x29800000, 0x7FC00000, opclOpcConstraints, InstName.StpGenPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPMemWBack, AddressForm.PreIndexed),
+ new(0x29000000, 0x7FC00000, opclOpcConstraints, InstName.StpGenSignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRt2RnSP, AddressForm.SignedScaled),
+ new(0x38000400, 0xFFE00C00, InstName.StrbImmPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x38000C00, 0xFFE00C00, InstName.StrbImmPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x39000000, 0xFFC00000, InstName.StrbImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled),
+ new(0x38200800, 0xFFE00C00, optionConstraints, InstName.StrbReg, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg),
+ new(0x78000400, 0xFFE00C00, InstName.StrhImmPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0x78000C00, 0xFFE00C00, InstName.StrhImmPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0x79000000, 0xFFC00000, InstName.StrhImmUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled),
+ new(0x78200800, 0xFFE00C00, optionConstraints, InstName.StrhReg, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg),
+ new(0x3C000400, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimdMemWBack, AddressForm.PostIndexed),
+ new(0x3C000C00, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimdMemWBack, AddressForm.PreIndexed),
+ new(0x3D000000, 0x3F400000, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.StrImmFpsimdUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.UnsignedScaled),
+ new(0xB8000400, 0xBFE00C00, InstName.StrImmGenPostIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PostIndexed),
+ new(0xB8000C00, 0xBFE00C00, InstName.StrImmGenPreIndexed, IsaVersion.v80, InstFlags.RtReadRtRnSPMemWBack, AddressForm.PreIndexed),
+ new(0xB9000000, 0xBFC00000, InstName.StrImmGenUnsignedScaledOffset, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.UnsignedScaled),
+ new(0x3C200800, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeOptionConstraints, InstName.StrRegFpsimd, IsaVersion.v80, InstFlags.RtReadRtRnSPRmFpSimd, AddressForm.OffsetReg),
+ new(0xB8200800, 0xBFE00C00, optionConstraints, InstName.StrRegGen, IsaVersion.v80, InstFlags.RtReadRtRnSPRm, AddressForm.OffsetReg),
+ new(0xB8000800, 0xBFE00C00, InstName.Sttr, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x38000800, 0xFFE00C00, InstName.Sttrb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x78000800, 0xFFE00C00, InstName.Sttrh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x38000000, 0xFFE00C00, InstName.Sturb, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x78000000, 0xFFE00C00, InstName.Sturh, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x3C000000, 0x3F600C00, opc1sizeOpc1sizeOpc1sizeConstraints, InstName.SturFpsimd, IsaVersion.v80, InstFlags.RtReadRtRnSPFpSimd, AddressForm.BasePlusOffset),
+ new(0xB8000000, 0xBFE00C00, InstName.SturGen, IsaVersion.v80, InstFlags.RtReadRtRnSP, AddressForm.BasePlusOffset),
+ new(0x88200000, 0xBFE08000, InstName.Stxp, IsaVersion.v80, InstFlags.RtReadRtRt2RnSPRs, AddressForm.BaseRegister),
+ new(0x88007C00, 0xBFE0FC00, InstName.Stxr, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x08007C00, 0xFFE0FC00, InstName.Stxrb, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0x48007C00, 0xFFE0FC00, InstName.Stxrh, IsaVersion.v80, InstFlags.RtReadRtRnSPRs, AddressForm.BaseRegister),
+ new(0xD9E00400, 0xFFE00C00, InstName.Stz2gPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed),
+ new(0xD9E00C00, 0xFFE00C00, InstName.Stz2gPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed),
+ new(0xD9E00800, 0xFFE00C00, InstName.Stz2gSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled),
+ new(0xD9600400, 0xFFE00C00, InstName.StzgPostIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PostIndexed),
+ new(0xD9600C00, 0xFFE00C00, InstName.StzgPreIndexed, IsaVersion.v85, InstFlags.MemWBack, AddressForm.PreIndexed),
+ new(0xD9600800, 0xFFE00C00, InstName.StzgSignedScaledOffset, IsaVersion.v85, InstFlags.None, AddressForm.SignedScaled),
+ new(0xD9200000, 0xFFFFFC00, InstName.Stzgm, IsaVersion.v85, InstFlags.None),
+ new(0xD1800000, 0xFFC0C000, InstName.Subg, IsaVersion.v85, InstFlags.None),
+ new(0x0E206000, 0xBF20FC00, sizeConstraints, InstName.SubhnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x9AC00000, 0xFFE0FC00, InstName.Subp, IsaVersion.v85, InstFlags.None),
+ new(0xBAC00000, 0xFFE0FC00, InstName.Subps, IsaVersion.v85, InstFlags.S),
+ new(0x6B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.SubsAddsubExt, IsaVersion.v80, InstFlags.RdRnSPRmS),
+ new(0x71000000, 0x7F800000, InstName.SubsAddsubImm, IsaVersion.v80, InstFlags.RdRnSPS),
+ new(0x6B000000, 0x7F200000, shiftSfimm6Constraints, InstName.SubsAddsubShift, IsaVersion.v80, InstFlags.RdRnRmS),
+ new(0x4B200000, 0x7FE00000, opuOpuOpuConstraints, InstName.SubAddsubExt, IsaVersion.v80, InstFlags.RdSPRnSPRm),
+ new(0x51000000, 0x7F800000, InstName.SubAddsubImm, IsaVersion.v80, InstFlags.RdSPRnSP),
+ new(0x4B000000, 0x7F200000, shiftSfimm6Constraints, InstName.SubAddsubShift, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x7EE08400, 0xFFE0FC00, InstName.SubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E208400, 0xBF20FC00, qsizeConstraints, InstName.SubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0F00F000, 0xBFC0F400, InstName.SudotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x5E203800, 0xFF3FFC00, InstName.SuqaddAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0E203800, 0xBF3FFC00, qsizeConstraints, InstName.SuqaddAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0xD4000001, 0xFFE0001F, InstName.Svc, IsaVersion.v80, InstFlags.None),
+ new(0xB8208000, 0xBF20FC00, InstName.Swp, IsaVersion.v81, InstFlags.RtReadRtRnSPRs),
+ new(0x38208000, 0xFF20FC00, InstName.Swpb, IsaVersion.v81, InstFlags.RtReadRtRnSPRs),
+ new(0x78208000, 0xFF20FC00, InstName.Swph, IsaVersion.v81, InstFlags.RtReadRtRnSPRs),
+ new(0x19208000, 0xFF20FC00, rtRt2Constraints, InstName.Swpp, IsaVersion.None, InstFlags.RtReadRtRt2RnSP),
+ new(0xD5080000, 0xFFF80000, InstName.Sys, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0xD5280000, 0xFFF80000, InstName.Sysl, IsaVersion.v80, InstFlags.Rt),
+ new(0xD5480000, 0xFFF80000, InstName.Sysp, IsaVersion.None, InstFlags.RtReadRt),
+ new(0x0E000000, 0xBFE09C00, InstName.TblAdvsimd, IsaVersion.v80, InstFlags.RdRnSeqRmFpSimd),
+ new(0x37000000, 0x7F000000, InstName.Tbnz, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0x0E001000, 0xBFE09C00, InstName.TbxAdvsimd, IsaVersion.v80, InstFlags.RdRnSeqRmFpSimd),
+ new(0x36000000, 0x7F000000, InstName.Tbz, IsaVersion.v80, InstFlags.RtReadRt),
+ new(0xD4600000, 0xFFE0001F, InstName.Tcancel, IsaVersion.None, InstFlags.None),
+ new(0xD503307F, 0xFFFFFFFF, InstName.Tcommit, IsaVersion.None, InstFlags.None),
+ new(0x0E002800, 0xBF20FC00, qsizeConstraints, InstName.Trn1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E006800, 0xBF20FC00, qsizeConstraints, InstName.Trn2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xD503225F, 0xFFFFFFFF, InstName.Tsb, IsaVersion.v84, InstFlags.None),
+ new(0xD5233060, 0xFFFFFFE0, InstName.Tstart, IsaVersion.None, InstFlags.RtReadRt),
+ new(0xD5233160, 0xFFFFFFE0, InstName.Ttest, IsaVersion.None, InstFlags.RtReadRt),
+ new(0x2E205000, 0xBF20FC00, sizeConstraints, InstName.UabalAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E207C00, 0xBF20FC00, sizeConstraints, InstName.UabaAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E207000, 0xBF20FC00, sizeConstraints, InstName.UabdlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E207400, 0xBF20FC00, sizeConstraints, InstName.UabdAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E206800, 0xBF3FFC00, sizeConstraints, InstName.UadalpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2E202800, 0xBF3FFC00, sizeConstraints, InstName.UaddlpAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0x2E303800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UaddlvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E200000, 0xBF20FC00, sizeConstraints, InstName.UaddlAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E201000, 0xBF20FC00, sizeConstraints, InstName.UaddwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x53000000, 0x7F800000, sfnSfnSfimmr5Sfimms5Constraints, InstName.Ubfm, IsaVersion.v80, InstFlags.RdRn),
+ new(0x7F40E400, 0xFFC0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7F10E400, 0xFFF0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7F20E400, 0xFFE0FC00, immhConstraints, InstName.UcvtfAdvsimdFixS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F40E400, 0xBFC0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F10E400, 0xBFF0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F20E400, 0xBFE0FC00, immhQimmhConstraints, InstName.UcvtfAdvsimdFixV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7E79D800, 0xFFFFFC00, InstName.UcvtfAdvsimdIntSH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x7E21D800, 0xFFBFFC00, InstName.UcvtfAdvsimdIntS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E79D800, 0xBFFFFC00, InstName.UcvtfAdvsimdIntVH, IsaVersion.v82, InstFlags.RdRnFpSimd),
+ new(0x2E21D800, 0xBFBFFC00, qszConstraints, InstName.UcvtfAdvsimdIntV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x1E030000, 0x7FBF0000, sfscaleConstraints, InstName.UcvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1EC30000, 0x7FFF0000, sfscaleConstraints, InstName.UcvtfFloatFix, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1E230000, 0x7FBFFC00, InstName.UcvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x1EE30000, 0x7FFFFC00, InstName.UcvtfFloatInt, IsaVersion.v80, InstFlags.RdRnFpSimdFromGpr),
+ new(0x00000000, 0xFFFF0000, InstName.UdfPermUndef, IsaVersion.v80, InstFlags.None),
+ new(0x1AC00800, 0x7FE0FC00, InstName.Udiv, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x2F80E000, 0xBFC0F400, InstName.UdotAdvsimdElt, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E809400, 0xBFE0FC00, InstName.UdotAdvsimdVec, IsaVersion.v82, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2E200400, 0xBF20FC00, sizeConstraints, InstName.UhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E202400, 0xBF20FC00, sizeConstraints, InstName.UhsubAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x9BA00000, 0xFFE08000, InstName.Umaddl, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x2E20A400, 0xBF20FC00, sizeConstraints, InstName.UmaxpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E30A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UmaxvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E206400, 0xBF20FC00, sizeConstraints, InstName.UmaxAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x11C40000, 0x7FFC0000, InstName.UmaxImm, IsaVersion.v89, InstFlags.RdRn),
+ new(0x1AC06400, 0x7FE0FC00, InstName.UmaxReg, IsaVersion.v89, InstFlags.RdRnRm),
+ new(0x2E20AC00, 0xBF20FC00, sizeConstraints, InstName.UminpAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E31A800, 0xBF3FFC00, qsizeSizeConstraints, InstName.UminvAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E206C00, 0xBF20FC00, sizeConstraints, InstName.UminAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x11CC0000, 0x7FFC0000, InstName.UminImm, IsaVersion.v89, InstFlags.RdRn),
+ new(0x1AC06C00, 0x7FE0FC00, InstName.UminReg, IsaVersion.v89, InstFlags.RdRnRm),
+ new(0x2F002000, 0xBF00F400, sizeSizeConstraints, InstName.UmlalAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E208000, 0xBF20FC00, sizeConstraints, InstName.UmlalAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2F006000, 0xBF00F400, sizeSizeConstraints, InstName.UmlslAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E20A000, 0xBF20FC00, sizeConstraints, InstName.UmlslAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x6E80A400, 0xFFE0FC00, InstName.UmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x0E013C00, 0xFFE1FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x0E023C00, 0xFFE3FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x0E043C00, 0xFFE7FC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x4E083C00, 0xFFEFFC00, InstName.UmovAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimdToGpr),
+ new(0x9BA08000, 0xFFE08000, InstName.Umsubl, IsaVersion.v80, InstFlags.RdRnRmRa),
+ new(0x9BC07C00, 0xFFE0FC00, InstName.Umulh, IsaVersion.v80, InstFlags.RdRnRm),
+ new(0x2F00A000, 0xBF00F400, sizeSizeConstraints, InstName.UmullAdvsimdElt, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E20C000, 0xBF20FC00, sizeConstraints, InstName.UmullAdvsimdVec, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7E200C00, 0xFF20FC00, InstName.UqaddAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x2E200C00, 0xBF20FC00, qsizeConstraints, InstName.UqaddAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7E205C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UqrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x2E205C00, 0xBF20FC00, qsizeConstraints, InstName.UqrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7F009C00, 0xFF80FC00, immhImmhConstraints, InstName.UqrshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2F009C00, 0xBF80FC00, immhImmhConstraints, InstName.UqrshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7F007400, 0xFF80FC00, immhOpuConstraints, InstName.UqshlAdvsimdImmS, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x2F007400, 0xBF80FC00, immhQimmhOpuConstraints, InstName.UqshlAdvsimdImmV, IsaVersion.v80, InstFlags.RdRnQcFpSimd),
+ new(0x7E204C00, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UqshlAdvsimdRegS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x2E204C00, 0xBF20FC00, qsizeConstraints, InstName.UqshlAdvsimdRegV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7F009400, 0xFF80FC00, immhImmhConstraints, InstName.UqshrnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2F009400, 0xBF80FC00, immhImmhConstraints, InstName.UqshrnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7E202C00, 0xFF20FC00, InstName.UqsubAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x2E202C00, 0xBF20FC00, qsizeConstraints, InstName.UqsubAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmQcFpSimd),
+ new(0x7E214800, 0xFF3FFC00, sizeConstraints, InstName.UqxtnAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2E214800, 0xBF3FFC00, sizeConstraints, InstName.UqxtnAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x0EA1C800, 0xBFBFFC00, szConstraints, InstName.UrecpeAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E201400, 0xBF20FC00, sizeConstraints, InstName.UrhaddAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7E205400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UrshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E205400, 0xBF20FC00, qsizeConstraints, InstName.UrshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7F402400, 0xFFC0FC00, immhConstraints, InstName.UrshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F002400, 0xBF80FC00, immhQimmhConstraints, InstName.UrshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2EA1C800, 0xBFBFFC00, szConstraints, InstName.UrsqrteAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7F403400, 0xFFC0FC00, immhConstraints, InstName.UrsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F003400, 0xBF80FC00, immhQimmhConstraints, InstName.UrsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x0F80F000, 0xBFC0F400, InstName.UsdotAdvsimdElt, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x0E809C00, 0xBFE0FC00, InstName.UsdotAdvsimdVec, IsaVersion.v86, InstFlags.RdReadRdRnRmFpSimd),
+ new(0x2F00A400, 0xBF80FC00, immhImmhConstraints, InstName.UshllAdvsimd, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x7E204400, 0xFF20FC00, ssizeSsizeSsizeConstraints, InstName.UshlAdvsimdS, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E204400, 0xBF20FC00, qsizeConstraints, InstName.UshlAdvsimdV, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x7F400400, 0xFFC0FC00, immhConstraints, InstName.UshrAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F000400, 0xBF80FC00, immhQimmhConstraints, InstName.UshrAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x4E80AC00, 0xFFE0FC00, InstName.UsmmlaAdvsimdVec, IsaVersion.v86, InstFlags.RdRnRmFpSimd),
+ new(0x7E203800, 0xFF3FFC00, InstName.UsqaddAdvsimdS, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x2E203800, 0xBF3FFC00, qsizeConstraints, InstName.UsqaddAdvsimdV, IsaVersion.v80, InstFlags.RdReadRdRnQcFpSimd),
+ new(0x7F401400, 0xFFC0FC00, immhConstraints, InstName.UsraAdvsimdS, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2F001400, 0xBF80FC00, immhQimmhConstraints, InstName.UsraAdvsimdV, IsaVersion.v80, InstFlags.RdRnFpSimd),
+ new(0x2E202000, 0xBF20FC00, sizeConstraints, InstName.UsublAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x2E203000, 0xBF20FC00, sizeConstraints, InstName.UsubwAdvsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E001800, 0xBF20FC00, qsizeConstraints, InstName.Uzp1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E005800, 0xBF20FC00, qsizeConstraints, InstName.Uzp2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0xD503205F, 0xFFFFFFFF, InstName.Wfe, IsaVersion.v80, InstFlags.None),
+ new(0xD5031000, 0xFFFFFFE0, InstName.Wfet, IsaVersion.v87, InstFlags.Rd),
+ new(0xD503207F, 0xFFFFFFFF, InstName.Wfi, IsaVersion.v80, InstFlags.None),
+ new(0xD5031020, 0xFFFFFFE0, InstName.Wfit, IsaVersion.v87, InstFlags.Rd),
+ new(0xD500403F, 0xFFFFFFFF, InstName.Xaflag, IsaVersion.v85, InstFlags.C),
+ new(0xCE800000, 0xFFE00000, InstName.XarAdvsimd, IsaVersion.v82, InstFlags.RdRnRmFpSimd),
+ new(0xDAC143E0, 0xFFFFFBE0, InstName.XpacGeneral, IsaVersion.v83, InstFlags.Rd),
+ new(0xD50320FF, 0xFFFFFFFF, InstName.XpacSystem, IsaVersion.v83, InstFlags.None),
+ new(0x0E212800, 0xBF3FFC00, sizeConstraints, InstName.XtnAdvsimd, IsaVersion.v80, InstFlags.RdReadRdRnFpSimd),
+ new(0xD503203F, 0xFFFFFFFF, InstName.Yield, IsaVersion.v80, InstFlags.None),
+ new(0x0E003800, 0xBF20FC00, qsizeConstraints, InstName.Zip1Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ new(0x0E007800, 0xBF20FC00, qsizeConstraints, InstName.Zip2Advsimd, IsaVersion.v80, InstFlags.RdRnRmFpSimd),
+ };
+
+ _table = new(insts);
+ }
+
+ public static (InstName, InstFlags, AddressForm) GetInstNameAndFlags(uint encoding, IsaVersion version, IsaFeature features)
+ {
+ if (_table.TryFind(encoding, version, features, out InstInfo info))
+ {
+ return (info.Name, info.Flags, info.AddressForm);
+ }
+
+ return new(InstName.UdfPermUndef, InstFlags.None, AddressForm.None);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs b/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs
new file mode 100644
index 00000000..0249e24b
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ readonly struct CacheEntry : IComparable
+ {
+ public int Offset { get; }
+ public int Size { get; }
+
+ public CacheEntry(int offset, int size)
+ {
+ Offset = offset;
+ Size = size;
+ }
+
+ public int CompareTo([AllowNull] CacheEntry other)
+ {
+ return Offset.CompareTo(other.Offset);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs
new file mode 100644
index 00000000..8ba3a6dc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ class CacheMemoryAllocator
+ {
+ private readonly struct MemoryBlock : IComparable
+ {
+ public int Offset { get; }
+ public int Size { get; }
+
+ public MemoryBlock(int offset, int size)
+ {
+ Offset = offset;
+ Size = size;
+ }
+
+ public int CompareTo([AllowNull] MemoryBlock other)
+ {
+ return Offset.CompareTo(other.Offset);
+ }
+ }
+
+ private readonly List _blocks = new();
+
+ public CacheMemoryAllocator(int capacity)
+ {
+ _blocks.Add(new MemoryBlock(0, capacity));
+ }
+
+ public int Allocate(int size)
+ {
+ for (int i = 0; i < _blocks.Count; i++)
+ {
+ MemoryBlock block = _blocks[i];
+
+ if (block.Size > size)
+ {
+ _blocks[i] = new(block.Offset + size, block.Size - size);
+ return block.Offset;
+ }
+ else if (block.Size == size)
+ {
+ _blocks.RemoveAt(i);
+ return block.Offset;
+ }
+ }
+
+ // We don't have enough free memory to perform the allocation.
+ return -1;
+ }
+
+ public void ForceAllocation(int offset, int size)
+ {
+ int index = _blocks.BinarySearch(new(offset, size));
+
+ if (index < 0)
+ {
+ index = ~index;
+ }
+
+ int endOffset = offset + size;
+
+ MemoryBlock block = _blocks[index];
+
+ Debug.Assert(block.Offset <= offset && block.Offset + block.Size >= endOffset);
+
+ if (offset > block.Offset && endOffset < block.Offset + block.Size)
+ {
+ _blocks[index] = new(block.Offset, offset - block.Offset);
+ _blocks.Insert(index + 1, new(endOffset, (block.Offset + block.Size) - endOffset));
+ }
+ else if (offset > block.Offset)
+ {
+ _blocks[index] = new(block.Offset, offset - block.Offset);
+ }
+ else if (endOffset < block.Offset + block.Size)
+ {
+ _blocks[index] = new(endOffset, (block.Offset + block.Size) - endOffset);
+ }
+ else
+ {
+ _blocks.RemoveAt(index);
+ }
+ }
+
+ public void Free(int offset, int size)
+ {
+ Insert(new MemoryBlock(offset, size));
+ }
+
+ private void Insert(MemoryBlock block)
+ {
+ int index = _blocks.BinarySearch(block);
+
+ if (index < 0)
+ {
+ index = ~index;
+ }
+
+ if (index < _blocks.Count)
+ {
+ MemoryBlock next = _blocks[index];
+
+ int endOffs = block.Offset + block.Size;
+
+ if (next.Offset == endOffs)
+ {
+ block = new MemoryBlock(block.Offset, block.Size + next.Size);
+ _blocks.RemoveAt(index);
+ }
+ }
+
+ if (index > 0)
+ {
+ MemoryBlock prev = _blocks[index - 1];
+
+ if (prev.Offset + prev.Size == block.Offset)
+ {
+ block = new MemoryBlock(block.Offset - prev.Size, block.Size + prev.Size);
+ _blocks.RemoveAt(--index);
+ }
+ }
+
+ _blocks.Insert(index, block);
+ }
+
+ public void Clear()
+ {
+ _blocks.Clear();
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
new file mode 100644
index 00000000..6f1191ca
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
@@ -0,0 +1,197 @@
+using ARMeilleure.Memory;
+using Ryujinx.Memory;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ static partial class JitCache
+ {
+ private static readonly int _pageSize = (int)MemoryBlock.GetPageSize();
+ private static readonly int _pageMask = _pageSize - 1;
+
+ private const int CodeAlignment = 4; // Bytes.
+ private const int CacheSize = 2047 * 1024 * 1024;
+
+ private static ReservedRegion _jitRegion;
+ private static JitCacheInvalidation _jitCacheInvalidator;
+
+ private static CacheMemoryAllocator _cacheAllocator;
+
+ private static readonly List _cacheEntries = new();
+
+ private static readonly object _lock = new();
+ private static bool _initialized;
+
+ [SupportedOSPlatform("windows")]
+ [LibraryImport("kernel32.dll", SetLastError = true)]
+ public static partial IntPtr FlushInstructionCache(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize);
+
+ public static void Initialize(IJitMemoryAllocator allocator)
+ {
+ if (_initialized)
+ {
+ return;
+ }
+
+ lock (_lock)
+ {
+ if (_initialized)
+ {
+ return;
+ }
+
+ _jitRegion = new ReservedRegion(allocator, CacheSize);
+
+ if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
+ {
+ _jitCacheInvalidator = new JitCacheInvalidation(allocator);
+ }
+
+ _cacheAllocator = new CacheMemoryAllocator(CacheSize);
+
+ _initialized = true;
+ }
+ }
+
+ public unsafe static IntPtr Map(ReadOnlySpan code)
+ {
+ lock (_lock)
+ {
+ Debug.Assert(_initialized);
+
+ int funcOffset = Allocate(code.Length);
+
+ IntPtr funcPtr = _jitRegion.Pointer + funcOffset;
+
+ if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ {
+ unsafe
+ {
+ fixed (byte* codePtr = code)
+ {
+ JitSupportDarwin.Copy(funcPtr, (IntPtr)codePtr, (ulong)code.Length);
+ }
+ }
+ }
+ else
+ {
+ ReprotectAsWritable(funcOffset, code.Length);
+ code.CopyTo(new Span((void*)funcPtr, code.Length));
+ ReprotectAsExecutable(funcOffset, code.Length);
+
+ if (OperatingSystem.IsWindows() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ {
+ FlushInstructionCache(Process.GetCurrentProcess().Handle, funcPtr, (UIntPtr)code.Length);
+ }
+ else
+ {
+ _jitCacheInvalidator?.Invalidate(funcPtr, (ulong)code.Length);
+ }
+ }
+
+ Add(funcOffset, code.Length);
+
+ return funcPtr;
+ }
+ }
+
+ public static void Unmap(IntPtr pointer)
+ {
+ lock (_lock)
+ {
+ Debug.Assert(_initialized);
+
+ int funcOffset = (int)(pointer.ToInt64() - _jitRegion.Pointer.ToInt64());
+
+ if (TryFind(funcOffset, out CacheEntry entry, out int entryIndex) && entry.Offset == funcOffset)
+ {
+ _cacheAllocator.Free(funcOffset, AlignCodeSize(entry.Size));
+ _cacheEntries.RemoveAt(entryIndex);
+ }
+ }
+ }
+
+ private static void ReprotectAsWritable(int offset, int size)
+ {
+ int endOffs = offset + size;
+
+ int regionStart = offset & ~_pageMask;
+ int regionEnd = (endOffs + _pageMask) & ~_pageMask;
+
+ _jitRegion.Block.MapAsRwx((ulong)regionStart, (ulong)(regionEnd - regionStart));
+ }
+
+ private static void ReprotectAsExecutable(int offset, int size)
+ {
+ int endOffs = offset + size;
+
+ int regionStart = offset & ~_pageMask;
+ int regionEnd = (endOffs + _pageMask) & ~_pageMask;
+
+ _jitRegion.Block.MapAsRx((ulong)regionStart, (ulong)(regionEnd - regionStart));
+ }
+
+ private static int Allocate(int codeSize)
+ {
+ codeSize = AlignCodeSize(codeSize);
+
+ int allocOffset = _cacheAllocator.Allocate(codeSize);
+
+ if (allocOffset < 0)
+ {
+ throw new OutOfMemoryException("JIT Cache exhausted.");
+ }
+
+ _jitRegion.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
+
+ return allocOffset;
+ }
+
+ private static int AlignCodeSize(int codeSize)
+ {
+ return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
+ }
+
+ private static void Add(int offset, int size)
+ {
+ CacheEntry entry = new(offset, size);
+
+ int index = _cacheEntries.BinarySearch(entry);
+
+ if (index < 0)
+ {
+ index = ~index;
+ }
+
+ _cacheEntries.Insert(index, entry);
+ }
+
+ public static bool TryFind(int offset, out CacheEntry entry, out int entryIndex)
+ {
+ lock (_lock)
+ {
+ int index = _cacheEntries.BinarySearch(new CacheEntry(offset, 0));
+
+ if (index < 0)
+ {
+ index = ~index - 1;
+ }
+
+ if (index >= 0)
+ {
+ entry = _cacheEntries[index];
+ entryIndex = index;
+ return true;
+ }
+ }
+
+ entry = default;
+ entryIndex = 0;
+ return false;
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs
new file mode 100644
index 00000000..cd5f3ede
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs
@@ -0,0 +1,79 @@
+using ARMeilleure.Memory;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ class JitCacheInvalidation
+ {
+ private static readonly int[] _invalidationCode = new int[]
+ {
+ unchecked((int)0xd53b0022), // mrs x2, ctr_el0
+ unchecked((int)0xd3504c44), // ubfx x4, x2, #16, #4
+ unchecked((int)0x52800083), // mov w3, #0x4
+ unchecked((int)0x12000c45), // and w5, w2, #0xf
+ unchecked((int)0x1ac42064), // lsl w4, w3, w4
+ unchecked((int)0x51000482), // sub w2, w4, #0x1
+ unchecked((int)0x8a220002), // bic x2, x0, x2
+ unchecked((int)0x1ac52063), // lsl w3, w3, w5
+ unchecked((int)0xeb01005f), // cmp x2, x1
+ unchecked((int)0x93407c84), // sxtw x4, w4
+ unchecked((int)0x540000a2), // b.cs 3c
+ unchecked((int)0xd50b7b22), // dc cvau, x2
+ unchecked((int)0x8b040042), // add x2, x2, x4
+ unchecked((int)0xeb02003f), // cmp x1, x2
+ unchecked((int)0x54ffffa8), // b.hi 2c
+ unchecked((int)0xd5033b9f), // dsb ish
+ unchecked((int)0x51000462), // sub w2, w3, #0x1
+ unchecked((int)0x93407c63), // sxtw x3, w3
+ unchecked((int)0x8a220000), // bic x0, x0, x2
+ unchecked((int)0xeb00003f), // cmp x1, x0
+ unchecked((int)0x540000a9), // b.ls 64
+ unchecked((int)0xd50b7520), // ic ivau, x0
+ unchecked((int)0x8b030000), // add x0, x0, x3
+ unchecked((int)0xeb00003f), // cmp x1, x0
+ unchecked((int)0x54ffffa8), // b.hi 54
+ unchecked((int)0xd5033b9f), // dsb ish
+ unchecked((int)0xd5033fdf), // isb
+ unchecked((int)0xd65f03c0), // ret
+ };
+
+ private delegate void InvalidateCache(ulong start, ulong end);
+
+ private readonly InvalidateCache _invalidateCache;
+ private readonly ReservedRegion _invalidateCacheCodeRegion;
+
+ private readonly bool _needsInvalidation;
+
+ public JitCacheInvalidation(IJitMemoryAllocator allocator)
+ {
+ // On macOS and Windows, a different path is used to write to the JIT cache, which does the invalidation.
+ if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+ {
+ ulong size = (ulong)_invalidationCode.Length * sizeof(int);
+ ulong mask = (ulong)ReservedRegion.DefaultGranularity - 1;
+
+ size = (size + mask) & ~mask;
+
+ _invalidateCacheCodeRegion = new ReservedRegion(allocator, size);
+ _invalidateCacheCodeRegion.ExpandIfNeeded(size);
+
+ Marshal.Copy(_invalidationCode, 0, _invalidateCacheCodeRegion.Pointer, _invalidationCode.Length);
+
+ _invalidateCacheCodeRegion.Block.MapAsRx(0, size);
+
+ _invalidateCache = Marshal.GetDelegateForFunctionPointer(_invalidateCacheCodeRegion.Pointer);
+
+ _needsInvalidation = true;
+ }
+ }
+
+ public void Invalidate(IntPtr basePointer, ulong size)
+ {
+ if (_needsInvalidation)
+ {
+ _invalidateCache((ulong)basePointer, (ulong)basePointer + size);
+ }
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
new file mode 100644
index 00000000..06c81045
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ [SupportedOSPlatform("macos")]
+ static partial class JitSupportDarwin
+ {
+ [LibraryImport("libarmeilleure-jitsupport", EntryPoint = "armeilleure_jit_memcpy")]
+ public static partial void Copy(IntPtr dst, IntPtr src, ulong n);
+
+ [LibraryImport("libc", EntryPoint = "sys_icache_invalidate", SetLastError = true)]
+ public static partial void SysIcacheInvalidate(IntPtr start, IntPtr len);
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs
new file mode 100644
index 00000000..a7107499
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs
@@ -0,0 +1,340 @@
+using ARMeilleure.Memory;
+using Ryujinx.Common;
+using Ryujinx.Memory;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ class NoWxCache : IDisposable
+ {
+ private const int CodeAlignment = 4; // Bytes.
+ private const int SharedCacheSize = 2047 * 1024 * 1024;
+ private const int LocalCacheSize = 128 * 1024 * 1024;
+
+ // How many calls to the same function we allow until we pad the shared cache to force the function to become available there
+ // and allow the guest to take the fast path.
+ private const int MinCallsForPad = 8;
+
+ private class MemoryCache : IDisposable
+ {
+ private readonly ReservedRegion _region;
+ private readonly CacheMemoryAllocator _cacheAllocator;
+
+ public CacheMemoryAllocator Allocator => _cacheAllocator;
+ public IntPtr Pointer => _region.Block.Pointer;
+
+ public MemoryCache(IJitMemoryAllocator allocator, ulong size)
+ {
+ _region = new(allocator, size);
+ _cacheAllocator = new((int)size);
+ }
+
+ public int Allocate(int codeSize)
+ {
+ codeSize = AlignCodeSize(codeSize);
+
+ int allocOffset = _cacheAllocator.Allocate(codeSize);
+
+ if (allocOffset < 0)
+ {
+ throw new OutOfMemoryException("JIT Cache exhausted.");
+ }
+
+ _region.ExpandIfNeeded((ulong)allocOffset + (ulong)codeSize);
+
+ return allocOffset;
+ }
+
+ public void Free(int offset, int size)
+ {
+ _cacheAllocator.Free(offset, size);
+ }
+
+ public void ReprotectAsRw(int offset, int size)
+ {
+ Debug.Assert(offset >= 0 && (offset & (int)(MemoryBlock.GetPageSize() - 1)) == 0);
+ Debug.Assert(size > 0 && (size & (int)(MemoryBlock.GetPageSize() - 1)) == 0);
+
+ _region.Block.MapAsRw((ulong)offset, (ulong)size);
+ }
+
+ public void ReprotectAsRx(int offset, int size)
+ {
+ Debug.Assert(offset >= 0 && (offset & (int)(MemoryBlock.GetPageSize() - 1)) == 0);
+ Debug.Assert(size > 0 && (size & (int)(MemoryBlock.GetPageSize() - 1)) == 0);
+
+ _region.Block.MapAsRx((ulong)offset, (ulong)size);
+
+ if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
+ {
+ JitSupportDarwin.SysIcacheInvalidate(_region.Block.Pointer + offset, size);
+ }
+ else
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+
+ private static int AlignCodeSize(int codeSize)
+ {
+ return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _region.Dispose();
+ _cacheAllocator.Clear();
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ private readonly IStackWalker _stackWalker;
+ private readonly Translator _translator;
+ private readonly MemoryCache _sharedCache;
+ private readonly MemoryCache _localCache;
+ private readonly PageAlignedRangeList _pendingMap;
+ private readonly object _lock;
+
+ class ThreadLocalCacheEntry
+ {
+ public readonly int Offset;
+ public readonly int Size;
+ public readonly IntPtr FuncPtr;
+ private int _useCount;
+
+ public ThreadLocalCacheEntry(int offset, int size, IntPtr funcPtr)
+ {
+ Offset = offset;
+ Size = size;
+ FuncPtr = funcPtr;
+ _useCount = 0;
+ }
+
+ public int IncrementUseCount()
+ {
+ return ++_useCount;
+ }
+ }
+
+ [ThreadStatic]
+ private static Dictionary _threadLocalCache;
+
+ public NoWxCache(IJitMemoryAllocator allocator, IStackWalker stackWalker, Translator translator)
+ {
+ _stackWalker = stackWalker;
+ _translator = translator;
+ _sharedCache = new(allocator, SharedCacheSize);
+ _localCache = new(allocator, LocalCacheSize);
+ _pendingMap = new(_sharedCache.ReprotectAsRx, RegisterFunction);
+ _lock = new();
+ }
+
+ public unsafe IntPtr Map(IntPtr framePointer, ReadOnlySpan code, ulong guestAddress, ulong guestSize)
+ {
+ if (TryGetThreadLocalFunction(guestAddress, out IntPtr funcPtr))
+ {
+ return funcPtr;
+ }
+
+ lock (_lock)
+ {
+ if (!_pendingMap.Has(guestAddress) && !_translator.Functions.ContainsKey(guestAddress))
+ {
+ int funcOffset = _sharedCache.Allocate(code.Length);
+
+ funcPtr = _sharedCache.Pointer + funcOffset;
+ code.CopyTo(new Span((void*)funcPtr, code.Length));
+
+ TranslatedFunction function = new(funcPtr, guestSize);
+
+ _pendingMap.Add(funcOffset, code.Length, guestAddress, function);
+ }
+
+ ClearThreadLocalCache(framePointer);
+
+ return AddThreadLocalFunction(code, guestAddress);
+ }
+ }
+
+ public unsafe IntPtr MapPageAligned(ReadOnlySpan code)
+ {
+ lock (_lock)
+ {
+ // Ensure we will get an aligned offset from the allocator.
+ _pendingMap.Pad(_sharedCache.Allocator);
+
+ int sizeAligned = BitUtils.AlignUp(code.Length, (int)MemoryBlock.GetPageSize());
+ int funcOffset = _sharedCache.Allocate(sizeAligned);
+
+ Debug.Assert((funcOffset & ((int)MemoryBlock.GetPageSize() - 1)) == 0);
+
+ IntPtr funcPtr = _sharedCache.Pointer + funcOffset;
+ code.CopyTo(new Span((void*)funcPtr, code.Length));
+
+ _sharedCache.ReprotectAsRx(funcOffset, sizeAligned);
+
+ return funcPtr;
+ }
+ }
+
+ private bool TryGetThreadLocalFunction(ulong guestAddress, out IntPtr funcPtr)
+ {
+ if ((_threadLocalCache ??= new()).TryGetValue(guestAddress, out var entry))
+ {
+ if (entry.IncrementUseCount() >= MinCallsForPad)
+ {
+ // Function is being called often, let's make it available in the shared cache so that the guest code
+ // can take the fast path and stop calling the emulator to get the function from the thread local cache.
+ // To do that we pad all "pending" function until they complete a page of memory, allowing us to reprotect them as RX.
+
+ lock (_lock)
+ {
+ _pendingMap.Pad(_sharedCache.Allocator);
+ }
+ }
+
+ funcPtr = entry.FuncPtr;
+
+ return true;
+ }
+
+ funcPtr = IntPtr.Zero;
+
+ return false;
+ }
+
+ private void ClearThreadLocalCache(IntPtr framePointer)
+ {
+ // Try to delete functions that are already on the shared cache
+ // and no longer being executed.
+
+ if (_threadLocalCache == null)
+ {
+ return;
+ }
+
+ IEnumerable callStack = _stackWalker.GetCallStack(
+ framePointer,
+ _localCache.Pointer,
+ LocalCacheSize,
+ _sharedCache.Pointer,
+ SharedCacheSize);
+
+ List<(ulong, ThreadLocalCacheEntry)> toDelete = new();
+
+ foreach ((ulong address, ThreadLocalCacheEntry entry) in _threadLocalCache)
+ {
+ // We only want to delete if the function is already on the shared cache,
+ // otherwise we will keep translating the same function over and over again.
+ bool canDelete = !_pendingMap.Has(address);
+ if (!canDelete)
+ {
+ continue;
+ }
+
+ // We can only delete if the function is not part of the current thread call stack,
+ // otherwise we will crash the program when the thread returns to it.
+ foreach (ulong funcAddress in callStack)
+ {
+ if (funcAddress >= (ulong)entry.FuncPtr && funcAddress < (ulong)entry.FuncPtr + (ulong)entry.Size)
+ {
+ canDelete = false;
+ break;
+ }
+ }
+
+ if (canDelete)
+ {
+ toDelete.Add((address, entry));
+ }
+ }
+
+ int pageSize = (int)MemoryBlock.GetPageSize();
+
+ foreach ((ulong address, ThreadLocalCacheEntry entry) in toDelete)
+ {
+ _threadLocalCache.Remove(address);
+
+ int sizeAligned = BitUtils.AlignUp(entry.Size, pageSize);
+
+ _localCache.Free(entry.Offset, sizeAligned);
+ _localCache.ReprotectAsRw(entry.Offset, sizeAligned);
+ }
+ }
+
+ public void ClearEntireThreadLocalCache()
+ {
+ // Thread is exiting, delete everything.
+
+ if (_threadLocalCache == null)
+ {
+ return;
+ }
+
+ int pageSize = (int)MemoryBlock.GetPageSize();
+
+ foreach ((_, ThreadLocalCacheEntry entry) in _threadLocalCache)
+ {
+ int sizeAligned = BitUtils.AlignUp(entry.Size, pageSize);
+
+ _localCache.Free(entry.Offset, sizeAligned);
+ _localCache.ReprotectAsRw(entry.Offset, sizeAligned);
+ }
+
+ _threadLocalCache.Clear();
+ _threadLocalCache = null;
+ }
+
+ private unsafe IntPtr AddThreadLocalFunction(ReadOnlySpan code, ulong guestAddress)
+ {
+ int alignedSize = BitUtils.AlignUp(code.Length, (int)MemoryBlock.GetPageSize());
+ int funcOffset = _localCache.Allocate(alignedSize);
+
+ Debug.Assert((funcOffset & (int)(MemoryBlock.GetPageSize() - 1)) == 0);
+
+ IntPtr funcPtr = _localCache.Pointer + funcOffset;
+ code.CopyTo(new Span((void*)funcPtr, code.Length));
+
+ (_threadLocalCache ??= new()).Add(guestAddress, new(funcOffset, code.Length, funcPtr));
+
+ _localCache.ReprotectAsRx(funcOffset, alignedSize);
+
+ return funcPtr;
+ }
+
+ private void RegisterFunction(ulong address, TranslatedFunction func)
+ {
+ TranslatedFunction oldFunc = _translator.Functions.GetOrAdd(address, func.GuestSize, func);
+
+ Debug.Assert(oldFunc == func);
+
+ _translator.RegisterFunction(address, func);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _localCache.Dispose();
+ _sharedCache.Dispose();
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs b/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs
new file mode 100644
index 00000000..b6b38671
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs
@@ -0,0 +1,218 @@
+using Ryujinx.Common;
+using Ryujinx.Memory;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Ryujinx.Cpu.LightningJit.Cache
+{
+ class PageAlignedRangeList
+ {
+ private readonly struct Range : IComparable
+ {
+ public int Offset { get; }
+ public int Size { get; }
+
+ public Range(int offset, int size)
+ {
+ Offset = offset;
+ Size = size;
+ }
+
+ public int CompareTo([AllowNull] Range other)
+ {
+ return Offset.CompareTo(other.Offset);
+ }
+ }
+
+ private readonly Action _alignedRangeAction;
+ private readonly Action _alignedFunctionAction;
+ private readonly List<(Range, ulong, TranslatedFunction)> _pendingFunctions;
+ private readonly List _ranges;
+
+ public PageAlignedRangeList(Action