From 427b7d06b5ab6d2b06784a9d283eaf836a04c27e Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Sat, 20 Jan 2024 11:11:28 -0300
Subject: [PATCH] Implement a new JIT for Arm devices (#6057)

* Implement a new JIT for Arm devices

* Auto-format

* Make a lot of Assembler members read-only

* More read-only

* Fix more warnings

* ObjectDisposedException.ThrowIf

* New JIT cache for platforms that enforce W^X, currently unused

* Remove unused using

* Fix assert

* Pass memory manager type around

* Safe memory manager mode support + other improvements

* Actual safe memory manager mode masking support

* PR feedback
---
 src/ARMeilleure/Common/AddressTable.cs        |    2 +-
 src/ARMeilleure/Memory/IJitMemoryBlock.cs     |    1 +
 src/ARMeilleure/Memory/ReservedRegion.cs      |    2 +-
 src/ARMeilleure/Native/JitSupportDarwin.cs    |    2 +-
 src/ARMeilleure/Translation/IntervalTree.cs   |    2 +-
 src/ARMeilleure/Translation/Translator.cs     |    2 +-
 .../Translation/TranslatorStubs.cs            |   29 +-
 src/Ryujinx.Cpu/AppleHv/HvCpuContext.cs       |    4 +
 src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs    |   17 +
 src/Ryujinx.Cpu/ICpuContext.cs                |    4 +-
 src/Ryujinx.Cpu/Jit/JitCpuContext.cs          |    6 +-
 src/Ryujinx.Cpu/Jit/JitMemoryAllocator.cs     |    9 +-
 src/Ryujinx.Cpu/Jit/JitMemoryBlock.cs         |    1 +
 src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs |   32 +
 src/Ryujinx.Cpu/LightningJit/AddressForm.cs   |   18 +
 .../LightningJit/Arm32/A32Compiler.cs         |   30 +
 src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs   |  101 +
 .../LightningJit/Arm32/BranchType.cs          |   15 +
 .../LightningJit/Arm32/CodeGenContext.cs      |  198 +
 src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs |  546 ++
 .../LightningJit/Arm32/IInstEmit.cs           | 1231 +++
 .../LightningJit/Arm32/ImmUtils.cs            |  137 +
 .../LightningJit/Arm32/InstDecoders.cs        | 2927 ++++++
 .../LightningJit/Arm32/InstFlags.cs           |   63 +
 .../LightningJit/Arm32/InstInfo.cs            |   20 +
 .../LightningJit/Arm32/InstInfoForTable.cs    |   79 +
 .../LightningJit/Arm32/InstMeta.cs            |   22 +
 .../LightningJit/Arm32/InstName.cs            |  562 ++
 .../LightningJit/Arm32/InstTableA32.cs        | 1194 +++
 .../LightningJit/Arm32/InstTableT16.cs        |  146 +
 .../LightningJit/Arm32/InstTableT32.cs        | 1212 +++
 .../LightningJit/Arm32/MultiBlock.cs          |   31 +
 .../LightningJit/Arm32/PendingBranch.cs       |   20 +
 .../LightningJit/Arm32/RegisterAllocator.cs   |  169 +
 .../LightningJit/Arm32/RegisterUtils.cs       |  109 +
 .../LightningJit/Arm32/ScopedRegister.cs      |   39 +
 .../Arm32/Target/Arm64/Compiler.cs            |  789 ++
 .../Arm32/Target/Arm64/InstEmit.cs            | 8502 +++++++++++++++++
 .../Arm32/Target/Arm64/InstEmitAbsDiff.cs     |   87 +
 .../Arm32/Target/Arm64/InstEmitAlu.cs         | 1105 +++
 .../Arm32/Target/Arm64/InstEmitBit.cs         |  103 +
 .../Arm32/Target/Arm64/InstEmitCommon.cs      |  263 +
 .../Arm32/Target/Arm64/InstEmitCrc32.cs       |   26 +
 .../Arm32/Target/Arm64/InstEmitDivide.cs      |   25 +
 .../Arm32/Target/Arm64/InstEmitExtension.cs   |  191 +
 .../Arm32/Target/Arm64/InstEmitFlow.cs        |  256 +
 .../Arm32/Target/Arm64/InstEmitGE.cs          |  265 +
 .../Arm32/Target/Arm64/InstEmitHalve.cs       |  178 +
 .../Arm32/Target/Arm64/InstEmitMemory.cs      | 1172 +++
 .../Arm32/Target/Arm64/InstEmitMove.cs        |  350 +
 .../Arm32/Target/Arm64/InstEmitMultiply.cs    |  603 ++
 .../Target/Arm64/InstEmitNeonArithmetic.cs    |  344 +
 .../Arm32/Target/Arm64/InstEmitNeonBit.cs     |   35 +
 .../Arm32/Target/Arm64/InstEmitNeonCommon.cs  | 1513 +++
 .../Arm32/Target/Arm64/InstEmitNeonCompare.cs |  126 +
 .../Arm32/Target/Arm64/InstEmitNeonConvert.cs |  137 +
 .../Arm32/Target/Arm64/InstEmitNeonCrypto.cs  |   43 +
 .../Arm32/Target/Arm64/InstEmitNeonHash.cs    |   97 +
 .../Arm32/Target/Arm64/InstEmitNeonLogical.cs |   79 +
 .../Arm32/Target/Arm64/InstEmitNeonMemory.cs  |  797 ++
 .../Arm32/Target/Arm64/InstEmitNeonMove.cs    |  665 ++
 .../Arm32/Target/Arm64/InstEmitNeonRound.cs   |  105 +
 .../Target/Arm64/InstEmitNeonSaturate.cs      |  205 +
 .../Arm32/Target/Arm64/InstEmitNeonShift.cs   |  123 +
 .../Arm32/Target/Arm64/InstEmitNeonSystem.cs  |   77 +
 .../Arm32/Target/Arm64/InstEmitSaturate.cs    |  452 +
 .../Arm32/Target/Arm64/InstEmitSystem.cs      |  648 ++
 .../Target/Arm64/InstEmitVfpArithmetic.cs     |   95 +
 .../Arm32/Target/Arm64/InstEmitVfpCompare.cs  |  133 +
 .../Arm32/Target/Arm64/InstEmitVfpConvert.cs  |  305 +
 .../Arm32/Target/Arm64/InstEmitVfpMove.cs     |   22 +
 .../Arm32/Target/Arm64/InstEmitVfpRound.cs    |   40 +
 .../LightningJit/Arm64/A64Compiler.cs         |   29 +
 src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs   |  138 +
 .../LightningJit/Arm64/ImmUtils.cs            |   20 +
 .../LightningJit/Arm64/InstFlags.cs           |  108 +
 .../LightningJit/Arm64/InstInfo.cs            |   22 +
 .../LightningJit/Arm64/InstName.cs            | 1134 +++
 .../LightningJit/Arm64/MultiBlock.cs          |   64 +
 .../LightningJit/Arm64/RegisterAllocator.cs   |  154 +
 .../LightningJit/Arm64/RegisterUtils.cs       |  495 +
 .../Arm64/Target/Arm64/Compiler.cs            |  743 ++
 .../Arm64/Target/Arm64/Decoder.cs             |  384 +
 .../Arm64/Target/Arm64/InstEmitMemory.cs      |  593 ++
 .../Arm64/Target/Arm64/InstEmitSystem.cs      |  610 ++
 .../Arm64/Target/Arm64/InstTable.cs           | 1605 ++++
 .../LightningJit/Cache/CacheEntry.cs          |   22 +
 .../Cache/CacheMemoryAllocator.cs             |  136 +
 .../LightningJit/Cache/JitCache.cs            |  197 +
 .../Cache/JitCacheInvalidation.cs             |   79 +
 .../LightningJit/Cache/JitSupportDarwin.cs    |   16 +
 .../LightningJit/Cache/NoWxCache.cs           |  340 +
 .../Cache/PageAlignedRangeList.cs             |  218 +
 .../CodeGen/Arm64/AbiConstants.cs             |   15 +
 .../CodeGen/Arm64/ArmCondition.cs             |   30 +
 .../CodeGen/Arm64/ArmExtensionType.cs         |   14 +
 .../CodeGen/Arm64/ArmShiftType.cs             |   11 +
 .../LightningJit/CodeGen/Arm64/Assembler.cs   | 4777 +++++++++
 .../CodeGen/Arm64/CodeGenCommon.cs            |   67 +
 .../CodeGen/Arm64/RegisterSaveRestore.cs      |  252 +
 .../LightningJit/CodeGen/Arm64/StackWalker.cs |   30 +
 .../LightningJit/CodeGen/Arm64/TailMerger.cs  |  120 +
 .../LightningJit/CodeGen/Operand.cs           |   38 +
 .../LightningJit/CodeGen/OperandKind.cs       |   10 +
 .../LightningJit/CodeGen/OperandType.cs       |   35 +
 .../LightningJit/CodeGen/Register.cs          |   42 +
 .../LightningJit/CodeGen/RegisterType.cs      |    8 +
 src/Ryujinx.Cpu/LightningJit/CodeWriter.cs    |   61 +
 .../LightningJit/CompiledFunction.cs          |   16 +
 src/Ryujinx.Cpu/LightningJit/CpuPreset.cs     |   14 +
 src/Ryujinx.Cpu/LightningJit/CpuPresets.cs    |   13 +
 .../LightningJit/Graph/DataFlow.cs            |  171 +
 src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs  |   17 +
 .../LightningJit/Graph/IBlockList.cs          |    9 +
 .../LightningJit/Graph/RegisterMask.cs        |   60 +
 .../LightningJit/Graph/RegisterUse.cs         |   24 +
 src/Ryujinx.Cpu/LightningJit/IStackWalker.cs  |   10 +
 src/Ryujinx.Cpu/LightningJit/IsaFeature.cs    |   65 +
 src/Ryujinx.Cpu/LightningJit/IsaVersion.cs    |   17 +
 .../LightningJit/LightningJitCpuContext.cs    |   58 +
 .../LightningJit/LightningJitEngine.cs        |   20 +
 .../LightningJit/NativeContextOffsets.cs      |   17 +
 .../LightningJit/NativeInterface.cs           |   93 +
 .../LightningJit/State/ExecutionContext.cs    |  153 +
 .../LightningJit/State/ExecutionMode.cs       |    9 +
 .../LightningJit/State/NativeContext.cs       |  173 +
 .../LightningJit/Table/IInstInfo.cs           |   12 +
 .../LightningJit/Table/InstEncoding.cs        |   14 +
 .../LightningJit/Table/InstTableLevel.cs      |   96 +
 .../LightningJit/TranslatedFunction.cs        |   16 +
 src/Ryujinx.Cpu/LightningJit/Translator.cs    |  227 +
 .../LightningJit/TranslatorCache.cs           |   96 +
 .../LightningJit/TranslatorStubs.cs           |  380 +
 src/Ryujinx.HLE/HOS/ArmProcessContext.cs      |    2 +
 .../HOS/ArmProcessContextFactory.cs           |    9 +-
 135 files changed, 43322 insertions(+), 24 deletions(-)
 create mode 100644 src/Ryujinx.Cpu/DummyDiskCacheLoadState.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/AddressForm.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/A32Compiler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Block.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/BranchType.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/CodeGenContext.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Decoder.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/IInstEmit.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/ImmUtils.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstDecoders.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstFlags.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstInfo.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstInfoForTable.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstMeta.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstName.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstTableA32.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT16.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/InstTableT32.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/MultiBlock.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/PendingBranch.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/RegisterAllocator.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/RegisterUtils.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/ScopedRegister.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmit.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAbsDiff.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitAlu.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitBit.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCommon.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitCrc32.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitDivide.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitExtension.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitFlow.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitGE.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitHalve.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMove.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMultiply.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonArithmetic.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonBit.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCommon.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCompare.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonConvert.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonCrypto.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonHash.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonLogical.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMemory.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonMove.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonRound.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSaturate.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonShift.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitNeonSystem.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSaturate.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitSystem.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpArithmetic.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpConvert.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpRound.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/A64Compiler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Block.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/ImmUtils.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/InstFlags.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/InstInfo.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/InstName.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/MultiBlock.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/RegisterUtils.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Decoder.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitSystem.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstTable.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/CacheEntry.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/CacheMemoryAllocator.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/NoWxCache.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Cache/PageAlignedRangeList.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CodeWriter.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CpuPreset.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/CpuPresets.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/IStackWalker.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/IsaFeature.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/IsaVersion.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/NativeInterface.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/Translator.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs
 create mode 100644 src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs

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.
     /// </summary>
     /// <typeparam name="TEntry">Type of the value</typeparam>
-    unsafe class AddressTable<TEntry> : IDisposable where TEntry : unmanaged
+    public unsafe class AddressTable<TEntry> : IDisposable where TEntry : unmanaged
     {
         /// <summary>
         /// Represents a level in an <see cref="AddressTable{TEntry}"/>.
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
     /// </summary>
     /// <typeparam name="TK">Key</typeparam>
     /// <typeparam name="TV">Value</typeparam>
-    class IntervalTree<TK, TV> where TK : IComparable<TK>
+    public class IntervalTree<TK, TV> where TK : IComparable<TK>
     {
         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<uint>();
             Functions = new TranslatorCache<TranslatedFunction>();
             FunctionTable = new AddressTable<ulong>(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
     /// </summary>
     class TranslatorStubs : IDisposable
     {
-        private static readonly Lazy<IntPtr> _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
+        private readonly Lazy<IntPtr> _slowDispatchStub;
 
         private bool _disposed;
 
-        private readonly Translator _translator;
+        private readonly AddressTable<ulong> _functionTable;
         private readonly Lazy<IntPtr> _dispatchStub;
         private readonly Lazy<DispatcherFunction> _dispatchLoop;
         private readonly Lazy<WrapperFunction> _contextWrapper;
@@ -83,13 +84,14 @@ namespace ARMeilleure.Translation
         /// Initializes a new instance of the <see cref="TranslatorStubs"/> class with the specified
         /// <see cref="Translator"/> instance.
         /// </summary>
-        /// <param name="translator"><see cref="Translator"/> instance to use</param>
+        /// <param name="functionTable">Function table used to store pointers to the functions that the guest code will call</param>
         /// <exception cref="ArgumentNullException"><paramref name="translator"/> is null</exception>
-        public TranslatorStubs(Translator translator)
+        public TranslatorStubs(AddressTable<ulong> 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 <see cref="SlowDispatchStub"/>.
         /// </summary>
         /// <returns>Generated <see cref="SlowDispatchStub"/></returns>
-        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
+        /// <inheritdoc/>
+        public event Action<LoadState, int, int> StateChanged;
+#pragma warning restore CS0067
+
+        /// <inheritdoc/>
+        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
 {
     /// <summary>
     /// CPU context interface.
     /// </summary>
-    public interface ICpuContext
+    public interface ICpuContext : IDisposable
     {
         /// <summary>
         /// 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<ulong> 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<ulong> 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<InstInfo> 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<InstInfo> 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<PendingBranch> _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<PendingBranch> GetPendingBranches()
+        {
+            return _pendingBranches;
+        }
+
+        public void SetItBlockStart(ReadOnlySpan<ArmCondition> 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<T> where T : IInstEmit
+    {
+        public static MultiBlock DecodeMulti(CpuPreset cpuPreset, IMemoryManager memoryManager, ulong address, bool isThumb)
+        {
+            List<Block> blocks = new();
+            List<ulong> 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<Block> blocks, List<ulong> 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<ulong> 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<InstInfo> 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<ushort>(address) << 16;
+                    address += 2UL;
+
+                    extraFlags = InstFlags.Thumb16;
+
+                    if (!InstTableT16<T>.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta))
+                    {
+                        encoding |= memoryManager.Read<ushort>(address);
+
+                        if (InstTableT32<T>.TryGetMeta(encoding, cpuPreset.Version, cpuPreset.Features, out meta))
+                        {
+                            address += 2UL;
+                            extraFlags = InstFlags.None;
+                        }
+                    }
+                }
+                else
+                {
+                    encoding = memoryManager.Read<uint>(address);
+                    address += 4UL;
+
+                    meta = InstTableA32<T>.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<CodeGenContext, uint> EmitFunc;
+        public readonly InstFlags Flags;
+
+        public InstInfo(uint encoding, InstName name, Action<CodeGenContext, uint> 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<CodeGenContext, uint> 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<CodeGenContext, uint> emitFunc,
+            IsaVersion isaVersion,
+            InstFlags flags) : this(encoding, encodingMask, constraints, name, emitFunc, isaVersion, IsaFeature.None, flags)
+        {
+        }
+
+        public InstInfoForTable(
+            uint encoding,
+            uint encodingMask,
+            InstName name,
+            Action<CodeGenContext, uint> 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<CodeGenContext, uint> 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<CodeGenContext, uint> EmitFunc;
+        public readonly IsaVersion Version;
+        public readonly IsaFeature Feature;
+        public readonly InstFlags Flags;
+
+        public InstMeta(InstName name, Action<CodeGenContext, uint> 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<T> where T : IInstEmit
+    {
+        private static readonly InstTableLevel<InstInfoForTable> _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<InstInfoForTable> 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<T> where T : IInstEmit
+    {
+        private static readonly InstTableLevel<InstInfoForTable> _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<InstInfoForTable> 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<T> where T : IInstEmit
+    {
+        private static readonly InstTableLevel<InstInfoForTable> _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<InstInfoForTable> 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<Block> Blocks;
+        public readonly bool HasHostCall;
+        public readonly bool IsTruncated;
+
+        public MultiBlock(List<Block> 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<int> 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<ulong> FuncTable;
+            public readonly IntPtr DispatchStubPointer;
+
+            private readonly RegisterSaveRestore _registerSaveRestore;
+            private readonly IntPtr _pageTablePointer;
+
+            public Context(
+                CodeWriter writer,
+                RegisterAllocator registerAllocator,
+                MemoryManagerType mmType,
+                TailMerger tailMerger,
+                AddressTable<ulong> 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<ulong> funcTable, IntPtr dispatchStubPtr, bool isThumb)
+        {
+            MultiBlock multiBlock = Decoder<InstEmit>.DecodeMulti(cpuPreset, memoryManager, address, isThumb);
+
+            Dictionary<ulong, int> 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<InstEmit>.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<PendingBranch> 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<ulong, int> 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<ulong, int> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, ArmShiftType, int> 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<Operand, Operand> 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<Operand, Operand, ArmShiftType, int> 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<Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand> 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<Operand, Operand, Operand, ArmShiftType, int> 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<Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand> elementAction)
+        {
+            Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: false);
+        }
+
+        public static void EmitUnsigned16BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action<Operand, Operand, Operand> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand> elementAction)
+        {
+            Emit8BitPair(context, rd, rn, rm, elementAction, unsigned: true);
+        }
+
+        private static void Emit8BitPair(CodeGenContext context, uint rd, uint rn, uint rm, Action<Operand, Operand, Operand> 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<Operand, Operand> 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<ArmCondition> 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<ulong> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, Operand, int> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, Operand, int> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, Operand, int> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, Operand, int> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, int> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, int> 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<Operand, Operand> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, Operand> 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<Operand, Operand, int> writeInst,
+            Action<Operand, Operand, int> 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<Operand, Operand, int> 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<Operand, Operand, Operand, int> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, Operand> 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<Operand, Operand, uint> 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<Operand, Operand, uint> action, Action<Operand, Operand> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, Operand, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, Operand, uint> 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<Operand, Operand, Operand, Operand, uint> 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<Operand, Operand> 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<Operand, Operand, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, Operand> 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<Operand, Operand, Operand, uint> 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<Operand, Operand, Operand, uint, uint> action,
+            Action<Operand, Operand, Operand, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint, uint> action,
+            Action<Operand, Operand, uint, uint> 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<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> 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<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint, uint> 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<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> 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<Operand, Operand, Operand, uint> 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<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> 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<Operand, Operand, uint, uint, uint> action,
+            Action<Operand, Operand, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> 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<Operand, Operand, uint, uint> action,
+            Action<Operand, Operand, uint> 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<Operand, Operand, uint, uint> action,
+            Action<Operand, Operand, uint> 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<Operand, Operand, uint, uint, uint> 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<Operand, Operand, Operand, uint, uint> action,
+            Action<Operand, Operand, Operand, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> action,
+            Action<Operand, Operand, uint, Operand, uint, uint, uint> 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<Operand, Operand, Operand, uint, uint> action,
+            Action<Operand, Operand, Operand, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> action,
+            Action<Operand, Operand, uint, Operand, uint, uint, uint> 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<Operand, Operand, uint, Operand, uint, uint, uint, uint> action,
+            Action<Operand, Operand, uint, Operand, uint, uint, uint> 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<Operand> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint> 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<Operand, Operand, uint, uint, uint> 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<Operand, Operand, uint, uint> 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<ScopedRegister> registers)
+        {
+            for (int index = 0; index < registers.Length; index++)
+            {
+                registers[index].Dispose();
+            }
+        }
+
+        [Conditional("DEBUG")]
+        private static void AssertSequentialRegisters(ReadOnlySpan<ScopedRegister> 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<ScopedRegister> 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<ScopedRegister> 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<ScopedRegister> 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<ScopedRegister> 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<ScopedRegister> 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<Operand, Operand, Operand, uint, uint> action1,
+            Action<Operand, Operand, Operand, uint, uint> 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<Operand, Operand, Operand, uint, uint> action1,
+            Action<Operand, Operand, Operand, uint, uint> 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<SoftwareInterruptHandler>(NativeInterface.Break);
+        }
+
+        private static IntPtr GetSvcHandlerPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<SoftwareInterruptHandler>(NativeInterface.SupervisorCall);
+        }
+
+        private static IntPtr GetUdfHandlerPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<SoftwareInterruptHandler>(NativeInterface.Undefined);
+        }
+
+        private static IntPtr GetCntpctEl0Ptr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<Get64>(NativeInterface.GetCntpctEl0);
+        }
+
+        private static IntPtr CheckSynchronizationPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<GetBool>(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<ulong> 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<Block> _predecessors;
+        private readonly List<Block> _successors;
+
+        public int PredecessorsCount => _predecessors.Count;
+        public int SuccessorsCount => _successors.Count;
+
+        public readonly ulong Address;
+        public readonly ulong EndAddress;
+        public readonly List<InstInfo> Instructions;
+        public readonly bool EndsWithBranch;
+        public readonly bool IsTruncated;
+        public readonly bool IsLoopEnd;
+
+        public Block(ulong address, ulong endAddress, List<InstInfo> 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<Block> 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<Block> 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<int> predList = new();
+                List<int> 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<int> 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<int> 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<ulong> 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<ulong> 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<ulong> funcTable, IntPtr dispatchStubPtr)
+        {
+            MultiBlock multiBlock = Decoder.DecodeMulti(cpuPreset, memoryManager, address);
+
+            Dictionary<ulong, int> targets = new();
+            List<PendingBranch> 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<ulong, int> 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<Block> blocks = new();
+            List<ulong> 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<Block> blocks, List<ulong> 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<Block> blocks)
+        {
+            Dictionary<ulong, Block> 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<ulong> 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<InstInfo> 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<uint>(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<SoftwareInterruptHandler>(NativeInterface.Break);
+        }
+
+        private static IntPtr GetSvcHandlerPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<SoftwareInterruptHandler>(NativeInterface.SupervisorCall);
+        }
+
+        private static IntPtr GetUdfHandlerPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<SoftwareInterruptHandler>(NativeInterface.Undefined);
+        }
+
+        private static IntPtr GetCntpctEl0Ptr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<Get64>(NativeInterface.GetCntpctEl0);
+        }
+
+        private static IntPtr CheckSynchronizationPtr()
+        {
+            return Marshal.GetFunctionPointerForDelegate<GetBool>(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<ulong> 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<ulong> 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<InstInfo> _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<InstInfo> 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<CacheEntry>
+    {
+        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<MemoryBlock>
+        {
+            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<MemoryBlock> _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<CacheEntry> _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<byte> 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<byte>((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 <do_ic_clear>
+            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 <dc_clear_loop>
+            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 <exit>
+            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 <ic_clear_loop>
+            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<InvalidateCache>(_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<ulong, ThreadLocalCacheEntry> _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<byte> 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<byte>((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<byte> 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<byte>((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<ulong> 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<byte> 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<byte>((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<Range>
+        {
+            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<int, int> _alignedRangeAction;
+        private readonly Action<ulong, TranslatedFunction> _alignedFunctionAction;
+        private readonly List<(Range, ulong, TranslatedFunction)> _pendingFunctions;
+        private readonly List<Range> _ranges;
+
+        public PageAlignedRangeList(Action<int, int> alignedRangeAction, Action<ulong, TranslatedFunction> alignedFunctionAction)
+        {
+            _alignedRangeAction = alignedRangeAction;
+            _alignedFunctionAction = alignedFunctionAction;
+            _pendingFunctions = new();
+            _ranges = new();
+        }
+
+        public bool Has(ulong address)
+        {
+            foreach ((_, ulong guestAddress, _) in _pendingFunctions)
+            {
+                if (guestAddress == address)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        public void Add(int offset, int size, ulong address, TranslatedFunction function)
+        {
+            Range range = new(offset, size);
+
+            Insert(range);
+            _pendingFunctions.Add((range, address, function));
+            ProcessAlignedRanges();
+        }
+
+        public void Pad(CacheMemoryAllocator allocator)
+        {
+            int pageSize = (int)MemoryBlock.GetPageSize();
+
+            for (int index = 0; index < _ranges.Count; index++)
+            {
+                Range range = _ranges[index];
+
+                int endOffset = range.Offset + range.Size;
+
+                int alignedStart = BitUtils.AlignDown(range.Offset, pageSize);
+                int alignedEnd = BitUtils.AlignUp(endOffset, pageSize);
+                int alignedSize = alignedEnd - alignedStart;
+
+                if (alignedStart < range.Offset)
+                {
+                    allocator.ForceAllocation(alignedStart, range.Offset - alignedStart);
+                }
+
+                if (alignedEnd > endOffset)
+                {
+                    allocator.ForceAllocation(endOffset, alignedEnd - endOffset);
+                }
+
+                _alignedRangeAction(alignedStart, alignedSize);
+                _ranges.RemoveAt(index--);
+                ProcessPendingFunctions(index, alignedEnd);
+            }
+        }
+
+        private void ProcessAlignedRanges()
+        {
+            int pageSize = (int)MemoryBlock.GetPageSize();
+
+            for (int index = 0; index < _ranges.Count; index++)
+            {
+                Range range = _ranges[index];
+
+                int alignedStart = BitUtils.AlignUp(range.Offset, pageSize);
+                int alignedEnd = BitUtils.AlignDown(range.Offset + range.Size, pageSize);
+                int alignedSize = alignedEnd - alignedStart;
+
+                if (alignedSize <= 0)
+                {
+                    continue;
+                }
+
+                _alignedRangeAction(alignedStart, alignedSize);
+                SplitAt(ref index, alignedStart, alignedEnd);
+                ProcessPendingFunctions(index, alignedEnd);
+            }
+        }
+
+        private void ProcessPendingFunctions(int rangeIndex, int alignedEnd)
+        {
+            if ((rangeIndex > 0 && rangeIndex == _ranges.Count) ||
+                (rangeIndex >= 0 && rangeIndex < _ranges.Count && _ranges[rangeIndex].Offset >= alignedEnd))
+            {
+                rangeIndex--;
+            }
+
+            int alignedStart;
+
+            if (rangeIndex >= 0)
+            {
+                alignedStart = _ranges[rangeIndex].Offset + _ranges[rangeIndex].Size;
+            }
+            else
+            {
+                alignedStart = 0;
+            }
+
+            if (rangeIndex < _ranges.Count - 1)
+            {
+                alignedEnd = _ranges[rangeIndex + 1].Offset;
+            }
+            else
+            {
+                alignedEnd = int.MaxValue;
+            }
+
+            for (int index = 0; index < _pendingFunctions.Count; index++)
+            {
+                (Range range, ulong address, TranslatedFunction function) = _pendingFunctions[index];
+
+                if (range.Offset >= alignedStart && range.Offset + range.Size <= alignedEnd)
+                {
+                    _alignedFunctionAction(address, function);
+                    _pendingFunctions.RemoveAt(index--);
+                }
+            }
+        }
+
+        private void Insert(Range range)
+        {
+            int index = _ranges.BinarySearch(range);
+
+            if (index < 0)
+            {
+                index = ~index;
+            }
+
+            if (index < _ranges.Count)
+            {
+                Range next = _ranges[index];
+
+                int endOffs = range.Offset + range.Size;
+
+                if (next.Offset == endOffs)
+                {
+                    range = new Range(range.Offset, range.Size + next.Size);
+                    _ranges.RemoveAt(index);
+                }
+            }
+
+            if (index > 0)
+            {
+                Range prev = _ranges[index - 1];
+
+                if (prev.Offset + prev.Size == range.Offset)
+                {
+                    range = new Range(range.Offset - prev.Size, range.Size + prev.Size);
+                    _ranges.RemoveAt(--index);
+                }
+            }
+
+            _ranges.Insert(index, range);
+        }
+
+        private void SplitAt(ref int index, int alignedStart, int alignedEnd)
+        {
+            Range range = _ranges[index];
+
+            if (range.Offset < alignedStart)
+            {
+                _ranges[index++] = new(range.Offset, alignedStart - range.Offset);
+
+                if (range.Offset + range.Size > alignedEnd)
+                {
+                    _ranges.Insert(index, new(alignedEnd, (range.Offset + range.Size) - alignedEnd));
+                }
+            }
+            else if (range.Offset + range.Size > alignedEnd)
+            {
+                _ranges[index] = new(alignedEnd, (range.Offset + range.Size) - alignedEnd);
+            }
+            else if (range.Offset == alignedStart && range.Offset + range.Size == alignedEnd)
+            {
+                Debug.Assert(range.Offset == alignedStart && range.Offset + range.Size == alignedEnd);
+
+                _ranges.RemoveAt(index--);
+            }
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs
new file mode 100644
index 00000000..24a646ca
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/AbiConstants.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    static class AbiConstants
+    {
+        // 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 uint GprCalleeSavedRegsMask = 0x1ff80000; // X19 to X28
+        public const uint FpSimdCalleeSavedRegsMask = 0xff00; // D8 to D15
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs
new file mode 100644
index 00000000..caa2e593
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmCondition.cs
@@ -0,0 +1,30 @@
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    enum ArmCondition
+    {
+        Eq = 0,
+        Ne = 1,
+        GeUn = 2,
+        LtUn = 3,
+        Mi = 4,
+        Pl = 5,
+        Vs = 6,
+        Vc = 7,
+        GtUn = 8,
+        LeUn = 9,
+        Ge = 10,
+        Lt = 11,
+        Gt = 12,
+        Le = 13,
+        Al = 14,
+        Nv = 15,
+    }
+
+    static class ArmConditionExtensions
+    {
+        public static ArmCondition Invert(this ArmCondition condition)
+        {
+            return (ArmCondition)((int)condition ^ 1);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs
new file mode 100644
index 00000000..abcf7678
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmExtensionType.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    enum ArmExtensionType
+    {
+        Uxtb = 0,
+        Uxth = 1,
+        Uxtw = 2,
+        Uxtx = 3,
+        Sxtb = 4,
+        Sxth = 5,
+        Sxtw = 6,
+        Sxtx = 7,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs
new file mode 100644
index 00000000..348edd48
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/ArmShiftType.cs
@@ -0,0 +1,11 @@
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    enum ArmShiftType
+    {
+        Lsl = 0,
+        Lsr = 1,
+        Asr = 2,
+        Ror = 3,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs
new file mode 100644
index 00000000..28539707
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/Assembler.cs
@@ -0,0 +1,4777 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    struct Assembler
+    {
+        private const uint SfFlag = 1u << 31;
+
+        public const int SpRegister = 31;
+        public const int ZrRegister = 31;
+
+        private readonly List<uint> _code;
+
+        private class LabelState
+        {
+            public int BranchIndex;
+            public int TargetIndex;
+            public bool HasBranch;
+            public bool HasTarget;
+        }
+
+        private readonly List<LabelState> _labels;
+
+        public Assembler(CodeWriter writer)
+        {
+            _code = writer.GetList();
+            _labels = new List<LabelState>();
+        }
+
+        public readonly Operand CreateLabel()
+        {
+            int labelIndex = _labels.Count;
+            _labels.Add(new LabelState());
+
+            return new Operand(OperandKind.Label, OperandType.None, (ulong)labelIndex);
+        }
+
+        public readonly void MarkLabel(Operand label)
+        {
+            int targetIndex = _code.Count;
+
+            var state = _labels[label.AsInt32()];
+
+            state.TargetIndex = targetIndex;
+            state.HasTarget = true;
+
+            if (state.HasBranch)
+            {
+                int imm = (targetIndex - state.BranchIndex) * sizeof(uint);
+                uint code = _code[state.BranchIndex];
+
+                if ((code & 0xfc000000u) == 0x14000000u)
+                {
+                    _code[state.BranchIndex] = code | EncodeSImm26_2(imm);
+                }
+                else
+                {
+                    _code[state.BranchIndex] = code | (EncodeSImm19_2(imm) << 5);
+                }
+            }
+        }
+
+        // Base
+
+        public readonly void B(Operand label, ArmCondition condition = ArmCondition.Al)
+        {
+            int branchIndex = _code.Count;
+
+            var state = _labels[label.AsInt32()];
+
+            state.BranchIndex = branchIndex;
+            state.HasBranch = true;
+
+            int imm = 0;
+
+            if (state.HasTarget)
+            {
+                imm = (state.TargetIndex - branchIndex) * sizeof(uint);
+            }
+
+            if (condition == ArmCondition.Al)
+            {
+                B(imm);
+            }
+            else
+            {
+                B(condition, imm);
+            }
+        }
+
+        public readonly void Cbz(Operand rt, Operand label)
+        {
+            int branchIndex = _code.Count;
+
+            var state = _labels[label.AsInt32()];
+
+            state.BranchIndex = branchIndex;
+            state.HasBranch = true;
+
+            int imm = 0;
+
+            if (state.HasTarget)
+            {
+                imm = (state.TargetIndex - branchIndex) * sizeof(uint);
+            }
+
+            Cbz(rt, imm);
+        }
+
+        public readonly void Cbnz(Operand rt, Operand label)
+        {
+            int branchIndex = _code.Count;
+
+            var state = _labels[label.AsInt32()];
+
+            state.BranchIndex = branchIndex;
+            state.HasBranch = true;
+
+            int imm = 0;
+
+            if (state.HasTarget)
+            {
+                imm = (state.TargetIndex - branchIndex) * sizeof(uint);
+            }
+
+            Cbnz(rt, imm);
+        }
+
+        public readonly void Adc(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x1a000000u, rd, rn, rm);
+        }
+
+        public readonly void Adcs(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x3a000000u, rd, rn, rm);
+        }
+
+        public readonly void Add(Operand rd, Operand rn, Operand rm, ArmExtensionType extensionType, int shiftAmount = 0)
+        {
+            WriteInstructionAuto(0x0b200000u, rd, rn, rm, extensionType, shiftAmount);
+        }
+
+        public readonly void Add(Operand rd, Operand rn, Operand rm)
+        {
+            Add(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Add(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Add(rd, rn, rm, shiftType, shiftAmount, false);
+        }
+
+        public readonly void Add(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount, bool immForm)
+        {
+            WriteInstructionAuto(0x11000000u, 0x0b000000u, rd, rn, rm, shiftType, shiftAmount, immForm);
+        }
+
+        public readonly void Adds(Operand rd, Operand rn, Operand rm)
+        {
+            Adds(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Adds(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Adds(rd, rn, rm, shiftType, shiftAmount, false);
+        }
+
+        public readonly void Adds(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount, bool immForm)
+        {
+            WriteInstructionAuto(0x31000000u, 0x2b000000u, rd, rn, rm, shiftType, shiftAmount, immForm);
+        }
+
+        public readonly void And(Operand rd, Operand rn, Operand rm)
+        {
+            And(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void And(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionBitwiseAuto(0x12000000u, 0x0a000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Ands(Operand rd, Operand rn, Operand rm)
+        {
+            Ands(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Ands(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionBitwiseAuto(0x72000000u, 0x6a000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Asr(Operand rd, Operand rn, Operand rm)
+        {
+            if (rm.Kind == OperandKind.Constant)
+            {
+                int shift = rm.AsInt32();
+                int mask = rd.Type == OperandType.I64 ? 63 : 31;
+                shift &= mask;
+                Sbfm(rd, rn, shift, mask);
+            }
+            else
+            {
+                Asrv(rd, rn, rm);
+            }
+        }
+
+        public readonly void Asrv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionBitwiseAuto(0x1ac02800u, rd, rn, rm);
+        }
+
+        public readonly void B(int imm)
+        {
+            WriteUInt32(0x14000000u | EncodeSImm26_2(imm));
+        }
+
+        public readonly void B(ArmCondition condition, int imm)
+        {
+            WriteUInt32(0x54000000u | (uint)condition | (EncodeSImm19_2(imm) << 5));
+        }
+
+        public readonly void Bfc(Operand rd, int lsb, int width)
+        {
+            Bfi(rd, new Operand(ZrRegister, RegisterType.Integer, OperandType.I32), lsb, width);
+        }
+
+        public readonly void Bfi(Operand rd, Operand rn, int lsb, int width)
+        {
+            Bfm(rd, rn, -lsb & 31, width - 1);
+        }
+
+        public readonly void Bfm(Operand rd, Operand rn, int immr, int imms)
+        {
+            WriteInstruction(0x33000000u | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn);
+        }
+
+        public readonly void Bfxil(Operand rd, Operand rn, int lsb, int width)
+        {
+            Bfm(rd, rn, lsb, lsb + width - 1);
+        }
+
+        public readonly void Bic(Operand rd, Operand rn, Operand rm)
+        {
+            Bic(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Bic(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionAuto(0x0a200000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Bics(Operand rd, Operand rn, Operand rm)
+        {
+            Bics(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Bics(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionAuto(0x6a200000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Blr(Operand rn)
+        {
+            WriteUInt32(0xd63f0000u | (EncodeReg(rn) << 5));
+        }
+
+        public readonly void Br(Operand rn)
+        {
+            WriteUInt32(0xd61f0000u | (EncodeReg(rn) << 5));
+        }
+
+        public readonly void Brk()
+        {
+            WriteUInt32(0xd4200000u);
+        }
+
+        public readonly void Cbz(Operand rt, int imm)
+        {
+            WriteInstructionAuto(0x34000000u | (EncodeSImm19_2(imm) << 5), rt);
+        }
+
+        public readonly void Cbnz(Operand rt, int imm)
+        {
+            WriteInstructionAuto(0x35000000u | (EncodeSImm19_2(imm) << 5), rt);
+        }
+
+        public readonly void Crc32(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            Debug.Assert(sz <= 3);
+            WriteInstructionRm16(0x1ac04000u | (sz << 10), rd, rn, rm);
+        }
+
+        public readonly void Crc32c(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            Debug.Assert(sz <= 3);
+            WriteInstructionRm16(0x1ac05000u | (sz << 10), rd, rn, rm);
+        }
+
+        public readonly void Clrex(int crm = 15)
+        {
+            WriteUInt32(0xd503305fu | (EncodeUImm4(crm) << 8));
+        }
+
+        public readonly void Clz(Operand rd, Operand rn)
+        {
+            WriteInstructionAuto(0x5ac01000u, rd, rn);
+        }
+
+        public readonly void Cmn(Operand rn, Operand rm)
+        {
+            Cmn(rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Cmn(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Adds(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Cmp(Operand rn, Operand rm)
+        {
+            Cmp(rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Cmp(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Subs(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Csdb()
+        {
+            WriteUInt32(0xd503229fu);
+        }
+
+        public readonly void Csel(Operand rd, Operand rn, Operand rm, ArmCondition condition)
+        {
+            WriteInstructionBitwiseAuto(0x1a800000u | ((uint)condition << 12), rd, rn, rm);
+        }
+
+        public readonly void Cset(Operand rd, ArmCondition condition)
+        {
+            var zr = new Operand(ZrRegister, RegisterType.Integer, rd.Type);
+            Csinc(rd, zr, zr, (ArmCondition)((int)condition ^ 1));
+        }
+
+        public readonly void Csinc(Operand rd, Operand rn, Operand rm, ArmCondition condition)
+        {
+            WriteInstructionBitwiseAuto(0x1a800400u | ((uint)condition << 12), rd, rn, rm);
+        }
+
+        public readonly void Dmb(uint option)
+        {
+            WriteUInt32(0xd50330bfu | (option << 8));
+        }
+
+        public readonly void Dsb(uint option)
+        {
+            WriteUInt32(0xd503309fu | (option << 8));
+        }
+
+        public readonly void Eor(Operand rd, Operand rn, Operand rm)
+        {
+            Eor(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Eor(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionBitwiseAuto(0x52000000u, 0x4a000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Eors(Operand rd, Operand rn, Operand rm)
+        {
+            Eors(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Eors(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Eor(rd, rn, rm, shiftType, shiftAmount);
+            Tst(rd, rd);
+        }
+
+        public readonly void Esb()
+        {
+            WriteUInt32(0xd503221fu);
+        }
+
+        public readonly void Extr(Operand rd, Operand rn, Operand rm, int imms)
+        {
+            uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u;
+            WriteInstructionBitwiseAuto(0x13800000u | n | (EncodeUImm6(imms) << 10), rd, rn, rm);
+        }
+
+        public readonly void Isb(uint option)
+        {
+            WriteUInt32(0xd50330dfu | (option << 8));
+        }
+
+        public readonly void Ldar(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x88dffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn);
+        }
+
+        public readonly void Ldarb(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x08dffc00u, rt, rn);
+        }
+
+        public readonly void Ldarh(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x48dffc00u, rt, rn);
+        }
+
+        public readonly void Ldaxp(Operand rt, Operand rt2, Operand rn)
+        {
+            WriteInstruction(0x887f8000u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rt2);
+        }
+
+        public readonly void Ldaxr(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x885ffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn);
+        }
+
+        public readonly void Ldaxrb(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x085ffc00u, rt, rn);
+        }
+
+        public readonly void Ldaxrh(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x485ffc00u, rt, rn);
+        }
+
+        public readonly void LdpRiPost(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x28c00000u, 0x2cc00000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void LdpRiPre(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x29c00000u, 0x2dc00000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void LdpRiUn(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x29400000u, 0x2d400000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void LdrLit(Operand rt, int offset)
+        {
+            uint instruction = 0x18000000u | (EncodeSImm19_2(offset) << 5);
+
+            if (rt.Type == OperandType.I64)
+            {
+                instruction |= 1u << 30;
+            }
+
+            WriteInstruction(instruction, rt);
+        }
+
+        public readonly void LdrRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8400400u, 0x3c400400u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8400c00u, 0x3c400c00u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb9400000u, 0x3d400000u, rt.Type) | (EncodeUImm12(imm, rt.Type) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrRiUn(Operand rt, Operand rn, int imm, uint size)
+        {
+            uint instruction = GetLdrStrInstruction(0xb9400000u, 0x3d400000u, rt.Type, size) | (EncodeUImm12(imm, (int)size) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrRr(Operand rt, Operand rn, Operand rm, ArmExtensionType extensionType, bool shift)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8600800u, 0x3ce00800u, rt.Type);
+            WriteInstructionLdrStrAuto(instruction, rt, rn, rm, extensionType, shift);
+        }
+
+        public readonly void LdrbRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38400400u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrbRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38400c00u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrbRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x39400000u | (EncodeUImm12(imm, 0) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrhRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78400400u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrhRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78400c00u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrhRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x79400000u | (EncodeUImm12(imm, 1) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void LdrsbRiPost(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x38800400u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrsbRiPre(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x38800c00u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrsbRiUn(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x39800000u | (EncodeUImm12(imm, 0) << 10), rt, rn);
+        }
+
+        public readonly void LdrshRiPost(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x78800400u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrshRiPre(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x78800c00u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrshRiUn(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0x79800000u | (EncodeUImm12(imm, 1) << 10), rt, rn);
+        }
+
+        public readonly void LdrswRiPost(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0xb8800400u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrswRiPre(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0xb8800c00u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void LdrswRiUn(Operand rt, Operand rn, int imm)
+        {
+            WriteInstruction(0xb9800000u | (EncodeUImm12(imm, 2) << 10), rt, rn);
+        }
+
+        public readonly void Ldur(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8400000u, 0x3c400000u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldur(Operand rt, Operand rn, int imm, uint size)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8400000u, 0x3c400000u, rt.Type, size) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldurb(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38400000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldurh(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78400000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldursb(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38800000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldursh(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78800000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Ldursw(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0xb8800000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Lsl(Operand rd, Operand rn, Operand rm)
+        {
+            if (rm.Kind == OperandKind.Constant)
+            {
+                int shift = rm.AsInt32();
+                int mask = rd.Type == OperandType.I64 ? 63 : 31;
+                shift &= mask;
+                Ubfm(rd, rn, -shift & mask, mask - shift);
+            }
+            else
+            {
+                Lslv(rd, rn, rm);
+            }
+        }
+
+        public readonly void Lslv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionBitwiseAuto(0x1ac02000u, rd, rn, rm);
+        }
+
+        public readonly void Lsr(Operand rd, Operand rn, Operand rm)
+        {
+            if (rm.Kind == OperandKind.Constant)
+            {
+                int shift = rm.AsInt32();
+                int mask = rd.Type == OperandType.I64 ? 63 : 31;
+                shift &= mask;
+                Ubfm(rd, rn, shift, mask);
+            }
+            else
+            {
+                Lsrv(rd, rn, rm);
+            }
+        }
+
+        public readonly void Lsrv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionBitwiseAuto(0x1ac02400u, rd, rn, rm);
+        }
+
+        public readonly void Madd(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstructionAuto(0x1b000000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Msub(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstructionAuto(0x1b008000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Mul(Operand rd, Operand rn, Operand rm)
+        {
+            Madd(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type));
+        }
+
+        public readonly void Mov(Operand rd, Operand rn)
+        {
+            Debug.Assert(rd.Type.IsInteger());
+            Orr(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn);
+        }
+
+        public readonly void MovSp(Operand rd, Operand rn)
+        {
+            if (rd.GetRegister().Index == SpRegister ||
+                rn.GetRegister().Index == SpRegister)
+            {
+                Add(rd, rn, new Operand(rd.Type, 0), ArmShiftType.Lsl, 0, immForm: true);
+            }
+            else
+            {
+                Mov(rd, rn);
+            }
+        }
+
+        public readonly void Mov(Operand rd, ulong value)
+        {
+            if (value == 0)
+            {
+                Mov(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type));
+            }
+            else if (CodeGenCommon.TryEncodeBitMask(rd.Type, value, out _, out _, out _))
+            {
+                Orr(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), new Operand(OperandKind.Constant, rd.Type, value));
+            }
+            else if (value == ulong.MaxValue || (value == uint.MaxValue && rd.Type == OperandType.I32))
+            {
+                Mvn(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type));
+            }
+            else
+            {
+                int hw = 0;
+                bool first = true;
+
+                while (value != 0)
+                {
+                    int valueLow = (ushort)value;
+                    if (valueLow != 0)
+                    {
+                        if (first)
+                        {
+                            Movz(rd, valueLow, hw);
+                            first = false;
+                        }
+                        else
+                        {
+                            Movk(rd, valueLow, hw);
+                        }
+                    }
+
+                    hw++;
+                    value >>= 16;
+                }
+            }
+        }
+
+        public readonly void Mov(Operand rd, int imm)
+        {
+            Movz(rd, imm, 0);
+        }
+
+        public readonly void Movz(Operand rd, int imm, int hw)
+        {
+            Debug.Assert((hw & (rd.Type == OperandType.I64 ? 3 : 1)) == hw);
+            WriteInstructionAuto(0x52800000u | (EncodeUImm16(imm) << 5) | ((uint)hw << 21), rd);
+        }
+
+        public readonly void Movk(Operand rd, int imm, int hw)
+        {
+            Debug.Assert((hw & (rd.Type == OperandType.I64 ? 3 : 1)) == hw);
+            WriteInstructionAuto(0x72800000u | (EncodeUImm16(imm) << 5) | ((uint)hw << 21), rd);
+        }
+
+        public readonly void Mrs(Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2)
+        {
+            WriteSysRegInstruction(0xd5300000u, rt, o0, op1, crn, crm, op2);
+        }
+
+        public readonly void MrsNzcv(Operand rt)
+        {
+            WriteInstruction(0xd53b4200u, rt);
+        }
+
+        public readonly void MrsFpcr(Operand rt)
+        {
+            WriteInstruction(0xd53b4400u, rt);
+        }
+
+        public readonly void MrsFpsr(Operand rt)
+        {
+            WriteInstruction(0xd53b4420u, rt);
+        }
+
+        public readonly void MrsTpidrEl0(Operand rt)
+        {
+            WriteInstruction(0xd53bd040u, rt);
+        }
+
+        public readonly void MrsTpidrroEl0(Operand rt)
+        {
+            WriteInstruction(0xd53bd060u, rt);
+        }
+
+        public readonly void Msr(Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2)
+        {
+            WriteSysRegInstruction(0xd5100000u, rt, o0, op1, crn, crm, op2);
+        }
+
+        public readonly void MsrNzcv(Operand rt)
+        {
+            WriteInstruction(0xd51b4200u, rt);
+        }
+
+        public readonly void MsrFpcr(Operand rt)
+        {
+            WriteInstruction(0xd51b4400, rt);
+        }
+
+        public readonly void MsrFpsr(Operand rt)
+        {
+            WriteInstruction(0xd51b4420, rt);
+        }
+
+        public readonly void Mvn(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0)
+        {
+            Orn(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount);
+        }
+
+        public readonly void Neg(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0)
+        {
+            Sub(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount);
+        }
+
+        public readonly void Negs(Operand rd, Operand rn, ArmShiftType shiftType = ArmShiftType.Lsl, int shiftAmount = 0)
+        {
+            Subs(rd, new Operand(ZrRegister, RegisterType.Integer, rd.Type), rn, shiftType, shiftAmount);
+        }
+
+        public readonly void Orn(Operand rd, Operand rn, Operand rm)
+        {
+            Orn(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Orn(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionBitwiseAuto(0x2a200000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Orns(Operand rd, Operand rn, Operand rm)
+        {
+            Orns(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Orns(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Orn(rd, rn, rm, shiftType, shiftAmount);
+            Tst(rd, rd);
+        }
+
+        public readonly void Orr(Operand rd, Operand rn, Operand rm)
+        {
+            Orr(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Orr(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionBitwiseAuto(0x32000000u, 0x2a000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Orrs(Operand rd, Operand rn, Operand rm)
+        {
+            Orrs(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Orrs(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Orr(rd, rn, rm, shiftType, shiftAmount);
+            Tst(rd, rd);
+        }
+
+        public readonly void PrfmI(Operand rn, int imm, uint type, uint target, uint policy)
+        {
+            Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
+            WriteInstruction(0xf9800000u | (EncodeUImm12(imm, 3) << 10), rt, rn);
+        }
+
+        public readonly void PrfmR(Operand rt, Operand rn)
+        {
+            WriteInstruction(0xf8a04800u, rt, rn);
+        }
+
+        public readonly void Prfum(Operand rn, int imm, uint type, uint target, uint policy)
+        {
+            Operand rt = new Operand((int)EncodeTypeTargetPolicy(type, target, policy), RegisterType.Integer, OperandType.I32);
+            WriteInstruction(0xf8800000u | (EncodeSImm9(imm) << 12), rt, rn);
+        }
+
+        public readonly void Rbit(Operand rd, Operand rn)
+        {
+            WriteInstructionAuto(0x5ac00000u, rd, rn);
+        }
+
+        public readonly void Ret()
+        {
+            Ret(new Operand(30, RegisterType.Integer, OperandType.I64));
+        }
+
+        public readonly void Ret(Operand rn)
+        {
+            WriteUInt32(0xd65f0000u | (EncodeReg(rn) << 5));
+        }
+
+        public readonly void Rev(Operand rd, Operand rn)
+        {
+            uint opc0 = rd.Type == OperandType.I64 ? 1u << 10 : 0u;
+            WriteInstructionAuto(0x5ac00800u | opc0, rd, rn);
+        }
+
+        public readonly void Rev16(Operand rd, Operand rn)
+        {
+            WriteInstructionAuto(0x5ac00400u, rd, rn);
+        }
+
+        public readonly void Rev32(Operand rd, Operand rn)
+        {
+            WriteInstructionAuto(0xdac00800u, rd, rn);
+        }
+
+        public readonly void Ror(Operand rd, Operand rn, Operand rm)
+        {
+            if (rm.Kind == OperandKind.Constant)
+            {
+                int shift = rm.AsInt32();
+                int mask = rd.Type == OperandType.I64 ? 63 : 31;
+                shift &= mask;
+                Extr(rd, rn, rn, shift);
+            }
+            else
+            {
+                Rorv(rd, rn, rm);
+            }
+        }
+
+        public readonly void Rorv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionBitwiseAuto(0x1ac02c00u, rd, rn, rm);
+        }
+
+        public readonly void Sbc(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5a000000u, rd, rn, rm);
+        }
+
+        public readonly void Sbcs(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7a000000u, rd, rn, rm);
+        }
+
+        public readonly void Sbfm(Operand rd, Operand rn, int immr, int imms)
+        {
+            uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u;
+            WriteInstructionAuto(0x13000000u | n | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn);
+        }
+
+        public readonly void Sbfx(Operand rd, Operand rn, int lsb, int width)
+        {
+            Sbfm(rd, rn, lsb, lsb + width - 1);
+        }
+
+        public readonly void Sdiv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16Auto(0x1ac00c00u, rd, rn, rm);
+        }
+
+        public readonly void Sev()
+        {
+            WriteUInt32(0xd503209fu);
+        }
+
+        public readonly void Sevl()
+        {
+            WriteUInt32(0xd50320bfu);
+        }
+
+        public readonly void Smaddl(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstruction(0x9b200000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Smsubl(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstruction(0x9b208000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Smulh(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x9b407c00u, rd, rn, rm);
+        }
+
+        public readonly void Smull(Operand rd, Operand rn, Operand rm)
+        {
+            Smaddl(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type));
+        }
+
+        public readonly void Stlr(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x889ffc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn);
+        }
+
+        public readonly void Stlrb(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x089ffc00u, rt, rn);
+        }
+
+        public readonly void Stlrh(Operand rt, Operand rn)
+        {
+            WriteInstruction(0x489ffc00u, rt, rn);
+        }
+
+        public readonly void Stlxp(Operand rs, Operand rt, Operand rt2, Operand rn)
+        {
+            WriteInstruction(0x88208000u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rs, rt2);
+        }
+
+        public readonly void Stlxr(Operand rs, Operand rt, Operand rn)
+        {
+            WriteInstructionRm16(0x8800fc00u | ((rt.Type == OperandType.I64 ? 3u : 2u) << 30), rt, rn, rs);
+        }
+
+        public readonly void Stlxrb(Operand rs, Operand rt, Operand rn)
+        {
+            WriteInstructionRm16(0x0800fc00u, rt, rn, rs);
+        }
+
+        public readonly void Stlxrh(Operand rs, Operand rt, Operand rn)
+        {
+            WriteInstructionRm16(0x4800fc00u, rt, rn, rs);
+        }
+
+        public readonly void StpRiPost(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x28800000u, 0x2c800000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void StpRiPre(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x29800000u, 0x2d800000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void StpRiUn(Operand rt, Operand rt2, Operand rn, int imm)
+        {
+            uint instruction = GetLdpStpInstruction(0x29000000u, 0x2d000000u, imm, rt.Type);
+            WriteInstruction(instruction, rt, rn, rt2);
+        }
+
+        public readonly void StrRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8000400u, 0x3c000400u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8000c00u, 0x3c000c00u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb9000000u, 0x3d000000u, rt.Type) | (EncodeUImm12(imm, rt.Type) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrRiUn(Operand rt, Operand rn, int imm, uint size)
+        {
+            uint instruction = GetLdrStrInstruction(0xb9000000u, 0x3d000000u, rt.Type, size) | (EncodeUImm12(imm, (int)size) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrRr(Operand rt, Operand rn, Operand rm, ArmExtensionType extensionType, bool shift)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8200800u, 0x3ca00800u, rt.Type);
+            WriteInstructionLdrStrAuto(instruction, rt, rn, rm, extensionType, shift);
+        }
+
+        public readonly void StrbRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38000400u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrbRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38000c00u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrbRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x39000000u | (EncodeUImm12(imm, 0) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrhRiPost(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78000400u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrhRiPre(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78000c00u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void StrhRiUn(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x79000000u | (EncodeUImm12(imm, 1) << 10);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Stur(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8000000u, 0x3c000000u, rt.Type) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Stur(Operand rt, Operand rn, int imm, uint size)
+        {
+            uint instruction = GetLdrStrInstruction(0xb8000000u, 0x3c000000u, rt.Type, size) | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Sturb(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x38000000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Sturh(Operand rt, Operand rn, int imm)
+        {
+            uint instruction = 0x78000000u | (EncodeSImm9(imm) << 12);
+            WriteInstruction(instruction, rt, rn);
+        }
+
+        public readonly void Sub(Operand rd, Operand rn, Operand rm, ArmExtensionType extensionType, int shiftAmount = 0)
+        {
+            WriteInstructionAuto(0x4b200000u, rd, rn, rm, extensionType, shiftAmount);
+        }
+
+        public readonly void Sub(Operand rd, Operand rn, Operand rm)
+        {
+            Sub(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Sub(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionAuto(0x51000000u, 0x4b000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Subs(Operand rd, Operand rn, Operand rm)
+        {
+            Subs(rd, rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Subs(Operand rd, Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            WriteInstructionAuto(0x71000000u, 0x6b000000u, rd, rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Sxtb(Operand rd, Operand rn)
+        {
+            Sbfm(rd, rn, 0, 7);
+        }
+
+        public readonly void Sxth(Operand rd, Operand rn)
+        {
+            Sbfm(rd, rn, 0, 15);
+        }
+
+        public readonly void Sxtw(Operand rd, Operand rn)
+        {
+            Sbfm(rd, rn, 0, 31);
+        }
+
+        public readonly void Tsb()
+        {
+            WriteUInt32(0xd503225fu);
+        }
+
+        public readonly void Tst(Operand rn, Operand rm)
+        {
+            Tst(rn, rm, ArmShiftType.Lsl, 0);
+        }
+
+        public readonly void Tst(Operand rn, Operand rm, ArmShiftType shiftType, int shiftAmount)
+        {
+            Ands(new Operand(ZrRegister, RegisterType.Integer, rn.Type), rn, rm, shiftType, shiftAmount);
+        }
+
+        public readonly void Ubfm(Operand rd, Operand rn, int immr, int imms)
+        {
+            uint n = rd.Type == OperandType.I64 ? 1u << 22 : 0u;
+            WriteInstructionAuto(0x53000000u | n | (EncodeUImm6(imms) << 10) | (EncodeUImm6(immr) << 16), rd, rn);
+        }
+
+        public readonly void Ubfx(Operand rd, Operand rn, int lsb, int width)
+        {
+            Ubfm(rd, rn, lsb, lsb + width - 1);
+        }
+
+        public readonly void Udiv(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16Auto(0x1ac00800u, rd, rn, rm);
+        }
+
+        public readonly void Umaddl(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstructionAuto(0x9ba00000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Umulh(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x9bc07c00u, rd, rn, rm);
+        }
+
+        public readonly void Umull(Operand rd, Operand rn, Operand rm)
+        {
+            Umaddl(rd, rn, rm, new Operand(ZrRegister, RegisterType.Integer, rd.Type));
+        }
+
+        public readonly void Uxtb(Operand rd, Operand rn)
+        {
+            Ubfm(rd, rn, 0, 7);
+        }
+
+        public readonly void Uxth(Operand rd, Operand rn)
+        {
+            Ubfm(rd, rn, 0, 15);
+        }
+
+        // FP & SIMD
+
+        public readonly void AbsS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e20b800u | (size << 22), rd, rn);
+        }
+
+        public readonly void AbsV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e20b800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Addhn(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e204000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void AddpPair(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e31b800u | (size << 22), rd, rn);
+        }
+
+        public readonly void AddpVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20bc00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Addv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e31b800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void AddS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e208400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void AddV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e208400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Aesd(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x4e285800u, rd, rn);
+        }
+
+        public readonly void Aese(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x4e284800u, rd, rn);
+        }
+
+        public readonly void Aesimc(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x4e287800u, rd, rn);
+        }
+
+        public readonly void Aesmc(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x4e286800u, rd, rn);
+        }
+
+        public readonly void And(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e201c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Bcax(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstruction(0xce200000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Bfcvtn(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ea16800u | (q << 30), rd, rn);
+        }
+
+        public readonly void BfcvtFloat(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e634000u, rd, rn);
+        }
+
+        public readonly void BfdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f40f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void BfdotVec(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e40fc00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void BfmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0fc0f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void BfmlalVec(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec0fc00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Bfmmla(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x6e40ec00u, rd, rn, rm);
+        }
+
+        public readonly void BicImm(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q)
+        {
+            WriteInstruction(0x2f001400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd);
+        }
+
+        public readonly void BicReg(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e601c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Bif(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ee01c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Bit(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ea01c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Bsl(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e601c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Cls(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e204800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Clz(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e204800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmeqRegS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e208c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmeqRegV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e208c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void CmeqZeroS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e209800u | (size << 22), rd, rn);
+        }
+
+        public readonly void CmeqZeroV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e209800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmgeRegS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e203c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmgeRegV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e203c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void CmgeZeroS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e208800u | (size << 22), rd, rn);
+        }
+
+        public readonly void CmgeZeroV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e208800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmgtRegS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e203400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmgtRegV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e203400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void CmgtZeroS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e208800u | (size << 22), rd, rn);
+        }
+
+        public readonly void CmgtZeroV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e208800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmhiS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e203400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmhiV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e203400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void CmhsS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e203c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmhsV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e203c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void CmleS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e209800u | (size << 22), rd, rn);
+        }
+
+        public readonly void CmleV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e209800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmltS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e20a800u | (size << 22), rd, rn);
+        }
+
+        public readonly void CmltV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e20a800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void CmtstS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e208c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void CmtstV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e208c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Cnt(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e205800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void DupEltScalarFromElement(Operand rd, Operand rn, uint imm5)
+        {
+            WriteInstruction(0x5e000400u | (imm5 << 16), rd, rn);
+        }
+
+        public readonly void DupEltVectorFromElement(Operand rd, Operand rn, uint imm5, uint q)
+        {
+            WriteInstruction(0x0e000400u | (imm5 << 16) | (q << 30), rd, rn);
+        }
+
+        public readonly void DupGen(Operand rd, Operand rn, uint imm5, uint q)
+        {
+            WriteInstruction(0x0e000c00u | (imm5 << 16) | (q << 30), rd, rn);
+        }
+
+        public readonly void Eor3(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstruction(0xce000000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Eor(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e201c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Ext(Operand rd, Operand rn, uint imm4, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e000000u | (imm4 << 11) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FabdSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7ec01400u, rd, rn, rm);
+        }
+
+        public readonly void FabdS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x7ea0d400u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FabdVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec01400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FabdV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2ea0d400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FabsHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef8f800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FabsSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea0f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FabsFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e20c000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FacgeSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7e402c00u, rd, rn, rm);
+        }
+
+        public readonly void FacgeS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x7e20ec00u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FacgeVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e402c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FacgeV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20ec00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FacgtSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7ec02c00u, rd, rn, rm);
+        }
+
+        public readonly void FacgtS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x7ea0ec00u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FacgtVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec02c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FacgtV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2ea0ec00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FaddpPairHalf(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e30d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FaddpPairSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e30d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FaddpVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e401400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FaddpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20d400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FaddHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e401400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FaddSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20d400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FaddFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e202800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FcaddVec(Operand rd, Operand rn, uint rot, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e00e400u | (rot << 12) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FccmpeFloat(uint nzcv, Operand rn, uint cond, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e200410u | (nzcv << 0) | (cond << 12) | (ftype << 22), rn, rm);
+        }
+
+        public readonly void FccmpFloat(uint nzcv, Operand rn, uint cond, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e200400u | (nzcv << 0) | (cond << 12) | (ftype << 22), rn, rm);
+        }
+
+        public readonly void FcmeqRegSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e402400u, rd, rn, rm);
+        }
+
+        public readonly void FcmeqRegS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x5e20e400u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FcmeqRegVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e402400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmeqRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20e400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmeqZeroSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef8d800u, rd, rn);
+        }
+
+        public readonly void FcmeqZeroS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea0d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcmeqZeroVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef8d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmeqZeroV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea0d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmgeRegSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7e402400u, rd, rn, rm);
+        }
+
+        public readonly void FcmgeRegS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x7e20e400u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FcmgeRegVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e402400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmgeRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20e400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmgeZeroSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7ef8c800u, rd, rn);
+        }
+
+        public readonly void FcmgeZeroS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7ea0c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcmgeZeroVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef8c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmgeZeroV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea0c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmgtRegSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x7ec02400u, rd, rn, rm);
+        }
+
+        public readonly void FcmgtRegS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x7ea0e400u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FcmgtRegVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec02400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmgtRegV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2ea0e400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmgtZeroSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef8c800u, rd, rn);
+        }
+
+        public readonly void FcmgtZeroS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea0c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcmgtZeroVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef8c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmgtZeroV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea0c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmlaElt(Operand rd, Operand rn, uint h, uint rot, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f001000u | (h << 11) | (rot << 13) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmlaVec(Operand rd, Operand rn, uint rot, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e00c400u | (rot << 11) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FcmleSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7ef8d800u, rd, rn);
+        }
+
+        public readonly void FcmleS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7ea0d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcmleVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef8d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmleV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea0d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmltSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef8e800u, rd, rn);
+        }
+
+        public readonly void FcmltS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea0e800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcmltVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef8e800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmltV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea0e800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcmpeFloat(Operand rn, Operand rm, uint opc, uint ftype)
+        {
+            WriteInstructionRm16(0x1e202010u | (opc << 3) | (ftype << 22), rn, rm);
+        }
+
+        public readonly void FcmpFloat(Operand rn, Operand rm, uint opc, uint ftype)
+        {
+            WriteInstructionRm16(0x1e202000u | (opc << 3) | (ftype << 22), rn, rm);
+        }
+
+        public readonly void FcselFloat(Operand rd, Operand rn, uint cond, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e200c00u | (cond << 12) | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FcvtasSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e79c800u, rd, rn);
+        }
+
+        public readonly void FcvtasS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e21c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtasVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e79c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtasV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtasFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e240000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtauSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7e79c800u, rd, rn);
+        }
+
+        public readonly void FcvtauS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e21c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtauVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e79c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtauV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtauFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e250000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void Fcvtl(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e217800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtmsSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e79b800u, rd, rn);
+        }
+
+        public readonly void FcvtmsS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e21b800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtmsVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e79b800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtmsV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21b800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtmsFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e300000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtmuSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7e79b800u, rd, rn);
+        }
+
+        public readonly void FcvtmuS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e21b800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtmuVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e79b800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtmuV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21b800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtmuFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e310000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtnsSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e79a800u, rd, rn);
+        }
+
+        public readonly void FcvtnsS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e21a800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtnsVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e79a800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtnsV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21a800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtnsFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e200000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtnuSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7e79a800u, rd, rn);
+        }
+
+        public readonly void FcvtnuS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e21a800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtnuVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e79a800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtnuV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21a800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtnuFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e210000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void Fcvtn(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e216800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtpsSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef9a800u, rd, rn);
+        }
+
+        public readonly void FcvtpsS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea1a800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtpsVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef9a800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtpsV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea1a800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtpsFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e280000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtpuSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7ef9a800u, rd, rn);
+        }
+
+        public readonly void FcvtpuS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7ea1a800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtpuVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef9a800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtpuV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea1a800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtpuFloat(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e290000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtxnS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e216800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtxnV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e216800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzsFixS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f00fc00u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void FcvtzsFixV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f00fc00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzsIntSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef9b800u, rd, rn);
+        }
+
+        public readonly void FcvtzsIntS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea1b800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtzsIntVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef9b800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzsIntV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea1b800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzsFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e180000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtzsFloatInt(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e380000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtzuFixS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f00fc00u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void FcvtzuFixV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f00fc00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzuIntSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7ef9b800u, rd, rn);
+        }
+
+        public readonly void FcvtzuIntS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7ea1b800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FcvtzuIntVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef9b800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzuIntV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea1b800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FcvtzuFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e190000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtzuFloatInt(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e390000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FcvtFloat(Operand rd, Operand rn, uint opc, uint ftype)
+        {
+            WriteInstruction(0x1e224000u | (opc << 15) | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FdivHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e403c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FdivSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20fc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FdivFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e201800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void Fjcvtzs(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e7e0000u, rd, rn);
+        }
+
+        public readonly void FmaddFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype)
+        {
+            WriteInstruction(0x1f000000u | (ftype << 22), rd, rn, rm, ra);
+        }
+
+        public readonly void FmaxnmpPairHalf(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e30c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FmaxnmpPairSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e30c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FmaxnmpVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e400400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxnmpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20c400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxnmvHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e30c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FmaxnmvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e30c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FmaxnmHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e400400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxnmSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20c400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxnmFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e206800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FmaxpPairHalf(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e30f800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FmaxpPairSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e30f800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FmaxpVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e403400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20f400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxvHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e30f800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FmaxvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e30f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FmaxHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e403400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20f400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmaxFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e204800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FminnmpPairHalf(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5eb0c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FminnmpPairSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7eb0c800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FminnmpVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec00400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminnmpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2ea0c400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminnmvHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0eb0c800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FminnmvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2eb0c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FminnmHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ec00400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminnmSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0ea0c400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminnmFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e207800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FminpPairHalf(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5eb0f800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FminpPairSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7eb0f800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FminpVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ec03400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminpVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2ea0f400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminvHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0eb0f800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FminvSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2eb0f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FminHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ec03400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0ea0f400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FminFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e205800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FmlalEltFmlal(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f800000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlalEltFmlal2(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x2f808000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlalVecFmlal(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e20ec00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlalVecFmlal2(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e20cc00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlaElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l)
+        {
+            WriteInstructionRm16(0x5f001000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm);
+        }
+
+        public readonly void FmlaElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz)
+        {
+            WriteInstructionRm16(0x5f801000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FmlaElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f001000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlaElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0f801000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlaVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e400c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlaVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20cc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlslEltFmlsl(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f804000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlslEltFmlsl2(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x2f80c000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlslVecFmlsl(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ea0ec00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlslVecFmlsl2(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2ea0cc00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlsElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l)
+        {
+            WriteInstructionRm16(0x5f005000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm);
+        }
+
+        public readonly void FmlsElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz)
+        {
+            WriteInstructionRm16(0x5f805000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FmlsElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f005000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlsElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0f805000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlsVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ec00c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmlsVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0ea0cc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmovPerHalf(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q)
+        {
+            WriteInstruction(0x0f00fc00u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd);
+        }
+
+        public readonly void FmovSingleAndDouble(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint op, uint q)
+        {
+            WriteInstruction(0x0f00f400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (op << 29) | (q << 30), rd);
+        }
+
+        public readonly void FmovFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e204000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FmovFloatGen(Operand rd, Operand rn, uint ftype, uint sf, uint dir, uint top)
+        {
+            WriteInstruction(0x1e260000u | (dir << 16) | (top << 19) | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void FmovFloatImm(Operand rd, uint imm8, uint ftype)
+        {
+            WriteInstruction(0x1e201000u | (imm8 << 13) | (ftype << 22), rd);
+        }
+
+        public readonly void FmsubFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype)
+        {
+            WriteInstruction(0x1f008000u | (ftype << 22), rd, rn, rm, ra);
+        }
+
+        public readonly void FmulxElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l)
+        {
+            WriteInstructionRm16(0x7f009000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm);
+        }
+
+        public readonly void FmulxElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz)
+        {
+            WriteInstructionRm16(0x7f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FmulxElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x2f009000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulxElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulxVecSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e401c00u, rd, rn, rm);
+        }
+
+        public readonly void FmulxVecS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x5e20dc00u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FmulxVecVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e401c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulxVecV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20dc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulElt2regScalarHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l)
+        {
+            WriteInstructionRm16(0x5f009000u | (h << 11) | (m << 20) | (l << 21), rd, rn, rm);
+        }
+
+        public readonly void FmulElt2regScalarSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz)
+        {
+            WriteInstructionRm16(0x5f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FmulElt2regElementHalf(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f009000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulElt2regElementSingleAndDouble(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0f809000u | (h << 11) | (m << 20) | (l << 21) | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulVecHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x2e401c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulVecSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x2e20dc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FmulFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e200800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FnegHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef8f800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FnegSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea0f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FnegFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e214000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FnmaddFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype)
+        {
+            WriteInstruction(0x1f200000u | (ftype << 22), rd, rn, rm, ra);
+        }
+
+        public readonly void FnmsubFloat(Operand rd, Operand rn, Operand rm, Operand ra, uint ftype)
+        {
+            WriteInstruction(0x1f208000u | (ftype << 22), rd, rn, rm, ra);
+        }
+
+        public readonly void FnmulFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e208800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void FrecpeSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef9d800u, rd, rn);
+        }
+
+        public readonly void FrecpeS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea1d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FrecpeVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef9d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrecpeV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea1d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrecpsSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e403c00u, rd, rn, rm);
+        }
+
+        public readonly void FrecpsS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x5e20fc00u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FrecpsVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e403c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FrecpsV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0e20fc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FrecpxHalf(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5ef9f800u, rd, rn);
+        }
+
+        public readonly void FrecpxSingleAndDouble(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5ea1f800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void Frint32x(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21e800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Frint32xFloat(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e28c000u, rd, rn);
+        }
+
+        public readonly void Frint32z(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21e800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Frint32zFloat(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e284000u, rd, rn);
+        }
+
+        public readonly void Frint64x(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Frint64xFloat(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e29c000u, rd, rn);
+        }
+
+        public readonly void Frint64z(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Frint64zFloat(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x1e294000u, rd, rn);
+        }
+
+        public readonly void FrintaHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e798800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintaSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e218800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintaFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e264000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintiHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef99800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintiSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea19800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintiFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e27c000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintmHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e799800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintmSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e219800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintmFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e254000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintnHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e798800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintnSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e218800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintnFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e244000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintpHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef98800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintpSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea18800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintpFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e24c000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintxHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e799800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintxSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e219800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintxFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e274000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrintzHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0ef99800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintzSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea19800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrintzFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e25c000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FrsqrteSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7ef9d800u, rd, rn);
+        }
+
+        public readonly void FrsqrteS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7ea1d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void FrsqrteVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef9d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FrsqrteV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea1d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FrsqrtsSH(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5ec03c00u, rd, rn, rm);
+        }
+
+        public readonly void FrsqrtsS(Operand rd, Operand rn, Operand rm, uint sz)
+        {
+            WriteInstructionRm16(0x5ea0fc00u | (sz << 22), rd, rn, rm);
+        }
+
+        public readonly void FrsqrtsVH(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ec03c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FrsqrtsV(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0ea0fc00u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FsqrtHalf(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2ef9f800u | (q << 30), rd, rn);
+        }
+
+        public readonly void FsqrtSingleAndDouble(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea1f800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void FsqrtFloat(Operand rd, Operand rn, uint ftype)
+        {
+            WriteInstruction(0x1e21c000u | (ftype << 22), rd, rn);
+        }
+
+        public readonly void FsubHalf(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ec01400u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FsubSingleAndDouble(Operand rd, Operand rn, Operand rm, uint sz, uint q)
+        {
+            WriteInstructionRm16(0x0ea0d400u | (sz << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void FsubFloat(Operand rd, Operand rn, Operand rm, uint ftype)
+        {
+            WriteInstructionRm16(0x1e203800u | (ftype << 22), rd, rn, rm);
+        }
+
+        public readonly void InsElt(Operand rd, Operand rn, uint imm4, uint imm5)
+        {
+            WriteInstruction(0x6e000400u | (imm4 << 11) | (imm5 << 16), rd, rn);
+        }
+
+        public readonly void InsGen(Operand rd, Operand rn, uint imm5)
+        {
+            WriteInstruction(0x4e001c00u | (imm5 << 16), rd, rn);
+        }
+
+        public readonly void Ld1rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0d40c000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld1rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0dc0c000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld1MultAsNoPostIndex(Operand rt, Operand rn, uint registersCount, uint size, uint q)
+        {
+            WriteInstruction(0x0c402000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld1MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint registersCount, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0cc02000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld1SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d400000u, index, size), rt, rn);
+        }
+
+        public readonly void Ld1SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0dc00000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void Ld2rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0d60c000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld2rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0de0c000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld2MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c408000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld2MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0cc08000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld2SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d600000u, index, size), rt, rn);
+        }
+
+        public readonly void Ld2SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0de00000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void Ld3rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0d40e000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld3rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0dc0e000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld3MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c404000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld3MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0cc04000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld3SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d402000u, index, size), rt, rn);
+        }
+
+        public readonly void Ld3SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0dc02000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void Ld4rAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0d60e000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld4rAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0de0e000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld4MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c400000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void Ld4MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0cc00000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void Ld4SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d602000u, index, size), rt, rn);
+        }
+
+        public readonly void Ld4SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0de02000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void Ldap1Sngl(Operand rt, Operand rn, uint q)
+        {
+            WriteInstruction(0x0d418400u | (q << 30), rt, rn);
+        }
+
+        public readonly void Ldra(Operand rt, Operand rn, uint w, uint imm9, uint s, uint m)
+        {
+            WriteInstruction(0xf8200400u | (w << 11) | (imm9 << 12) | (s << 22) | (m << 23), rt, rn);
+        }
+
+        public readonly void MlaElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f000000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void MlaVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e209400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void MlsElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f004000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void MlsVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e209400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Movi(Operand rd, uint h, uint g, uint f, uint e, uint d, uint cmode, uint c, uint b, uint a, uint op, uint q)
+        {
+            WriteInstruction(0x0f000400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (cmode << 12) | (c << 16) | (b << 17) | (a << 18) | (op << 29) | (q << 30), rd);
+        }
+
+        public readonly void MulElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f008000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void MulVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e209c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Mvni(Operand rd, uint h, uint g, uint f, uint e, uint d, uint cmode, uint c, uint b, uint a, uint q)
+        {
+            WriteInstruction(0x2f000400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (cmode << 12) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd);
+        }
+
+        public readonly void NegS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e20b800u | (size << 22), rd, rn);
+        }
+
+        public readonly void NegV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e20b800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Not(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e205800u | (q << 30), rd, rn);
+        }
+
+        public readonly void Orn(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ee01c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void OrrImm(Operand rd, uint h, uint g, uint f, uint e, uint d, uint c, uint b, uint a, uint q)
+        {
+            WriteInstruction(0x0f001400u | (h << 5) | (g << 6) | (f << 7) | (e << 8) | (d << 9) | (c << 16) | (b << 17) | (a << 18) | (q << 30), rd);
+        }
+
+        public readonly void OrrReg(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0ea01c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Pmull(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20e000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Pmul(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e209c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Raddhn(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e204000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Rax1(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce608c00u, rd, rn, rm);
+        }
+
+        public readonly void Rbit(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e605800u | (q << 30), rd, rn);
+        }
+
+        public readonly void Rev16(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e201800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Rev32(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e200800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Rev64(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e200800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Rshrn(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f008c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Rsubhn(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e206000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sabal(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e205000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Saba(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e207c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sabdl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e207000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sabd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e207400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sadalp(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e206800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Saddlp(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e202800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Saddlv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e303800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Saddl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e200000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Saddw(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e201000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void ScvtfFixS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f00e400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void ScvtfFixV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f00e400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void ScvtfIntSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e79d800u, rd, rn);
+        }
+
+        public readonly void ScvtfIntS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x5e21d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void ScvtfIntVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x0e79d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void ScvtfIntV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0e21d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void ScvtfFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e020000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void ScvtfFloatInt(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e220000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void SdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f00e000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SdotVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e009400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sha1c(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e000000u, rd, rn, rm);
+        }
+
+        public readonly void Sha1h(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e280800u, rd, rn);
+        }
+
+        public readonly void Sha1m(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e002000u, rd, rn, rm);
+        }
+
+        public readonly void Sha1p(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e001000u, rd, rn, rm);
+        }
+
+        public readonly void Sha1su0(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e003000u, rd, rn, rm);
+        }
+
+        public readonly void Sha1su1(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e281800u, rd, rn);
+        }
+
+        public readonly void Sha256h2(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e005000u, rd, rn, rm);
+        }
+
+        public readonly void Sha256h(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e004000u, rd, rn, rm);
+        }
+
+        public readonly void Sha256su0(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x5e282800u, rd, rn);
+        }
+
+        public readonly void Sha256su1(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x5e006000u, rd, rn, rm);
+        }
+
+        public readonly void Sha512h2(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce608400u, rd, rn, rm);
+        }
+
+        public readonly void Sha512h(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce608000u, rd, rn, rm);
+        }
+
+        public readonly void Sha512su0(Operand rd, Operand rn)
+        {
+            WriteInstruction(0xcec08000u, rd, rn);
+        }
+
+        public readonly void Sha512su1(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce608800u, rd, rn, rm);
+        }
+
+        public readonly void Shadd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e200400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Shll(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e213800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void ShlS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f005400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void ShlV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f005400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Shrn(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f008400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Shsub(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e202400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SliS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f005400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SliV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f005400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Sm3partw1(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce60c000u, rd, rn, rm);
+        }
+
+        public readonly void Sm3partw2(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce60c400u, rd, rn, rm);
+        }
+
+        public readonly void Sm3ss1(Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteInstruction(0xce400000u, rd, rn, rm, ra);
+        }
+
+        public readonly void Sm3tt1a(Operand rd, Operand rn, uint imm2, Operand rm)
+        {
+            WriteInstructionRm16(0xce408000u | (imm2 << 12), rd, rn, rm);
+        }
+
+        public readonly void Sm3tt1b(Operand rd, Operand rn, uint imm2, Operand rm)
+        {
+            WriteInstructionRm16(0xce408400u | (imm2 << 12), rd, rn, rm);
+        }
+
+        public readonly void Sm3tt2a(Operand rd, Operand rn, uint imm2, Operand rm)
+        {
+            WriteInstructionRm16(0xce408800u | (imm2 << 12), rd, rn, rm);
+        }
+
+        public readonly void Sm3tt2b(Operand rd, Operand rn, uint imm2, Operand rm)
+        {
+            WriteInstructionRm16(0xce408c00u | (imm2 << 12), rd, rn, rm);
+        }
+
+        public readonly void Sm4ekey(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0xce60c800u, rd, rn, rm);
+        }
+
+        public readonly void Sm4e(Operand rd, Operand rn)
+        {
+            WriteInstruction(0xcec08400u, rd, rn);
+        }
+
+        public readonly void Smaxp(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20a400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Smaxv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e30a800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Smax(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e206400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sminp(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20ac00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Sminv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e31a800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Smin(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e206c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f002000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmlalVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e208000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmlslElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f006000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmlslVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20a000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmmlaVec(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x4e80a400u, rd, rn, rm);
+        }
+
+        public readonly void Smov(Operand rd, Operand rn, int index, int size)
+        {
+            uint q = size == 2 ? 1u << 30 : 0u;
+            WriteInstruction(0x0e002c00u | (EncodeIndexSizeImm5(index, size) << 16) | q, rd, rn);
+        }
+
+        public readonly void SmullElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f00a000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SmullVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20c000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqabsS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e207800u | (size << 22), rd, rn);
+        }
+
+        public readonly void SqabsV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e207800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqaddS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e200c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqaddV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e200c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmlalElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x5f003000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmlalElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f003000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmlalVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e209000u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmlalVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e209000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmlslElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x5f007000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmlslElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f007000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmlslVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e20b000u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmlslVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20b000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmulhElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x5f00c000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmulhElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f00c000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmulhVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e20b400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmulhVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20b400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmullElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x5f00b000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmullElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f00b000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqdmullVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e20d000u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqdmullVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e20d000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqnegS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e207800u | (size << 22), rd, rn);
+        }
+
+        public readonly void SqnegV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e207800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqrdmlahElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x7f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlahElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlahVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e008400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlahVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e008400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlshElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x7f00f000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlshElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f00f000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlshVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e008c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmlshVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e008c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrdmulhElt2regScalar(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size)
+        {
+            WriteInstructionRm16(0x5f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmulhElt2regElement(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0f00d000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrdmulhVecS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e20b400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrdmulhVecV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e20b400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e205c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e205c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqrshrnS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f009c00u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqrshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f009c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqrshrunS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f008c00u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqrshrunV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f008c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqshluS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f006400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqshluV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f006400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqshlImmS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f007400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqshlImmV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f007400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqshlRegS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e204c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqshlRegV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e204c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqshrnS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f009400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f009400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqshrunS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f008400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SqshrunV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f008400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqsubS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e202c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SqsubV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e202c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SqxtnS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e214800u | (size << 22), rd, rn);
+        }
+
+        public readonly void SqxtnV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e214800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void SqxtunS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e212800u | (size << 22), rd, rn);
+        }
+
+        public readonly void SqxtunV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e212800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Srhadd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e201400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SriS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f004400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SriV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f004400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SrshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e205400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e205400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SrshrS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f002400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SrshrV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f002400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SrsraS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f003400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SrsraV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f003400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Sshll(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f00a400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x5e204400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e204400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SshrS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f000400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SshrV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f000400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void SsraS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x5f001400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void SsraV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x0f001400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Ssubl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e202000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Ssubw(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e203000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void St1MultAsNoPostIndex(Operand rt, Operand rn, uint registersCount, uint size, uint q)
+        {
+            WriteInstruction(0x0c002000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn);
+        }
+
+        public readonly void St1MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint registersCount, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0c802000u | (size << 10) | (EncodeLdSt1MultOpcode(registersCount) << 12) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void St1SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d000000u, index, size), rt, rn);
+        }
+
+        public readonly void St1SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0d800000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void St2MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c008000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void St2MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0c808000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void St2SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d200000u, index, size), rt, rn);
+        }
+
+        public readonly void St2SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0da00000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void St3MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c004000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void St3MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0c804000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void St3SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d002000u, index, size), rt, rn);
+        }
+
+        public readonly void St3SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0d802000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void St4MultAsNoPostIndex(Operand rt, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0c000000u | (size << 10) | (q << 30), rt, rn);
+        }
+
+        public readonly void St4MultAsPostIndex(Operand rt, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0c800000u | (size << 10) | (q << 30), rt, rn, rm);
+        }
+
+        public readonly void St4SnglAsNoPostIndex(Operand rt, Operand rn, uint index, uint size)
+        {
+            WriteInstruction(EncodeIndexSizeSngl(0x0d202000u, index, size), rt, rn);
+        }
+
+        public readonly void St4SnglAsPostIndex(Operand rt, Operand rn, Operand rm, uint index, uint size)
+        {
+            WriteInstructionRm16(EncodeIndexSizeSngl(0x0da02000u, index, size), rt, rn, rm);
+        }
+
+        public readonly void Stl1Sngl(Operand rt, Operand rn, uint q)
+        {
+            WriteInstruction(0x0d018400u | (q << 30), rt, rn);
+        }
+
+        public readonly void Subhn(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e206000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SubS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e208400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void SubV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e208400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SudotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f00f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void SuqaddS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x5e203800u | (size << 22), rd, rn);
+        }
+
+        public readonly void SuqaddV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e203800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Tbl(Operand rd, Operand rn, uint len, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e000000u | (len << 13) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Tbx(Operand rd, Operand rn, uint len, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e001000u | (len << 13) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Trn1(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e002800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Trn2(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e006800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uabal(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e205000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uaba(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e207c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uabdl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e207000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uabd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e207400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uadalp(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e206800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Uaddlp(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e202800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Uaddlv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e303800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Uaddl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e200000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uaddw(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e201000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UcvtfFixS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f00e400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UcvtfFixV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f00e400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UcvtfIntSH(Operand rd, Operand rn)
+        {
+            WriteInstruction(0x7e79d800u, rd, rn);
+        }
+
+        public readonly void UcvtfIntS(Operand rd, Operand rn, uint sz)
+        {
+            WriteInstruction(0x7e21d800u | (sz << 22), rd, rn);
+        }
+
+        public readonly void UcvtfIntVH(Operand rd, Operand rn, uint q)
+        {
+            WriteInstruction(0x2e79d800u | (q << 30), rd, rn);
+        }
+
+        public readonly void UcvtfIntV(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2e21d800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void UcvtfFloatFix(Operand rd, Operand rn, uint scale, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e030000u | (scale << 10) | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void UcvtfFloatInt(Operand rd, Operand rn, uint ftype, uint sf)
+        {
+            WriteInstruction(0x1e230000u | (ftype << 22) | (sf << 31), rd, rn);
+        }
+
+        public readonly void UdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f00e000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UdotVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e009400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uhadd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e200400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uhsub(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e202400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Umaxp(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e20a400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Umaxv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e30a800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Umax(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e206400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uminp(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e20ac00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uminv(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e31a800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Umin(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e206c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmlalElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f002000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmlalVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e208000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmlslElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f006000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmlslVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e20a000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmmlaVec(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x6e80a400u, rd, rn, rm);
+        }
+
+        public readonly void Umov(Operand rd, Operand rn, int index, int size)
+        {
+            uint q = size == 3 ? 1u << 30 : 0u;
+            WriteInstruction(0x0e003c00u | (EncodeIndexSizeImm5(index, size) << 16) | q, rd, rn);
+        }
+
+        public readonly void UmullElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2f00a000u | (h << 11) | (m << 20) | (l << 21) | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UmullVec(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e20c000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UqaddS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e200c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UqaddV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e200c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UqrshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e205c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UqrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e205c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UqrshrnS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f009c00u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UqrshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f009c00u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UqshlImmS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f007400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UqshlImmV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f007400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UqshlRegS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e204c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UqshlRegV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e204c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UqshrnS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f009400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UqshrnV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f009400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UqsubS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e202c00u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UqsubV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e202c00u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UqxtnS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e214800u | (size << 22), rd, rn);
+        }
+
+        public readonly void UqxtnV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e214800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Urecpe(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x0ea1c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Urhadd(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e201400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UrshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e205400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UrshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e205400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UrshrS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f002400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UrshrV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f002400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Ursqrte(Operand rd, Operand rn, uint sz, uint q)
+        {
+            WriteInstruction(0x2ea1c800u | (sz << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void UrsraS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f003400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UrsraV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f003400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UsdotElt(Operand rd, Operand rn, uint h, Operand rm, uint m, uint l, uint q)
+        {
+            WriteInstructionRm16(0x0f80f000u | (h << 11) | (m << 20) | (l << 21) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UsdotVec(Operand rd, Operand rn, Operand rm, uint q)
+        {
+            WriteInstructionRm16(0x0e809c00u | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Ushll(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f00a400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UshlS(Operand rd, Operand rn, Operand rm, uint size)
+        {
+            WriteInstructionRm16(0x7e204400u | (size << 22), rd, rn, rm);
+        }
+
+        public readonly void UshlV(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e204400u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void UshrS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f000400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UshrV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f000400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void UsmmlaVec(Operand rd, Operand rn, Operand rm)
+        {
+            WriteInstructionRm16(0x4e80ac00u, rd, rn, rm);
+        }
+
+        public readonly void UsqaddS(Operand rd, Operand rn, uint size)
+        {
+            WriteInstruction(0x7e203800u | (size << 22), rd, rn);
+        }
+
+        public readonly void UsqaddV(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x2e203800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void UsraS(Operand rd, Operand rn, uint immb, uint immh)
+        {
+            WriteInstruction(0x7f001400u | (immb << 16) | (immh << 19), rd, rn);
+        }
+
+        public readonly void UsraV(Operand rd, Operand rn, uint immb, uint immh, uint q)
+        {
+            WriteInstruction(0x2f001400u | (immb << 16) | (immh << 19) | (q << 30), rd, rn);
+        }
+
+        public readonly void Usubl(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e202000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Usubw(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x2e203000u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uzp1(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e001800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Uzp2(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e005800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Wfe()
+        {
+            WriteUInt32(0xd503205fu);
+        }
+
+        public readonly void Wfi()
+        {
+            WriteUInt32(0xd503207fu);
+        }
+
+        public readonly void Xar(Operand rd, Operand rn, uint imm6, Operand rm)
+        {
+            WriteInstructionRm16(0xce800000u | (imm6 << 10), rd, rn, rm);
+        }
+
+        public readonly void Xtn(Operand rd, Operand rn, uint size, uint q)
+        {
+            WriteInstruction(0x0e212800u | (size << 22) | (q << 30), rd, rn);
+        }
+
+        public readonly void Yield()
+        {
+            WriteUInt32(0xd503203fu);
+        }
+
+        public readonly void Zip1(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e003800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        public readonly void Zip2(Operand rd, Operand rn, Operand rm, uint size, uint q)
+        {
+            WriteInstructionRm16(0x0e007800u | (size << 22) | (q << 30), rd, rn, rm);
+        }
+
+        // Utility
+
+        public readonly void WriteSysRegInstruction(uint inst, Operand rt, uint o0, uint op1, uint crn, uint crm, uint op2)
+        {
+            inst |= (op2 & 7) << 5;
+            inst |= (crm & 15) << 8;
+            inst |= (crn & 15) << 12;
+            inst |= (op1 & 7) << 16;
+            inst |= (o0 & 1) << 19;
+
+            WriteInstruction(inst, rt);
+        }
+
+        private readonly void WriteInstructionAuto(
+            uint instI,
+            uint instR,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmShiftType shiftType = ArmShiftType.Lsl,
+            int shiftAmount = 0,
+            bool immForm = false)
+        {
+            if (rm.Kind == OperandKind.Constant && (rm.Value != 0 || immForm))
+            {
+                Debug.Assert(shiftAmount == 0);
+                int imm = rm.AsInt32();
+                Debug.Assert((uint)imm == rm.Value);
+                if (imm != 0 && (imm & 0xfff) == 0)
+                {
+                    instI |= 1 << 22; // sh flag
+                    imm >>= 12;
+                }
+                WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
+            }
+            else
+            {
+                Debug.Assert((uint)shiftType < 3); // ROR shift is a reserved encoding for ADD and SUB.
+                instR |= EncodeUImm6(shiftAmount) << 10;
+                instR |= (uint)shiftType << 22;
+
+                WriteInstructionRm16Auto(instR, rd, rn, rm);
+            }
+        }
+
+        private readonly void WriteInstructionAuto(
+            uint instR,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmShiftType shiftType = ArmShiftType.Lsl,
+            int shiftAmount = 0)
+        {
+            instR |= EncodeUImm6(shiftAmount) << 10;
+            instR |= (uint)shiftType << 22;
+
+            WriteInstructionRm16Auto(instR, rd, rn, rm);
+        }
+
+        private readonly void WriteInstructionAuto(
+            uint instruction,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmExtensionType extensionType,
+            int shiftAmount = 0)
+        {
+            Debug.Assert((uint)shiftAmount <= 4);
+
+            instruction |= (uint)shiftAmount << 10;
+            instruction |= (uint)extensionType << 13;
+
+            WriteInstructionRm16Auto(instruction, rd, rn, rm);
+        }
+
+        private readonly void WriteInstructionBitwiseAuto(
+            uint instI,
+            uint instR,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmShiftType shiftType = ArmShiftType.Lsl,
+            int shiftAmount = 0)
+        {
+            if (rm.Kind == OperandKind.Constant && rm.Value != 0)
+            {
+                Debug.Assert(shiftAmount == 0);
+                bool canEncode = CodeGenCommon.TryEncodeBitMask(rm, out int immN, out int immS, out int immR);
+                Debug.Assert(canEncode);
+                uint instruction = instI | ((uint)immS << 10) | ((uint)immR << 16) | ((uint)immN << 22);
+
+                WriteInstructionAuto(instruction, rd, rn);
+            }
+            else
+            {
+                WriteInstructionBitwiseAuto(instR, rd, rn, rm, shiftType, shiftAmount);
+            }
+        }
+
+        private readonly void WriteInstructionBitwiseAuto(
+            uint instruction,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmShiftType shiftType = ArmShiftType.Lsl,
+            int shiftAmount = 0)
+        {
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= SfFlag;
+            }
+
+            instruction |= EncodeUImm6(shiftAmount) << 10;
+            instruction |= (uint)shiftType << 22;
+
+            WriteInstructionRm16(instruction, rd, rn, rm);
+        }
+
+        private readonly void WriteInstructionLdrStrAuto(
+            uint instruction,
+            Operand rd,
+            Operand rn,
+            Operand rm,
+            ArmExtensionType extensionType,
+            bool shift)
+        {
+            if (shift)
+            {
+                instruction |= 1u << 12;
+            }
+
+            instruction |= (uint)extensionType << 13;
+
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= 1u << 30;
+            }
+
+            WriteInstructionRm16(instruction, rd, rn, rm);
+        }
+
+        private readonly void WriteInstructionAuto(uint instruction, Operand rd)
+        {
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= SfFlag;
+            }
+
+            WriteInstruction(instruction, rd);
+        }
+
+        public readonly void WriteInstructionAuto(uint instruction, Operand rd, Operand rn)
+        {
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= SfFlag;
+            }
+
+            WriteInstruction(instruction, rd, rn);
+        }
+
+        private readonly void WriteInstructionAuto(uint instruction, Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= SfFlag;
+            }
+
+            WriteInstruction(instruction, rd, rn, rm, ra);
+        }
+
+        public readonly void WriteInstruction(uint instruction, Operand rd)
+        {
+            WriteUInt32(instruction | EncodeReg(rd));
+        }
+
+        public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn)
+        {
+            WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5));
+        }
+
+        public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn, Operand rm)
+        {
+            WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 10));
+        }
+
+        public readonly void WriteInstruction(uint instruction, Operand rd, Operand rn, Operand rm, Operand ra)
+        {
+            WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(ra) << 10) | (EncodeReg(rm) << 16));
+        }
+
+        private readonly void WriteInstructionRm16Auto(uint instruction, Operand rd, Operand rn, Operand rm)
+        {
+            if (rd.Type == OperandType.I64)
+            {
+                instruction |= SfFlag;
+            }
+
+            WriteInstructionRm16(instruction, rd, rn, rm);
+        }
+
+        public readonly void WriteInstructionRm16(uint instruction, Operand rn, Operand rm)
+        {
+            WriteUInt32(instruction | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 16));
+        }
+
+        public readonly void WriteInstructionRm16(uint instruction, Operand rd, Operand rn, Operand rm)
+        {
+            WriteUInt32(instruction | EncodeReg(rd) | (EncodeReg(rn) << 5) | (EncodeReg(rm) << 16));
+        }
+
+        private static uint GetLdpStpInstruction(uint intInst, uint vecInst, int imm, OperandType type)
+        {
+            uint instruction;
+            int scale;
+
+            if (type.IsInteger())
+            {
+                instruction = intInst;
+
+                if (type == OperandType.I64)
+                {
+                    instruction |= SfFlag;
+                    scale = 3;
+                }
+                else
+                {
+                    scale = 2;
+                }
+            }
+            else
+            {
+                int opc = type switch
+                {
+                    OperandType.FP32 => 0,
+                    OperandType.FP64 => 1,
+                    _ => 2,
+                };
+
+                instruction = vecInst | ((uint)opc << 30);
+                scale = 2 + opc;
+            }
+
+            instruction |= (EncodeSImm7(imm, scale) << 15);
+
+            return instruction;
+        }
+
+        private static uint GetLdrStrInstruction(uint intInst, uint vecInst, OperandType type)
+        {
+            uint instruction;
+
+            if (type.IsInteger())
+            {
+                instruction = intInst;
+
+                if (type == OperandType.I64)
+                {
+                    instruction |= 1 << 30;
+                }
+            }
+            else
+            {
+                instruction = vecInst;
+
+                if (type == OperandType.V128)
+                {
+                    instruction |= 1u << 23;
+                }
+                else
+                {
+                    instruction |= type == OperandType.FP32 ? 2u << 30 : 3u << 30;
+                }
+            }
+
+            return instruction;
+        }
+
+        private static uint GetLdrStrInstruction(uint intInst, uint vecInst, OperandType type, uint size)
+        {
+            uint instruction;
+
+            if (type.IsInteger())
+            {
+                instruction = intInst;
+
+                if (type == OperandType.I64)
+                {
+                    instruction |= 1 << 30;
+                }
+            }
+            else
+            {
+                instruction = vecInst;
+
+                if (type == OperandType.V128)
+                {
+                    instruction |= 1u << 23;
+                }
+                else
+                {
+                    instruction |= size << 30;
+                }
+            }
+
+            return instruction;
+        }
+
+        private static uint EncodeIndexSizeImm5(int index, int size)
+        {
+            Debug.Assert((uint)size < 4);
+            Debug.Assert((uint)index < (16u >> size), $"Invalid index {index} and size {size} combination.");
+            return ((uint)index << (size + 1)) | (1u << size);
+        }
+
+        private static uint EncodeSImm7(int value, int scale)
+        {
+            uint imm = (uint)(value >> scale) & 0x7f;
+            Debug.Assert(((int)imm << 25) >> (25 - scale) == value, $"Failed to encode constant 0x{value:X} with scale {scale}.");
+            return imm;
+        }
+
+        private static uint EncodeSImm9(int value)
+        {
+            uint imm = (uint)value & 0x1ff;
+            Debug.Assert(((int)imm << 23) >> 23 == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeSImm19_2(int value)
+        {
+            uint imm = (uint)(value >> 2) & 0x7ffff;
+            Debug.Assert(((int)imm << 13) >> 11 == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeSImm26_2(int value)
+        {
+            uint imm = (uint)(value >> 2) & 0x3ffffff;
+            Debug.Assert(((int)imm << 6) >> 4 == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeUImm4(int value)
+        {
+            uint imm = (uint)value & 0xf;
+            Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeUImm6(int value)
+        {
+            uint imm = (uint)value & 0x3f;
+            Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeUImm12(int value, OperandType type)
+        {
+            return EncodeUImm12(value, GetScaleForType(type));
+        }
+
+        private static uint EncodeUImm12(int value, int scale)
+        {
+            uint imm = (uint)(value >> scale) & 0xfff;
+            Debug.Assert((int)imm << scale == value, $"Failed to encode constant 0x{value:X} with scale {scale}.");
+            return imm;
+        }
+
+        private static uint EncodeUImm16(int value)
+        {
+            uint imm = (uint)value & 0xffff;
+            Debug.Assert((int)imm == value, $"Failed to encode constant 0x{value:X}.");
+            return imm;
+        }
+
+        private static uint EncodeReg(Operand reg)
+        {
+            if (reg.Kind == OperandKind.Constant && reg.Value == 0)
+            {
+                return ZrRegister;
+            }
+
+            uint regIndex = (uint)reg.GetRegister().Index;
+            Debug.Assert(reg.Kind == OperandKind.Register);
+            Debug.Assert(regIndex < 32);
+            return regIndex;
+        }
+
+        private static uint EncodeTypeTargetPolicy(uint type, uint target, uint policy)
+        {
+            Debug.Assert(type <= 2);
+            Debug.Assert(target <= 2);
+            Debug.Assert(policy <= 1);
+
+            return (type << 3) | (target << 1) | policy;
+        }
+
+        private static uint EncodeIndexSizeSngl(uint inst, uint index, uint size)
+        {
+            uint opcode = Math.Min(2u, size) << 1;
+
+            index <<= (int)size;
+
+            if (size == 3)
+            {
+                index |= 1u;
+            }
+
+            size = index & 3;
+            uint s = (index >> 2) & 1;
+            uint q = index >> 3;
+
+            Debug.Assert(q <= 1);
+
+            return inst | (size << 10) | (s << 12) | (opcode << 13) | (q << 30);
+        }
+
+        private static uint EncodeLdSt1MultOpcode(uint registersCount)
+        {
+            return registersCount switch
+            {
+                2 => 0b1010,
+                3 => 0b0110,
+                4 => 0b0010,
+                _ => 0b0111,
+            };
+        }
+
+        private static int GetScaleForType(OperandType type)
+        {
+            return type switch
+            {
+                OperandType.I32 => 2,
+                OperandType.I64 => 3,
+                OperandType.FP32 => 2,
+                OperandType.FP64 => 3,
+                OperandType.V128 => 4,
+                _ => throw new ArgumentException($"Invalid type {type}."),
+            };
+        }
+
+        private readonly void WriteUInt32(uint value)
+        {
+            _code.Add(value);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs
new file mode 100644
index 00000000..db6a7159
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/CodeGenCommon.cs
@@ -0,0 +1,67 @@
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    static class CodeGenCommon
+    {
+        public static bool TryEncodeBitMask(Operand operand, out int immN, out int immS, out int immR)
+        {
+            return TryEncodeBitMask(operand.Type, operand.Value, out immN, out immS, out immR);
+        }
+
+        public static bool TryEncodeBitMask(OperandType type, ulong value, out int immN, out int immS, out int immR)
+        {
+            if (type == OperandType.I32)
+            {
+                value &= uint.MaxValue;
+                value |= value << 32;
+            }
+
+            return TryEncodeBitMask(value, out immN, out immS, out immR);
+        }
+
+        public static bool TryEncodeBitMask(ulong value, out int immN, out int immS, out int immR)
+        {
+            // Some special values also can't be encoded:
+            // 0 can't be encoded because we need to subtract 1 from onesCount (which would became negative if 0).
+            // A value with all bits set can't be encoded because it is reserved according to the spec, because:
+            // Any value AND all ones will be equal itself, so it's effectively a no-op.
+            // Any value OR all ones will be equal all ones, so one can just use MOV.
+            // Any value XOR all ones will be equal its inverse, so one can just use MVN.
+            if (value == 0 || value == ulong.MaxValue)
+            {
+                immN = 0;
+                immS = 0;
+                immR = 0;
+
+                return false;
+            }
+
+            // Normalize value, rotating it such that the LSB is 1: Ensures we get a complete element that has not
+            // been cut-in-half across the word boundary.
+            int rotation = BitOperations.TrailingZeroCount(value & (value + 1));
+            ulong rotatedValue = ulong.RotateRight(value, rotation);
+
+            // Now that we have a complete element in the LSB with the LSB = 1, determine size and number of ones
+            // in element.
+            int elementSize = BitOperations.TrailingZeroCount(rotatedValue & (rotatedValue + 1));
+            int onesInElement = BitOperations.TrailingZeroCount(~rotatedValue);
+
+            // Check the value is repeating; also ensures element size is a power of two.
+            if (ulong.RotateRight(value, elementSize) != value)
+            {
+                immN = 0;
+                immS = 0;
+                immR = 0;
+
+                return false;
+            }
+
+            immN = (elementSize >> 6) & 1;
+            immS = (((~elementSize + 1) << 1) | (onesInElement - 1)) & 0x3f;
+            immR = (elementSize - rotation) & (elementSize - 1);
+
+            return true;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs
new file mode 100644
index 00000000..b4b8bb52
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/RegisterSaveRestore.cs
@@ -0,0 +1,252 @@
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    readonly struct RegisterSaveRestore
+    {
+        private const int FpRegister = 29;
+        private const int LrRegister = 30;
+
+        public const int Encodable9BitsOffsetLimit = 0x100;
+
+        private readonly uint _gprMask;
+        private readonly uint _fpSimdMask;
+        private readonly OperandType _fpSimdType;
+        private readonly int _reservedStackSize;
+        private readonly bool _hasCall;
+
+        public RegisterSaveRestore(
+            uint gprMask,
+            uint fpSimdMask = 0,
+            OperandType fpSimdType = OperandType.FP64,
+            bool hasCall = false,
+            int reservedStackSize = 0)
+        {
+            _gprMask = gprMask;
+            _fpSimdMask = fpSimdMask;
+            _fpSimdType = fpSimdType;
+            _reservedStackSize = reservedStackSize;
+            _hasCall = hasCall;
+        }
+
+        public int GetReservedStackOffset()
+        {
+            int gprCalleeSavedRegsCount = BitOperations.PopCount(_gprMask);
+            int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(_fpSimdMask);
+
+            return (_hasCall ? 16 : 0) + Align16(gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes());
+        }
+
+        public void WritePrologue(ref Assembler asm)
+        {
+            uint gprMask = _gprMask;
+            uint fpSimdMask = _fpSimdMask;
+
+            int gprCalleeSavedRegsCount = BitOperations.PopCount(gprMask);
+            int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(fpSimdMask);
+
+            int reservedStackSize = Align16(_reservedStackSize);
+            int calleeSaveRegionSize = Align16(gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes()) + reservedStackSize;
+            int offset = 0;
+
+            WritePrologueCalleeSavesPreIndexed(ref asm, ref gprMask, ref offset, calleeSaveRegionSize, OperandType.I64);
+
+            if (_fpSimdType == OperandType.V128 && (gprCalleeSavedRegsCount & 1) != 0)
+            {
+                offset += 8;
+            }
+
+            WritePrologueCalleeSavesPreIndexed(ref asm, ref fpSimdMask, ref offset, calleeSaveRegionSize, _fpSimdType);
+
+            if (_hasCall)
+            {
+                Operand rsp = Register(Assembler.SpRegister);
+
+                if (offset != 0 || calleeSaveRegionSize + 16 < Encodable9BitsOffsetLimit)
+                {
+                    asm.StpRiPre(Register(FpRegister), Register(LrRegister), rsp, offset == 0 ? -(calleeSaveRegionSize + 16) : -16);
+                }
+                else
+                {
+                    asm.Sub(rsp, rsp, new Operand(OperandKind.Constant, OperandType.I64, (ulong)calleeSaveRegionSize));
+                    asm.StpRiPre(Register(FpRegister), Register(LrRegister), rsp, -16);
+                }
+
+                asm.MovSp(Register(FpRegister), rsp);
+            }
+        }
+
+        private static void WritePrologueCalleeSavesPreIndexed(
+            ref Assembler asm,
+            ref uint mask,
+            ref int offset,
+            int calleeSaveRegionSize,
+            OperandType type)
+        {
+            if ((BitOperations.PopCount(mask) & 1) != 0)
+            {
+                int reg = BitOperations.TrailingZeroCount(mask);
+
+                mask &= ~(1u << reg);
+
+                if (offset != 0)
+                {
+                    asm.StrRiUn(Register(reg, type), Register(Assembler.SpRegister), offset);
+                }
+                else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit)
+                {
+                    asm.StrRiPre(Register(reg, type), Register(Assembler.SpRegister), -calleeSaveRegionSize);
+                }
+                else
+                {
+                    asm.Sub(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize));
+                    asm.StrRiUn(Register(reg, type), Register(Assembler.SpRegister), 0);
+                }
+
+                offset += type.GetSizeInBytes();
+            }
+
+            while (mask != 0)
+            {
+                int reg = BitOperations.TrailingZeroCount(mask);
+
+                mask &= ~(1u << reg);
+
+                int reg2 = BitOperations.TrailingZeroCount(mask);
+
+                mask &= ~(1u << reg2);
+
+                if (offset != 0)
+                {
+                    asm.StpRiUn(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), offset);
+                }
+                else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit)
+                {
+                    asm.StpRiPre(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), -calleeSaveRegionSize);
+                }
+                else
+                {
+                    asm.Sub(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize));
+                    asm.StpRiUn(Register(reg, type), Register(reg2, type), Register(Assembler.SpRegister), 0);
+                }
+
+                offset += type.GetSizeInBytes() * 2;
+            }
+        }
+
+        public void WriteEpilogue(ref Assembler asm)
+        {
+            uint gprMask = _gprMask;
+            uint fpSimdMask = _fpSimdMask;
+
+            int gprCalleeSavedRegsCount = BitOperations.PopCount(gprMask);
+            int fpSimdCalleeSavedRegsCount = BitOperations.PopCount(fpSimdMask);
+
+            bool misalignedVector = _fpSimdType == OperandType.V128 && (gprCalleeSavedRegsCount & 1) != 0;
+
+            int offset = gprCalleeSavedRegsCount * 8 + fpSimdCalleeSavedRegsCount * _fpSimdType.GetSizeInBytes();
+
+            if (misalignedVector)
+            {
+                offset += 8;
+            }
+
+            int calleeSaveRegionSize = Align16(offset) + Align16(_reservedStackSize);
+
+            if (_hasCall)
+            {
+                Operand rsp = Register(Assembler.SpRegister);
+
+                if (offset != 0 || calleeSaveRegionSize + 16 < Encodable9BitsOffsetLimit)
+                {
+                    asm.LdpRiPost(Register(FpRegister), Register(LrRegister), rsp, offset == 0 ? calleeSaveRegionSize + 16 : 16);
+                }
+                else
+                {
+                    asm.LdpRiPost(Register(FpRegister), Register(LrRegister), rsp, 16);
+                    asm.Add(rsp, rsp, new Operand(OperandKind.Constant, OperandType.I64, (ulong)calleeSaveRegionSize));
+                }
+            }
+
+            WriteEpilogueCalleeSavesPostIndexed(ref asm, ref fpSimdMask, ref offset, calleeSaveRegionSize, _fpSimdType);
+
+            if (misalignedVector)
+            {
+                offset -= 8;
+            }
+
+            WriteEpilogueCalleeSavesPostIndexed(ref asm, ref gprMask, ref offset, calleeSaveRegionSize, OperandType.I64);
+        }
+
+        private static void WriteEpilogueCalleeSavesPostIndexed(
+            ref Assembler asm,
+            ref uint mask,
+            ref int offset,
+            int calleeSaveRegionSize,
+            OperandType type)
+        {
+            while (mask != 0)
+            {
+                int reg = HighestBitSet(mask);
+
+                mask &= ~(1u << reg);
+
+                if (mask != 0)
+                {
+                    int reg2 = HighestBitSet(mask);
+
+                    mask &= ~(1u << reg2);
+
+                    offset -= type.GetSizeInBytes() * 2;
+
+                    if (offset != 0)
+                    {
+                        asm.LdpRiUn(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), offset);
+                    }
+                    else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit)
+                    {
+                        asm.LdpRiPost(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), calleeSaveRegionSize);
+                    }
+                    else
+                    {
+                        asm.LdpRiUn(Register(reg2, type), Register(reg, type), Register(Assembler.SpRegister), 0);
+                        asm.Add(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize));
+                    }
+                }
+                else
+                {
+                    offset -= type.GetSizeInBytes();
+
+                    if (offset != 0)
+                    {
+                        asm.LdrRiUn(Register(reg, type), Register(Assembler.SpRegister), offset);
+                    }
+                    else if (calleeSaveRegionSize < Encodable9BitsOffsetLimit)
+                    {
+                        asm.LdrRiPost(Register(reg, type), Register(Assembler.SpRegister), calleeSaveRegionSize);
+                    }
+                    else
+                    {
+                        asm.LdrRiUn(Register(reg, type), Register(Assembler.SpRegister), 0);
+                        asm.Add(Register(Assembler.SpRegister), Register(Assembler.SpRegister), new Operand(OperandType.I64, (ulong)calleeSaveRegionSize));
+                    }
+                }
+            }
+        }
+
+        private static int HighestBitSet(uint value)
+        {
+            return 31 - BitOperations.LeadingZeroCount(value);
+        }
+
+        private static Operand Register(int register, OperandType type = OperandType.I64)
+        {
+            return new Operand(register, RegisterType.Integer, type);
+        }
+
+        private static int Align16(int value)
+        {
+            return (value + 0xf) & ~0xf;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs
new file mode 100644
index 00000000..3b01e674
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    class StackWalker : IStackWalker
+    {
+        public IEnumerable<ulong> GetCallStack(IntPtr framePointer, IntPtr codeRegionStart, int codeRegionSize, IntPtr codeRegion2Start, int codeRegion2Size)
+        {
+            List<ulong> functionPointers = new();
+
+            while (true)
+            {
+                IntPtr functionPointer = Marshal.ReadIntPtr(framePointer, IntPtr.Size);
+
+                if ((functionPointer < codeRegionStart || functionPointer >= codeRegionStart + codeRegionSize) &&
+                    (functionPointer < codeRegion2Start || functionPointer >= codeRegion2Start + codeRegion2Size))
+                {
+                    break;
+                }
+
+                functionPointers.Add((ulong)functionPointer - 4);
+                framePointer = Marshal.ReadIntPtr(framePointer);
+            }
+
+            return functionPointers;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs
new file mode 100644
index 00000000..e042af12
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/TailMerger.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
+{
+    class TailMerger
+    {
+        private enum BranchType
+        {
+            Conditional,
+            Unconditional,
+        }
+
+        private readonly List<(BranchType, int)> _branchPointers;
+
+        public TailMerger()
+        {
+            _branchPointers = new();
+        }
+
+        public void AddConditionalReturn(CodeWriter writer, in Assembler asm, ArmCondition returnCondition)
+        {
+            _branchPointers.Add((BranchType.Conditional, writer.InstructionPointer));
+            asm.B(returnCondition, 0);
+        }
+
+        public void AddConditionalZeroReturn(CodeWriter writer, in Assembler asm, Operand value)
+        {
+            _branchPointers.Add((BranchType.Conditional, writer.InstructionPointer));
+            asm.Cbz(value, 0);
+        }
+
+        public void AddUnconditionalReturn(CodeWriter writer, in Assembler asm)
+        {
+            _branchPointers.Add((BranchType.Unconditional, writer.InstructionPointer));
+            asm.B(0);
+        }
+
+        public void WriteReturn(CodeWriter writer, Action writeEpilogue)
+        {
+            if (_branchPointers.Count == 0)
+            {
+                return;
+            }
+
+            int targetIndex = writer.InstructionPointer;
+            int startIndex = _branchPointers.Count - 1;
+
+            if (startIndex >= 0 &&
+                _branchPointers[startIndex].Item1 == BranchType.Unconditional &&
+                _branchPointers[startIndex].Item2 == targetIndex - 1)
+            {
+                // Remove the last branch if it is redundant.
+                writer.RemoveLastInstruction();
+                startIndex--;
+                targetIndex--;
+            }
+
+            Assembler asm = new(writer);
+
+            writeEpilogue();
+            asm.Ret();
+
+            for (int i = startIndex; i >= 0; i--)
+            {
+                (BranchType type, int branchIndex) = _branchPointers[i];
+
+                uint encoding = writer.ReadInstructionAt(branchIndex);
+                int delta = targetIndex - branchIndex;
+
+                if (type == BranchType.Conditional)
+                {
+                    uint branchMask = 0x7ffff;
+                    int branchMax = (int)(branchMask + 1) / 2;
+
+                    if (delta >= -branchMax && delta < branchMax)
+                    {
+                        writer.WriteInstructionAt(branchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5));
+                    }
+                    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.
+
+                        delta = writer.InstructionPointer - branchIndex;
+
+                        uint branchInst = 0x14000000u | ((uint)delta & 0x3ffffff);
+                        Debug.Assert(ExtractSImm26Times4(branchInst) == delta * 4);
+
+                        writer.WriteInstructionAt(branchIndex, branchInst);
+
+                        int movedBranchIndex = writer.InstructionPointer;
+
+                        writer.WriteInstruction(0u); // Placeholder
+                        asm.B((branchIndex + 1 - writer.InstructionPointer) * 4);
+
+                        delta = targetIndex - movedBranchIndex;
+
+                        writer.WriteInstructionAt(movedBranchIndex, (encoding & ~(branchMask << 5)) | (uint)((delta & branchMask) << 5));
+                    }
+                }
+                else
+                {
+                    Debug.Assert(type == BranchType.Unconditional);
+
+                    writer.WriteInstructionAt(branchIndex, (encoding & ~0x3ffffffu) | (uint)(delta & 0x3ffffff));
+                }
+            }
+        }
+
+        private static int ExtractSImm26Times4(uint encoding)
+        {
+            return (int)(encoding << 6) >> 4;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs
new file mode 100644
index 00000000..8bf34030
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Operand.cs
@@ -0,0 +1,38 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen
+{
+    readonly struct Operand
+    {
+        public readonly OperandKind Kind { get; }
+        public readonly OperandType Type { get; }
+        public readonly ulong Value { get; }
+
+        public Operand(OperandKind kind, OperandType type, ulong value)
+        {
+            Kind = kind;
+            Type = type;
+            Value = value;
+        }
+
+        public Operand(int index, RegisterType regType, OperandType type) : this(OperandKind.Register, type, (ulong)((int)regType << 24 | index))
+        {
+        }
+
+        public Operand(OperandType type, ulong value) : this(OperandKind.Constant, type, value)
+        {
+        }
+
+        public readonly Register GetRegister()
+        {
+            Debug.Assert(Kind == OperandKind.Register);
+
+            return new Register((int)Value & 0xffffff, (RegisterType)(Value >> 24));
+        }
+
+        public readonly int AsInt32()
+        {
+            return (int)Value;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs
new file mode 100644
index 00000000..4f31763b
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandKind.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.Cpu.LightningJit.CodeGen
+{
+    enum OperandKind
+    {
+        None,
+        Constant,
+        Label,
+        Register,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs
new file mode 100644
index 00000000..6191f791
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/OperandType.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen
+{
+    enum OperandType
+    {
+        None,
+        I32,
+        I64,
+        FP32,
+        FP64,
+        V128,
+    }
+
+    static class OperandTypeExtensions
+    {
+        public static bool IsInteger(this OperandType type)
+        {
+            return type == OperandType.I32 || type == OperandType.I64;
+        }
+
+        public static int GetSizeInBytes(this OperandType type)
+        {
+            return type switch
+            {
+                OperandType.FP32 => 4,
+                OperandType.FP64 => 8,
+                OperandType.I32 => 4,
+                OperandType.I64 => 8,
+                OperandType.V128 => 16,
+                _ => throw new InvalidOperationException($"Invalid operand type \"{type}\"."),
+            };
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs
new file mode 100644
index 00000000..8b96c916
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Register.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.CodeGen
+{
+    readonly struct Register : IEquatable<Register>
+    {
+        public int Index { get; }
+
+        public RegisterType Type { get; }
+
+        public Register(int index, RegisterType type)
+        {
+            Index = index;
+            Type = type;
+        }
+
+        public override int GetHashCode()
+        {
+            return (ushort)Index | ((int)Type << 16);
+        }
+
+        public static bool operator ==(Register x, Register y)
+        {
+            return x.Equals(y);
+        }
+
+        public static bool operator !=(Register x, Register y)
+        {
+            return !x.Equals(y);
+        }
+
+        public override bool Equals(object obj)
+        {
+            return obj is Register reg && Equals(reg);
+        }
+
+        public bool Equals(Register other)
+        {
+            return other.Index == Index && other.Type == Type;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs
new file mode 100644
index 00000000..c4a726bc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/RegisterType.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.Cpu.LightningJit.CodeGen
+{
+    enum RegisterType
+    {
+        Integer,
+        Vector,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs b/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs
new file mode 100644
index 00000000..ac4b22ff
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CodeWriter.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    class CodeWriter
+    {
+        private readonly List<uint> _instructions;
+
+        public int InstructionPointer => _instructions.Count;
+
+        public CodeWriter()
+        {
+            _instructions = new();
+        }
+
+        public void WriteInstruction(uint instruction)
+        {
+            _instructions.Add(instruction);
+        }
+
+        public void WriteInstructionAt(int index, uint instruction)
+        {
+            _instructions[index] = instruction;
+        }
+
+        public void WriteInstructionsAt(int index, CodeWriter writer)
+        {
+            _instructions.InsertRange(index, writer._instructions);
+        }
+
+        public uint ReadInstructionAt(int index)
+        {
+            return _instructions[index];
+        }
+
+        public List<uint> GetList()
+        {
+            return _instructions;
+        }
+
+        public void RemoveLastInstruction()
+        {
+            if (_instructions.Count > 0)
+            {
+                _instructions.RemoveAt(_instructions.Count - 1);
+            }
+        }
+
+        public ReadOnlySpan<uint> AsSpan()
+        {
+            return CollectionsMarshal.AsSpan(_instructions);
+        }
+
+        public ReadOnlySpan<byte> AsByteSpan()
+        {
+            return MemoryMarshal.Cast<uint, byte>(AsSpan());
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs b/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs
new file mode 100644
index 00000000..ed375f22
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CompiledFunction.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    readonly ref struct CompiledFunction
+    {
+        public readonly ReadOnlySpan<byte> Code;
+        public readonly int GuestCodeLength;
+
+        public CompiledFunction(ReadOnlySpan<byte> code, int guestCodeLength)
+        {
+            Code = code;
+            GuestCodeLength = guestCodeLength;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs b/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs
new file mode 100644
index 00000000..e5af69b3
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CpuPreset.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.Cpu.LightningJit
+{
+    public readonly struct CpuPreset
+    {
+        public readonly IsaVersion Version;
+        public readonly IsaFeature Features;
+
+        public CpuPreset(IsaVersion version, IsaFeature features)
+        {
+            Version = version;
+            Features = features;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs b/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs
new file mode 100644
index 00000000..7798fbfc
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/CpuPresets.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.Cpu.LightningJit
+{
+    public static class CpuPresets
+    {
+        public static CpuPreset CortexA57 => new(
+            IsaVersion.v80,
+            IsaFeature.FeatAes |
+            IsaFeature.FeatCrc32 |
+            IsaFeature.FeatSha1 |
+            IsaFeature.FeatSha256 |
+            IsaFeature.FeatPmull);
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs b/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs
new file mode 100644
index 00000000..e5b369d6
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Graph/DataFlow.cs
@@ -0,0 +1,171 @@
+namespace Ryujinx.Cpu.LightningJit.Graph
+{
+    static class DataFlow
+    {
+        public static (RegisterMask[], RegisterMask[]) GetGlobalUses(IBlockList blocks)
+        {
+            // Compute local register inputs and outputs used inside blocks.
+            RegisterMask[] localInputs = new RegisterMask[blocks.Count];
+            RegisterMask[] localOutputs = new RegisterMask[blocks.Count];
+
+            for (int index = 0; index < blocks.Count; index++)
+            {
+                IBlock block = blocks[index];
+
+                RegisterUse use = block.ComputeUseMasks();
+
+                localInputs[block.Index] = use.Read;
+                localOutputs[block.Index] = use.Write;
+            }
+
+            // Compute global register inputs and outputs used across blocks.
+            RegisterMask[] globalInputs = new RegisterMask[blocks.Count];
+            RegisterMask[] globalOutputs = new RegisterMask[blocks.Count];
+
+            bool modified;
+
+            // Compute register outputs.
+            do
+            {
+                modified = false;
+
+                for (int index = 0; index < blocks.Count; index++)
+                {
+                    IBlock block = blocks[index];
+
+                    int firstPIndex = GetFirstPredecessorIndex(block);
+                    if (firstPIndex >= 0)
+                    {
+                        IBlock predecessor = block.GetPredecessor(firstPIndex);
+
+                        RegisterMask outputs = globalOutputs[predecessor.Index];
+
+                        for (int pIndex = firstPIndex + 1; pIndex < block.PredecessorsCount; pIndex++)
+                        {
+                            predecessor = block.GetPredecessor(pIndex);
+
+                            if (predecessor.EndsWithContextStore())
+                            {
+                                // If a block ended with a context store, then we don't need to care
+                                // about any of it's outputs, as they have already been saved to the context.
+                                // Common outputs must be reset as doing a context stores indicates we will
+                                // do a function call and wipe all register values.
+
+                                continue;
+                            }
+
+                            outputs |= globalOutputs[predecessor.Index];
+                        }
+
+                        outputs |= localOutputs[block.Index];
+                        modified |= Exchange(globalOutputs, block.Index, globalOutputs[block.Index] | outputs);
+                    }
+                    else
+                    {
+                        modified |= Exchange(globalOutputs, block.Index, localOutputs[block.Index]);
+                    }
+                }
+            }
+            while (modified);
+
+            // Compute register inputs.
+            do
+            {
+                modified = false;
+
+                for (int index = blocks.Count - 1; index >= 0; index--)
+                {
+                    IBlock block = blocks[index];
+
+                    RegisterMask cmnOutputs = RegisterMask.Zero;
+                    RegisterMask allOutputs = RegisterMask.Zero;
+
+                    int firstPIndex = GetFirstPredecessorIndex(block);
+                    if (firstPIndex == 0)
+                    {
+                        IBlock predecessor = block.GetPredecessor(0);
+
+                        // Assumes that block index 0 is the entry block.
+                        cmnOutputs = block.Index != 0 ? globalOutputs[predecessor.Index] : RegisterMask.Zero;
+                        allOutputs = globalOutputs[predecessor.Index];
+
+                        for (int pIndex = 1; pIndex < block.PredecessorsCount; pIndex++)
+                        {
+                            predecessor = block.GetPredecessor(pIndex);
+
+                            if (!predecessor.EndsWithContextStore())
+                            {
+                                RegisterMask outputs = globalOutputs[predecessor.Index];
+
+                                cmnOutputs &= outputs;
+                                allOutputs |= outputs;
+                            }
+                            else
+                            {
+                                cmnOutputs = RegisterMask.Zero;
+                            }
+                        }
+                    }
+                    else if (firstPIndex > 0)
+                    {
+                        IBlock predecessor = block.GetPredecessor(firstPIndex);
+
+                        allOutputs = globalOutputs[predecessor.Index];
+
+                        for (int pIndex = firstPIndex + 1; pIndex < block.PredecessorsCount; pIndex++)
+                        {
+                            predecessor = block.GetPredecessor(pIndex);
+
+                            if (!predecessor.EndsWithContextStore())
+                            {
+                                allOutputs |= globalOutputs[predecessor.Index];
+                            }
+                        }
+                    }
+
+                    RegisterMask inputs = localInputs[block.Index];
+
+                    // If this block will load from context at the end,
+                    // we don't need to care about what comes next.
+                    if (!block.EndsWithContextLoad())
+                    {
+                        for (int sIndex = 0; sIndex < block.SuccessorsCount; sIndex++)
+                        {
+                            inputs |= globalInputs[block.GetSuccessor(sIndex).Index] & ~localOutputs[block.Index];
+                        }
+                    }
+
+                    inputs |= allOutputs & ~localOutputs[block.Index];
+                    inputs &= ~cmnOutputs;
+
+                    modified |= Exchange(globalInputs, block.Index, globalInputs[block.Index] | inputs);
+                }
+            }
+            while (modified);
+
+            return (globalInputs, globalOutputs);
+        }
+
+        private static bool Exchange(RegisterMask[] masks, int blkIndex, RegisterMask value)
+        {
+            ref RegisterMask curValue = ref masks[blkIndex];
+            bool changed = curValue != value;
+            curValue = value;
+
+            return changed;
+        }
+
+        private static int GetFirstPredecessorIndex(IBlock block)
+        {
+            for (int pIndex = 0; pIndex < block.PredecessorsCount; pIndex++)
+            {
+                if (!block.GetPredecessor(pIndex).EndsWithContextStore())
+                {
+                    return pIndex;
+                }
+            }
+
+            return -1;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs b/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs
new file mode 100644
index 00000000..2e5d7132
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Graph/IBlock.cs
@@ -0,0 +1,17 @@
+namespace Ryujinx.Cpu.LightningJit.Graph
+{
+    interface IBlock
+    {
+        int Index { get; }
+
+        int PredecessorsCount { get; }
+        int SuccessorsCount { get; }
+
+        IBlock GetSuccessor(int index);
+        IBlock GetPredecessor(int index);
+
+        RegisterUse ComputeUseMasks();
+        bool EndsWithContextLoad();
+        bool EndsWithContextStore();
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs b/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs
new file mode 100644
index 00000000..aeec799c
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Graph/IBlockList.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Cpu.LightningJit.Graph
+{
+    interface IBlockList
+    {
+        int Count { get; }
+
+        IBlock this[int index] { get; }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs
new file mode 100644
index 00000000..cde324d5
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterMask.cs
@@ -0,0 +1,60 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.Graph
+{
+    readonly struct RegisterMask : IEquatable<RegisterMask>
+    {
+        public readonly uint GprMask;
+        public readonly uint FpSimdMask;
+        public readonly uint PStateMask;
+
+        public static RegisterMask Zero => new(0u, 0u, 0u);
+
+        public RegisterMask(uint gprMask, uint fpSimdMask, uint pStateMask)
+        {
+            GprMask = gprMask;
+            FpSimdMask = fpSimdMask;
+            PStateMask = pStateMask;
+        }
+
+        public static RegisterMask operator &(RegisterMask x, RegisterMask y)
+        {
+            return new(x.GprMask & y.GprMask, x.FpSimdMask & y.FpSimdMask, x.PStateMask & y.PStateMask);
+        }
+
+        public static RegisterMask operator |(RegisterMask x, RegisterMask y)
+        {
+            return new(x.GprMask | y.GprMask, x.FpSimdMask | y.FpSimdMask, x.PStateMask | y.PStateMask);
+        }
+
+        public static RegisterMask operator ~(RegisterMask x)
+        {
+            return new(~x.GprMask, ~x.FpSimdMask, ~x.PStateMask);
+        }
+
+        public static bool operator ==(RegisterMask x, RegisterMask y)
+        {
+            return x.Equals(y);
+        }
+
+        public static bool operator !=(RegisterMask x, RegisterMask y)
+        {
+            return !x.Equals(y);
+        }
+
+        public override bool Equals(object obj)
+        {
+            return obj is RegisterMask regMask && Equals(regMask);
+        }
+
+        public bool Equals(RegisterMask other)
+        {
+            return GprMask == other.GprMask && FpSimdMask == other.FpSimdMask && PStateMask == other.PStateMask;
+        }
+
+        public override int GetHashCode()
+        {
+            return HashCode.Combine(GprMask, FpSimdMask, PStateMask);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs
new file mode 100644
index 00000000..83ef4192
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Graph/RegisterUse.cs
@@ -0,0 +1,24 @@
+namespace Ryujinx.Cpu.LightningJit.Graph
+{
+    readonly struct RegisterUse
+    {
+        public readonly RegisterMask Read;
+        public readonly RegisterMask Write;
+
+        public RegisterUse(RegisterMask read, RegisterMask write)
+        {
+            Read = read;
+            Write = write;
+        }
+
+        public RegisterUse(
+            uint gprReadMask,
+            uint gprWriteMask,
+            uint fpSimdReadMask,
+            uint fpSimdWriteMask,
+            uint pStateReadMask,
+            uint pStateWriteMask) : this(new(gprReadMask, fpSimdReadMask, pStateReadMask), new(gprWriteMask, fpSimdWriteMask, pStateWriteMask))
+        {
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs
new file mode 100644
index 00000000..2fddef65
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    interface IStackWalker
+    {
+        IEnumerable<ulong> GetCallStack(IntPtr framePointer, IntPtr codeRegionStart, int codeRegionSize, IntPtr codeRegion2Start, int codeRegion2Size);
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs b/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs
new file mode 100644
index 00000000..c1f799d2
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/IsaFeature.cs
@@ -0,0 +1,65 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    [Flags]
+    public enum IsaFeature : ulong
+    {
+        None = 0,
+        FeatAa32bf16 = 1UL << 0,
+        FeatAa32i8mm = 1UL << 1,
+        FeatAes = 1UL << 2,
+        FeatBf16 = 1UL << 3,
+        FeatBti = 1UL << 4,
+        FeatChk = 1UL << 5,
+        FeatClrbhb = 1UL << 6,
+        FeatCrc32 = 1UL << 7,
+        FeatCssc = 1UL << 8,
+        FeatD128 = 1UL << 9,
+        FeatDgh = 1UL << 10,
+        FeatDotprod = 1UL << 11,
+        FeatFcma = 1UL << 12,
+        FeatFhm = 1UL << 13,
+        FeatFlagm = 1UL << 14,
+        FeatFlagm2 = 1UL << 15,
+        FeatFp16 = 1UL << 16,
+        FeatFrintts = 1UL << 17,
+        FeatGcs = 1UL << 18,
+        FeatHbc = 1UL << 19,
+        FeatI8mm = 1UL << 20,
+        FeatJscvt = 1UL << 21,
+        FeatLor = 1UL << 22,
+        FeatLrcpc = 1UL << 23,
+        FeatLrcpc2 = 1UL << 24,
+        FeatLrcpc3 = 1UL << 25,
+        FeatLs64 = 1UL << 26,
+        FeatLs64Accdata = 1UL << 27,
+        FeatLs64V = 1UL << 28,
+        FeatLse = 1UL << 29,
+        FeatLse128 = 1UL << 30,
+        FeatMops = 1UL << 31,
+        FeatMte = 1UL << 32,
+        FeatMte2 = 1UL << 33,
+        FeatPan = 1UL << 34,
+        FeatPauth = 1UL << 35,
+        FeatPmull = 1UL << 36,
+        FeatRas = 1UL << 37,
+        FeatRdm = 1UL << 38,
+        FeatRprfm = 1UL << 39,
+        FeatSb = 1UL << 40,
+        FeatSha1 = 1UL << 41,
+        FeatSha256 = 1UL << 42,
+        FeatSha3 = 1UL << 43,
+        FeatSha512 = 1UL << 44,
+        FeatSm3 = 1UL << 45,
+        FeatSm4 = 1UL << 46,
+        FeatSpe = 1UL << 47,
+        FeatSysinstr128 = 1UL << 48,
+        FeatSysreg128 = 1UL << 49,
+        FeatThe = 1UL << 50,
+        FeatTme = 1UL << 51,
+        FeatTrf = 1UL << 52,
+        FeatWfxt = 1UL << 53,
+        FeatXs = 1UL << 54,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs b/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs
new file mode 100644
index 00000000..5923eede
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/IsaVersion.cs
@@ -0,0 +1,17 @@
+namespace Ryujinx.Cpu.LightningJit
+{
+    public enum IsaVersion
+    {
+        None,
+        v80,
+        v81,
+        v82,
+        v83,
+        v84,
+        v85,
+        v86,
+        v87,
+        v88,
+        v89,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
new file mode 100644
index 00000000..b63636e3
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/LightningJitCpuContext.cs
@@ -0,0 +1,58 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.Jit;
+using Ryujinx.Cpu.LightningJit.State;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    class LightningJitCpuContext : ICpuContext
+    {
+        private readonly ITickSource _tickSource;
+        private readonly Translator _translator;
+
+        public LightningJitCpuContext(ITickSource tickSource, IMemoryManager memory, bool for64Bit)
+        {
+            _tickSource = tickSource;
+            _translator = new Translator(memory, for64Bit);
+            memory.UnmapEvent += UnmapHandler;
+        }
+
+        private void UnmapHandler(ulong address, ulong size)
+        {
+            _translator.InvalidateJitCacheRegion(address, size);
+        }
+
+        /// <inheritdoc/>
+        public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
+        {
+            return new ExecutionContext(new JitMemoryAllocator(), _tickSource, exceptionCallbacks);
+        }
+
+        /// <inheritdoc/>
+        public void Execute(IExecutionContext context, ulong address)
+        {
+            _translator.Execute((ExecutionContext)context, address);
+        }
+
+        /// <inheritdoc/>
+        public void InvalidateCacheRegion(ulong address, ulong size)
+        {
+            _translator.InvalidateJitCacheRegion(address, size);
+        }
+
+        /// <inheritdoc/>
+        public IDiskCacheLoadState LoadDiskCache(string titleIdText, string displayVersion, bool enabled)
+        {
+            return new DummyDiskCacheLoadState();
+        }
+
+        /// <inheritdoc/>
+        public void PrepareCodeRange(ulong address, ulong size)
+        {
+        }
+
+        public void Dispose()
+        {
+            _translator.Dispose();
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs b/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs
new file mode 100644
index 00000000..c97ddc7c
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/LightningJitEngine.cs
@@ -0,0 +1,20 @@
+using ARMeilleure.Memory;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    public class LightningJitEngine : ICpuEngine
+    {
+        private readonly ITickSource _tickSource;
+
+        public LightningJitEngine(ITickSource tickSource)
+        {
+            _tickSource = tickSource;
+        }
+
+        /// <inheritdoc/>
+        public ICpuContext CreateCpuContext(IMemoryManager memoryManager, bool for64Bit)
+        {
+            return new LightningJitCpuContext(_tickSource, memoryManager, for64Bit);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs b/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs
new file mode 100644
index 00000000..8a3a968d
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/NativeContextOffsets.cs
@@ -0,0 +1,17 @@
+using Ryujinx.Cpu.LightningJit.State;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    class NativeContextOffsets
+    {
+        public static int GprBaseOffset => NativeContext.GetXOffset();
+        public static int FpSimdBaseOffset => NativeContext.GetVOffset();
+        public static int FlagsBaseOffset => NativeContext.GetFlagsOffset();
+        public static int FpFlagsBaseOffset => NativeContext.GetFpFlagsOffset();
+        public static int TpidrEl0Offset => NativeContext.GetTpidrEl0Offset();
+        public static int TpidrroEl0Offset => NativeContext.GetTpidrroEl0Offset();
+        public static int RunningOffset => NativeContext.GetRunningOffset();
+        public static int CounterOffset => NativeContext.GetCounterOffset();
+        public static int DispatchAddressOffset => NativeContext.GetDispatchAddressOffset();
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs b/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs
new file mode 100644
index 00000000..da3ad983
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/NativeInterface.cs
@@ -0,0 +1,93 @@
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.LightningJit.State;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    static class NativeInterface
+    {
+        private const int DczSizeLog2 = 4; // Log2 size in words
+        private const int DczSizeInBytes = 4 << DczSizeLog2;
+
+        private class ThreadContext
+        {
+            public ExecutionContext Context { get; }
+            public IMemoryManager Memory { get; }
+            public Translator Translator { get; }
+
+            public ThreadContext(ExecutionContext context, IMemoryManager memory, Translator translator)
+            {
+                Context = context;
+                Memory = memory;
+                Translator = translator;
+            }
+        }
+
+        [ThreadStatic]
+        private static ThreadContext Context;
+
+        public static void RegisterThread(ExecutionContext context, IMemoryManager memory, Translator translator)
+        {
+            Context = new ThreadContext(context, memory, translator);
+        }
+
+        public static void UnregisterThread()
+        {
+            Context = null;
+        }
+
+        public static void Break(ulong address, int imm)
+        {
+            GetContext().OnBreak(address, imm);
+        }
+
+        public static void SupervisorCall(ulong address, int imm)
+        {
+            GetContext().OnSupervisorCall(address, imm);
+        }
+
+        public static void Undefined(ulong address, int opCode)
+        {
+            GetContext().OnUndefined(address, opCode);
+        }
+
+        public static ulong GetCntfrqEl0()
+        {
+            return GetContext().CntfrqEl0;
+        }
+
+        public static ulong GetCntpctEl0()
+        {
+            return GetContext().CntpctEl0;
+        }
+
+        public static ulong GetFunctionAddress(IntPtr framePointer, ulong address)
+        {
+            return (ulong)Context.Translator.GetOrTranslatePointer(framePointer, address, GetContext().ExecutionMode);
+        }
+
+        public static void InvalidateCacheLine(ulong address)
+        {
+            Context.Translator.InvalidateJitCacheRegion(address, DczSizeInBytes);
+        }
+
+        public static bool CheckSynchronization()
+        {
+            ExecutionContext context = GetContext();
+
+            context.CheckInterrupt();
+
+            return context.Running;
+        }
+
+        public static ExecutionContext GetContext()
+        {
+            return Context.Context;
+        }
+
+        public static IMemoryManager GetMemoryManager()
+        {
+            return Context.Memory;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs b/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs
new file mode 100644
index 00000000..facb9142
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/State/ExecutionContext.cs
@@ -0,0 +1,153 @@
+using ARMeilleure.Memory;
+using ARMeilleure.State;
+using System;
+
+namespace Ryujinx.Cpu.LightningJit.State
+{
+    public class ExecutionContext : IExecutionContext
+    {
+        private const int MinCountForCheck = 4000;
+
+        private readonly NativeContext _nativeContext;
+
+        internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
+
+        private bool _interrupted;
+        private readonly ICounter _counter;
+
+        public ulong Pc => _nativeContext.GetPc();
+
+        public ulong CntfrqEl0 => _counter.Frequency;
+        public ulong CntpctEl0 => _counter.Counter;
+
+        public long TpidrEl0
+        {
+            get => _nativeContext.GetTpidrEl0();
+            set => _nativeContext.SetTpidrEl0(value);
+        }
+
+        public long TpidrroEl0
+        {
+            get => _nativeContext.GetTpidrroEl0();
+            set => _nativeContext.SetTpidrroEl0(value);
+        }
+
+        public uint Pstate
+        {
+            get => _nativeContext.GetPstate();
+            set => _nativeContext.SetPstate(value);
+        }
+
+        public uint Fpsr
+        {
+            get => _nativeContext.GetFPState((uint)FPSR.Mask);
+            set => _nativeContext.SetFPState(value, (uint)FPSR.Mask);
+        }
+
+        public uint Fpcr
+        {
+            get => _nativeContext.GetFPState((uint)FPCR.Mask);
+            set => _nativeContext.SetFPState(value, (uint)FPCR.Mask);
+        }
+
+        public bool IsAarch32 { get; set; }
+
+        internal ExecutionMode ExecutionMode
+        {
+            get
+            {
+                if (IsAarch32)
+                {
+                    return (Pstate & (1u << 5)) != 0
+                        ? ExecutionMode.Aarch32Thumb
+                        : ExecutionMode.Aarch32Arm;
+                }
+                else
+                {
+                    return ExecutionMode.Aarch64;
+                }
+            }
+        }
+
+        public bool Running
+        {
+            get => _nativeContext.GetRunning();
+            private set => _nativeContext.SetRunning(value);
+        }
+
+        private readonly ExceptionCallbackNoArgs _interruptCallback;
+        private readonly ExceptionCallback _breakCallback;
+        private readonly ExceptionCallback _supervisorCallback;
+        private readonly ExceptionCallback _undefinedCallback;
+
+        public ExecutionContext(IJitMemoryAllocator allocator, ICounter counter, ExceptionCallbacks exceptionCallbacks)
+        {
+            _nativeContext = new NativeContext(allocator);
+            _counter = counter;
+            _interruptCallback = exceptionCallbacks.InterruptCallback;
+            _breakCallback = exceptionCallbacks.BreakCallback;
+            _supervisorCallback = exceptionCallbacks.SupervisorCallback;
+            _undefinedCallback = exceptionCallbacks.UndefinedCallback;
+
+            Running = true;
+
+            _nativeContext.SetCounter(MinCountForCheck);
+        }
+
+        public ulong GetX(int index) => _nativeContext.GetX(index);
+        public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
+
+        public V128 GetV(int index) => _nativeContext.GetV(index);
+        public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
+
+        internal void CheckInterrupt()
+        {
+            if (_interrupted)
+            {
+                _interrupted = false;
+
+                _interruptCallback?.Invoke(this);
+            }
+
+            _nativeContext.SetCounter(MinCountForCheck);
+        }
+
+        public void RequestInterrupt()
+        {
+            _interrupted = true;
+        }
+
+        internal void OnBreak(ulong address, int imm)
+        {
+            _breakCallback?.Invoke(this, address, imm);
+        }
+
+        internal void OnSupervisorCall(ulong address, int imm)
+        {
+            _supervisorCallback?.Invoke(this, address, imm);
+        }
+
+        internal void OnUndefined(ulong address, int opCode)
+        {
+            _undefinedCallback?.Invoke(this, address, opCode);
+        }
+
+        public void StopRunning()
+        {
+            Running = false;
+
+            _nativeContext.SetCounter(0);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            _nativeContext.Dispose();
+        }
+
+        public void Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs b/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs
new file mode 100644
index 00000000..0602bc9a
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/State/ExecutionMode.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Cpu.LightningJit.State
+{
+    enum ExecutionMode
+    {
+        Aarch32Arm = 0,
+        Aarch32Thumb = 1,
+        Aarch64 = 2,
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs b/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs
new file mode 100644
index 00000000..fdb8793d
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/State/NativeContext.cs
@@ -0,0 +1,173 @@
+using ARMeilleure.Memory;
+using ARMeilleure.State;
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.Cpu.LightningJit.State
+{
+    class NativeContext : IDisposable
+    {
+        private unsafe struct NativeCtxStorage
+        {
+            public fixed ulong X[32];
+            public fixed ulong V[64];
+            public uint Flags;
+            public uint FpFlags;
+            public long TpidrEl0;
+            public long TpidrroEl0;
+            public int Counter;
+            public uint HostFpFlags;
+            public ulong DispatchAddress;
+            public int Running;
+        }
+
+        private static NativeCtxStorage _dummyStorage = new();
+
+        private readonly IJitMemoryBlock _block;
+
+        public IntPtr BasePtr => _block.Pointer;
+
+        public NativeContext(IJitMemoryAllocator allocator)
+        {
+            _block = allocator.Allocate((ulong)Unsafe.SizeOf<NativeCtxStorage>());
+        }
+
+        public ulong GetPc()
+        {
+            // TODO: More precise tracking of PC value.
+            return GetStorage().DispatchAddress;
+        }
+
+        public unsafe ulong GetX(int index)
+        {
+            if ((uint)index >= 32)
+            {
+                throw new ArgumentOutOfRangeException(nameof(index));
+            }
+
+            return GetStorage().X[index];
+        }
+
+        public unsafe void SetX(int index, ulong value)
+        {
+            if ((uint)index >= 32)
+            {
+                throw new ArgumentOutOfRangeException(nameof(index));
+            }
+
+            GetStorage().X[index] = value;
+        }
+
+        public unsafe V128 GetV(int index)
+        {
+            if ((uint)index >= 32)
+            {
+                throw new ArgumentOutOfRangeException(nameof(index));
+            }
+
+            return new V128(GetStorage().V[index * 2 + 0], GetStorage().V[index * 2 + 1]);
+        }
+
+        public unsafe void SetV(int index, V128 value)
+        {
+            if ((uint)index >= 32)
+            {
+                throw new ArgumentOutOfRangeException(nameof(index));
+            }
+
+            GetStorage().V[index * 2 + 0] = value.Extract<ulong>(0);
+            GetStorage().V[index * 2 + 1] = value.Extract<ulong>(1);
+        }
+
+        public unsafe uint GetPstate()
+        {
+            return GetStorage().Flags;
+        }
+
+        public unsafe void SetPstate(uint value)
+        {
+            GetStorage().Flags = value;
+        }
+
+        public unsafe uint GetFPState(uint mask = uint.MaxValue)
+        {
+            return GetStorage().FpFlags & mask;
+        }
+
+        public unsafe void SetFPState(uint value, uint mask = uint.MaxValue)
+        {
+            GetStorage().FpFlags = (value & mask) | (GetStorage().FpFlags & ~mask);
+        }
+
+        public long GetTpidrEl0() => GetStorage().TpidrEl0;
+        public void SetTpidrEl0(long value) => GetStorage().TpidrEl0 = value;
+
+        public long GetTpidrroEl0() => GetStorage().TpidrroEl0;
+        public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value;
+
+        public int GetCounter() => GetStorage().Counter;
+        public void SetCounter(int value) => GetStorage().Counter = value;
+
+        public bool GetRunning() => GetStorage().Running != 0;
+        public void SetRunning(bool value) => GetStorage().Running = value ? 1 : 0;
+
+        public unsafe static int GetXOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.X[0]);
+        }
+
+        public unsafe static int GetVOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.V[0]);
+        }
+
+        public static int GetFlagsOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.Flags);
+        }
+
+        public static int GetFpFlagsOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.FpFlags);
+        }
+
+        public static int GetTpidrEl0Offset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrEl0);
+        }
+
+        public static int GetTpidrroEl0Offset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0);
+        }
+
+        public static int GetCounterOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter);
+        }
+
+        public static int GetHostFpFlagsOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.HostFpFlags);
+        }
+
+        public static int GetDispatchAddressOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.DispatchAddress);
+        }
+
+        public static int GetRunningOffset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
+        }
+
+        private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
+        {
+            return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
+        }
+
+        private unsafe ref NativeCtxStorage GetStorage() => ref Unsafe.AsRef<NativeCtxStorage>((void*)_block.Pointer);
+
+        public void Dispose() => _block.Dispose();
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs b/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs
new file mode 100644
index 00000000..a51fe37b
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Table/IInstInfo.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.Cpu.LightningJit.Table
+{
+    interface IInstInfo
+    {
+        public uint Encoding { get; }
+        public uint EncodingMask { get; }
+        public IsaVersion Version { get; }
+        public IsaFeature Feature { get; }
+
+        bool IsConstrained(uint encoding);
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs b/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs
new file mode 100644
index 00000000..32250b03
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Table/InstEncoding.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.Cpu.LightningJit.Table
+{
+    readonly struct InstEncoding
+    {
+        public readonly uint Encoding;
+        public readonly uint EncodingMask;
+
+        public InstEncoding(uint encoding, uint encodingMask)
+        {
+            Encoding = encoding;
+            EncodingMask = encodingMask;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs
new file mode 100644
index 00000000..6567efee
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Table/InstTableLevel.cs
@@ -0,0 +1,96 @@
+using System.Collections.Generic;
+using System.Numerics;
+
+namespace Ryujinx.Cpu.LightningJit.Table
+{
+    class InstTableLevel<T> where T : IInstInfo
+    {
+        private readonly int _shift;
+        private readonly uint _mask;
+        private readonly InstTableLevel<T>[] _childs;
+        private readonly List<T> _insts;
+
+        private InstTableLevel(List<T> insts, uint baseMask)
+        {
+            uint commonEncodingMask = baseMask;
+
+            foreach (T info in insts)
+            {
+                commonEncodingMask &= info.EncodingMask;
+            }
+
+            if (commonEncodingMask != 0)
+            {
+                _shift = BitOperations.TrailingZeroCount(commonEncodingMask);
+                int bits = BitOperations.TrailingZeroCount(~(commonEncodingMask >> _shift));
+                int count = 1 << bits;
+                _mask = uint.MaxValue >> (32 - bits);
+
+                _childs = new InstTableLevel<T>[count];
+
+                List<T>[] splitList = new List<T>[count];
+
+                for (int index = 0; index < insts.Count; index++)
+                {
+                    int splitIndex = (int)((insts[index].Encoding >> _shift) & _mask);
+
+                    (splitList[splitIndex] ??= new()).Add(insts[index]);
+                }
+
+                for (int index = 0; index < count; index++)
+                {
+                    if (splitList[index] == null)
+                    {
+                        continue;
+                    }
+
+                    _childs[index] = new InstTableLevel<T>(splitList[index], baseMask & ~commonEncodingMask);
+                }
+            }
+            else
+            {
+                _insts = insts;
+            }
+        }
+
+        public InstTableLevel(List<T> insts) : this(insts, uint.MaxValue)
+        {
+        }
+
+        public bool TryFind(uint encoding, IsaVersion version, IsaFeature features, out T value)
+        {
+            if (_childs != null)
+            {
+                int index = (int)((encoding >> _shift) & _mask);
+
+                if (_childs[index] == null)
+                {
+                    value = default;
+
+                    return false;
+                }
+
+                return _childs[index].TryFind(encoding, version, features, out value);
+            }
+            else
+            {
+                foreach (T info in _insts)
+                {
+                    if ((encoding & info.EncodingMask) == info.Encoding &&
+                        !info.IsConstrained(encoding) &&
+                        info.Version <= version &&
+                        (info.Feature & features) == info.Feature)
+                    {
+                        value = info;
+
+                        return true;
+                    }
+                }
+
+                value = default;
+
+                return false;
+            }
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs
new file mode 100644
index 00000000..a4e2c7b9
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    class TranslatedFunction
+    {
+        public IntPtr FuncPointer { get; }
+        public ulong GuestSize { get; }
+
+        public TranslatedFunction(IntPtr funcPointer, ulong guestSize)
+        {
+            FuncPointer = funcPointer;
+            GuestSize = guestSize;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/Translator.cs b/src/Ryujinx.Cpu/LightningJit/Translator.cs
new file mode 100644
index 00000000..c883c1d6
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/Translator.cs
@@ -0,0 +1,227 @@
+using ARMeilleure.Common;
+using ARMeilleure.Memory;
+using Ryujinx.Cpu.Jit;
+using Ryujinx.Cpu.LightningJit.Cache;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using Ryujinx.Cpu.LightningJit.State;
+using Ryujinx.Cpu.Signal;
+using Ryujinx.Memory;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    class Translator : IDisposable
+    {
+        // Should be enabled on platforms that enforce W^X.
+        private static bool IsNoWxPlatform => false;
+
+        private static readonly AddressTable<ulong>.Level[] _levels64Bit =
+            new AddressTable<ulong>.Level[]
+            {
+                new(31, 17),
+                new(23,  8),
+                new(15,  8),
+                new( 7,  8),
+                new( 2,  5),
+            };
+
+        private static readonly AddressTable<ulong>.Level[] _levels32Bit =
+            new AddressTable<ulong>.Level[]
+            {
+                new(23, 9),
+                new(15, 8),
+                new( 7, 8),
+                new( 1, 6),
+            };
+
+        private readonly ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>> _oldFuncs;
+        private readonly NoWxCache _noWxCache;
+        private bool _disposed;
+
+        internal TranslatorCache<TranslatedFunction> Functions { get; }
+        internal AddressTable<ulong> FunctionTable { get; }
+        internal TranslatorStubs Stubs { get; }
+        internal IMemoryManager Memory { get; }
+
+        public Translator(IMemoryManager memory, bool for64Bits)
+        {
+            Memory = memory;
+
+            _oldFuncs = new ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>>();
+
+            if (IsNoWxPlatform)
+            {
+                _noWxCache = new(new JitMemoryAllocator(), CreateStackWalker(), this);
+            }
+            else
+            {
+                JitCache.Initialize(new JitMemoryAllocator(forJit: true));
+            }
+
+            Functions = new TranslatorCache<TranslatedFunction>();
+            FunctionTable = new AddressTable<ulong>(for64Bits ? _levels64Bit : _levels32Bit);
+            Stubs = new TranslatorStubs(FunctionTable, _noWxCache);
+
+            FunctionTable.Fill = (ulong)Stubs.SlowDispatchStub;
+
+            if (memory.Type.IsHostMapped())
+            {
+                NativeSignalHandler.InitializeSignalHandler(MemoryBlock.GetPageSize());
+            }
+        }
+
+        private static IStackWalker CreateStackWalker()
+        {
+            if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+            {
+                return new StackWalker();
+            }
+            else
+            {
+                throw new PlatformNotSupportedException();
+            }
+        }
+
+        public void Execute(State.ExecutionContext context, ulong address)
+        {
+            ObjectDisposedException.ThrowIf(_disposed, this);
+
+            NativeInterface.RegisterThread(context, Memory, this);
+
+            Stubs.DispatchLoop(context.NativeContextPtr, address);
+
+            NativeInterface.UnregisterThread();
+            _noWxCache?.ClearEntireThreadLocalCache();
+        }
+
+        internal IntPtr GetOrTranslatePointer(IntPtr framePointer, ulong address, ExecutionMode mode)
+        {
+            if (_noWxCache != null)
+            {
+                CompiledFunction func = Compile(address, mode);
+
+                return _noWxCache.Map(framePointer, func.Code, address, (ulong)func.GuestCodeLength);
+            }
+
+            return GetOrTranslate(address, mode).FuncPointer;
+        }
+
+        private TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
+        {
+            if (!Functions.TryGetValue(address, out TranslatedFunction func))
+            {
+                func = Translate(address, mode);
+
+                TranslatedFunction oldFunc = Functions.GetOrAdd(address, func.GuestSize, func);
+
+                if (oldFunc != func)
+                {
+                    JitCache.Unmap(func.FuncPointer);
+                    func = oldFunc;
+                }
+
+                RegisterFunction(address, func);
+            }
+
+            return func;
+        }
+
+        internal void RegisterFunction(ulong guestAddress, TranslatedFunction func)
+        {
+            if (FunctionTable.IsValid(guestAddress))
+            {
+                Volatile.Write(ref FunctionTable.GetValue(guestAddress), (ulong)func.FuncPointer);
+            }
+        }
+
+        private TranslatedFunction Translate(ulong address, ExecutionMode mode)
+        {
+            CompiledFunction func = Compile(address, mode);
+            IntPtr funcPointer = JitCache.Map(func.Code);
+
+            return new TranslatedFunction(funcPointer, (ulong)func.GuestCodeLength);
+        }
+
+        private CompiledFunction Compile(ulong address, ExecutionMode mode)
+        {
+            return AarchCompiler.Compile(CpuPresets.CortexA57, Memory, address, FunctionTable, Stubs.DispatchStub, mode, RuntimeInformation.ProcessArchitecture);
+        }
+
+        public void InvalidateJitCacheRegion(ulong address, ulong size)
+        {
+            ulong[] overlapAddresses = Array.Empty<ulong>();
+
+            int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses);
+
+            for (int index = 0; index < overlapsCount; index++)
+            {
+                ulong overlapAddress = overlapAddresses[index];
+
+                if (Functions.TryGetValue(overlapAddress, out TranslatedFunction overlap))
+                {
+                    Functions.Remove(overlapAddress);
+                    Volatile.Write(ref FunctionTable.GetValue(overlapAddress), FunctionTable.Fill);
+                    EnqueueForDeletion(overlapAddress, overlap);
+                }
+            }
+
+            // TODO: Remove overlapping functions from the JitCache aswell.
+            // This should be done safely, with a mechanism to ensure the function is not being executed.
+        }
+
+        private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func)
+        {
+            _oldFuncs.Enqueue(new(guestAddress, func));
+        }
+
+        private void ClearJitCache()
+        {
+            List<TranslatedFunction> functions = Functions.AsList();
+
+            foreach (var func in functions)
+            {
+                JitCache.Unmap(func.FuncPointer);
+            }
+
+            Functions.Clear();
+
+            while (_oldFuncs.TryDequeue(out var kv))
+            {
+                JitCache.Unmap(kv.Value.FuncPointer);
+            }
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                {
+                    if (_noWxCache != null)
+                    {
+                        _noWxCache.Dispose();
+                    }
+                    else
+                    {
+                        ClearJitCache();
+                    }
+
+                    Stubs.Dispose();
+                    FunctionTable.Dispose();
+                }
+
+                _disposed = true;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs
new file mode 100644
index 00000000..60e13de9
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs
@@ -0,0 +1,96 @@
+using ARMeilleure.Translation;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    internal class TranslatorCache<T>
+    {
+        private readonly IntervalTree<ulong, T> _tree;
+        private readonly ReaderWriterLockSlim _treeLock;
+
+        public int Count => _tree.Count;
+
+        public TranslatorCache()
+        {
+            _tree = new IntervalTree<ulong, T>();
+            _treeLock = new ReaderWriterLockSlim();
+        }
+
+        public bool TryAdd(ulong address, ulong size, T value)
+        {
+            return AddOrUpdate(address, size, value, null);
+        }
+
+        public bool AddOrUpdate(ulong address, ulong size, T value, Func<ulong, T, T> updateFactoryCallback)
+        {
+            _treeLock.EnterWriteLock();
+            bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback);
+            _treeLock.ExitWriteLock();
+
+            return result;
+        }
+
+        public T GetOrAdd(ulong address, ulong size, T value)
+        {
+            _treeLock.EnterWriteLock();
+            value = _tree.GetOrAdd(address, address + size, value);
+            _treeLock.ExitWriteLock();
+
+            return value;
+        }
+
+        public bool Remove(ulong address)
+        {
+            _treeLock.EnterWriteLock();
+            bool removed = _tree.Remove(address) != 0;
+            _treeLock.ExitWriteLock();
+
+            return removed;
+        }
+
+        public void Clear()
+        {
+            _treeLock.EnterWriteLock();
+            _tree.Clear();
+            _treeLock.ExitWriteLock();
+        }
+
+        public bool ContainsKey(ulong address)
+        {
+            _treeLock.EnterReadLock();
+            bool result = _tree.ContainsKey(address);
+            _treeLock.ExitReadLock();
+
+            return result;
+        }
+
+        public bool TryGetValue(ulong address, out T value)
+        {
+            _treeLock.EnterReadLock();
+            bool result = _tree.TryGet(address, out value);
+            _treeLock.ExitReadLock();
+
+            return result;
+        }
+
+        public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps)
+        {
+            _treeLock.EnterReadLock();
+            int count = _tree.Get(address, address + size, ref overlaps);
+            _treeLock.ExitReadLock();
+
+            return count;
+        }
+
+        public List<T> AsList()
+        {
+            _treeLock.EnterReadLock();
+            List<T> list = _tree.AsList();
+            _treeLock.ExitReadLock();
+
+            return list;
+        }
+    }
+}
diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs
new file mode 100644
index 00000000..914712bb
--- /dev/null
+++ b/src/Ryujinx.Cpu/LightningJit/TranslatorStubs.cs
@@ -0,0 +1,380 @@
+using ARMeilleure.Common;
+using Ryujinx.Cpu.LightningJit.Cache;
+using Ryujinx.Cpu.LightningJit.CodeGen;
+using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
+using Ryujinx.Cpu.LightningJit.State;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Cpu.LightningJit
+{
+    delegate void DispatcherFunction(IntPtr nativeContext, ulong startAddress);
+
+    /// <summary>
+    /// Represents a stub manager.
+    /// </summary>
+    class TranslatorStubs : IDisposable
+    {
+        private delegate ulong GetFunctionAddressDelegate(IntPtr framePointer, ulong address);
+
+        private readonly Lazy<IntPtr> _slowDispatchStub;
+
+        private bool _disposed;
+
+        private readonly AddressTable<ulong> _functionTable;
+        private readonly NoWxCache _noWxCache;
+        private readonly GetFunctionAddressDelegate _getFunctionAddressRef;
+        private readonly IntPtr _getFunctionAddress;
+        private readonly Lazy<IntPtr> _dispatchStub;
+        private readonly Lazy<DispatcherFunction> _dispatchLoop;
+
+        /// <summary>
+        /// Gets the dispatch stub.
+        /// </summary>
+        /// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception>
+        public IntPtr DispatchStub
+        {
+            get
+            {
+                ObjectDisposedException.ThrowIf(_disposed, this);
+
+                return _dispatchStub.Value;
+            }
+        }
+
+        /// <summary>
+        /// Gets the slow dispatch stub.
+        /// </summary>
+        /// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception>
+        public IntPtr SlowDispatchStub
+        {
+            get
+            {
+                ObjectDisposedException.ThrowIf(_disposed, this);
+
+                return _slowDispatchStub.Value;
+            }
+        }
+
+        /// <summary>
+        /// Gets the dispatch loop function.
+        /// </summary>
+        /// <exception cref="ObjectDisposedException"><see cref="TranslatorStubs"/> instance was disposed</exception>
+        public DispatcherFunction DispatchLoop
+        {
+            get
+            {
+                ObjectDisposedException.ThrowIf(_disposed, this);
+
+                return _dispatchLoop.Value;
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TranslatorStubs"/> class with the specified
+        /// <see cref="Translator"/> instance.
+        /// </summary>
+        /// <param name="functionTable">Function table used to store pointers to the functions that the guest code will call</param>
+        /// <param name="noWxCache">Cache used on platforms that enforce W^X, otherwise should be null</param>
+        /// <exception cref="ArgumentNullException"><paramref name="translator"/> is null</exception>
+        public TranslatorStubs(AddressTable<ulong> functionTable, NoWxCache noWxCache)
+        {
+            ArgumentNullException.ThrowIfNull(functionTable);
+
+            _functionTable = functionTable;
+            _noWxCache = noWxCache;
+            _getFunctionAddressRef = NativeInterface.GetFunctionAddress;
+            _getFunctionAddress = Marshal.GetFunctionPointerForDelegate(_getFunctionAddressRef);
+            _slowDispatchStub = new(GenerateSlowDispatchStub, isThreadSafe: true);
+            _dispatchStub = new(GenerateDispatchStub, isThreadSafe: true);
+            _dispatchLoop = new(GenerateDispatchLoop, isThreadSafe: true);
+        }
+
+        /// <summary>
+        /// Releases all resources used by the <see cref="TranslatorStubs"/> instance.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Releases all unmanaged and optionally managed resources used by the <see cref="TranslatorStubs"/> instance.
+        /// </summary>
+        /// <param name="disposing"><see langword="true"/> to dispose managed resources also; otherwise just unmanaged resouces</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_noWxCache == null)
+                {
+                    if (_dispatchStub.IsValueCreated)
+                    {
+                        JitCache.Unmap(_dispatchStub.Value);
+                    }
+
+                    if (_dispatchLoop.IsValueCreated)
+                    {
+                        JitCache.Unmap(Marshal.GetFunctionPointerForDelegate(_dispatchLoop.Value));
+                    }
+                }
+
+                _disposed = true;
+            }
+        }
+
+        /// <summary>
+        /// Frees resources used by the <see cref="TranslatorStubs"/> instance.
+        /// </summary>
+        ~TranslatorStubs()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Generates a <see cref="DispatchStub"/>.
+        /// </summary>
+        /// <returns>Generated <see cref="DispatchStub"/></returns>
+        private IntPtr GenerateDispatchStub()
+        {
+            List<int> branchToFallbackOffsets = new();
+
+            CodeWriter writer = new();
+
+            if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+            {
+                Assembler asm = new(writer);
+                RegisterSaveRestore rsr = new((1u << 19) | (1u << 21) | (1u << 22), hasCall: true);
+
+                rsr.WritePrologue(ref asm);
+
+                Operand context = Register(19);
+                asm.Mov(context, Register(0));
+
+                // Load the target guest address from the native context.
+                Operand guestAddress = Register(16);
+
+                asm.LdrRiUn(guestAddress, context, NativeContext.GetDispatchAddressOffset());
+
+                // Check if guest address is within range of the AddressTable.
+                asm.And(Register(17), guestAddress, Const(~_functionTable.Mask));
+
+                branchToFallbackOffsets.Add(writer.InstructionPointer);
+
+                asm.Cbnz(Register(17), 0);
+
+                Operand page = Register(17);
+                Operand index = Register(21);
+                Operand mask = Register(22);
+
+                asm.Mov(page, (ulong)_functionTable.Base);
+
+                for (int i = 0; i < _functionTable.Levels.Length; i++)
+                {
+                    ref var level = ref _functionTable.Levels[i];
+
+                    asm.Mov(mask, level.Mask >> level.Index);
+                    asm.And(index, mask, guestAddress, ArmShiftType.Lsr, level.Index);
+
+                    if (i < _functionTable.Levels.Length - 1)
+                    {
+                        asm.LdrRr(page, page, index, ArmExtensionType.Uxtx, true);
+
+                        branchToFallbackOffsets.Add(writer.InstructionPointer);
+
+                        asm.Cbz(page, 0);
+                    }
+                }
+
+                asm.LdrRr(page, page, index, ArmExtensionType.Uxtx, true);
+
+                rsr.WriteEpilogue(ref asm);
+
+                asm.Br(page);
+
+                foreach (int branchOffset in branchToFallbackOffsets)
+                {
+                    uint branchInst = writer.ReadInstructionAt(branchOffset);
+                    Debug.Assert(writer.InstructionPointer > branchOffset);
+                    writer.WriteInstructionAt(branchOffset, branchInst | ((uint)(writer.InstructionPointer - branchOffset) << 5));
+                }
+
+                // Fallback.
+                asm.Mov(Register(0), Register(29));
+                asm.Mov(Register(1), guestAddress);
+                asm.Mov(Register(16), (ulong)_getFunctionAddress);
+                asm.Blr(Register(16));
+                asm.Mov(Register(16), Register(0));
+                asm.Mov(Register(0), Register(19));
+
+                rsr.WriteEpilogue(ref asm);
+
+                asm.Br(Register(16));
+            }
+            else
+            {
+                throw new PlatformNotSupportedException();
+            }
+
+            return Map(writer.AsByteSpan());
+        }
+
+        /// <summary>
+        /// Generates a <see cref="SlowDispatchStub"/>.
+        /// </summary>
+        /// <returns>Generated <see cref="SlowDispatchStub"/></returns>
+        private IntPtr GenerateSlowDispatchStub()
+        {
+            CodeWriter writer = new();
+
+            if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+            {
+                Assembler asm = new(writer);
+                RegisterSaveRestore rsr = new(1u << 19, hasCall: true);
+
+                rsr.WritePrologue(ref asm);
+
+                Operand context = Register(19);
+                asm.Mov(context, Register(0));
+
+                // Load the target guest address from the native context.
+                asm.Mov(Register(0), Register(29));
+                asm.LdrRiUn(Register(1), context, NativeContext.GetDispatchAddressOffset());
+                asm.Mov(Register(16), (ulong)_getFunctionAddress);
+                asm.Blr(Register(16));
+                asm.Mov(Register(16), Register(0));
+                asm.Mov(Register(0), Register(19));
+
+                rsr.WriteEpilogue(ref asm);
+
+                asm.Br(Register(16));
+            }
+            else
+            {
+                throw new PlatformNotSupportedException();
+            }
+
+            return Map(writer.AsByteSpan());
+        }
+
+        /// <summary>
+        /// Emits code that syncs FP state before executing guest code, or returns it to normal.
+        /// </summary>
+        /// <param name="asm">Assembler</param>
+        /// <param name="context">Pointer to the native context</param>
+        /// <param name="tempRegister">First temporary register</param>
+        /// <param name="tempRegister2">Second temporary register</param>
+        /// <param name="enter">True if entering guest code, false otherwise</param>
+        private static void EmitSyncFpContext(ref Assembler asm, Operand context, Operand tempRegister, Operand tempRegister2, bool enter)
+        {
+            if (enter)
+            {
+                EmitSwapFpFlags(ref asm, context, tempRegister, tempRegister2, NativeContext.GetFpFlagsOffset(), NativeContext.GetHostFpFlagsOffset());
+            }
+            else
+            {
+                EmitSwapFpFlags(ref asm, context, tempRegister, tempRegister2, NativeContext.GetHostFpFlagsOffset(), NativeContext.GetFpFlagsOffset());
+            }
+        }
+
+        /// <summary>
+        /// Swaps the FPCR and FPSR values with values stored in the native context.
+        /// </summary>
+        /// <param name="asm">Assembler</param>
+        /// <param name="context">Pointer to the native context</param>
+        /// <param name="tempRegister">First temporary register</param>
+        /// <param name="tempRegister2">Second temporary register</param>
+        /// <param name="loadOffset">Offset of the new flags that will be loaded</param>
+        /// <param name="storeOffset">Offset where the current flags should be saved</param>
+        private static void EmitSwapFpFlags(ref Assembler asm, Operand context, Operand tempRegister, Operand tempRegister2, int loadOffset, int storeOffset)
+        {
+            asm.MrsFpcr(tempRegister);
+            asm.MrsFpsr(tempRegister2);
+            asm.Orr(tempRegister, tempRegister, tempRegister2);
+
+            asm.StrRiUn(tempRegister, context, storeOffset);
+
+            asm.LdrRiUn(tempRegister, context, loadOffset);
+            asm.MsrFpcr(tempRegister);
+            asm.MsrFpsr(tempRegister2);
+        }
+
+        /// <summary>
+        /// Generates a <see cref="DispatchLoop"/> function.
+        /// </summary>
+        /// <returns><see cref="DispatchLoop"/> function</returns>
+        private DispatcherFunction GenerateDispatchLoop()
+        {
+            CodeWriter writer = new();
+
+            if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+            {
+                Assembler asm = new(writer);
+                RegisterSaveRestore rsr = new(1u << 19, hasCall: true);
+
+                rsr.WritePrologue(ref asm);
+
+                Operand context = Register(19);
+                asm.Mov(context, Register(0));
+
+                EmitSyncFpContext(ref asm, context, Register(16, OperandType.I32), Register(17, OperandType.I32), true);
+
+                // Load the target guest address from the native context.
+                Operand guestAddress = Register(16);
+
+                asm.Mov(guestAddress, Register(1));
+
+                int loopStartIndex = writer.InstructionPointer;
+
+                asm.StrRiUn(guestAddress, context, NativeContext.GetDispatchAddressOffset());
+                asm.Mov(Register(0), context);
+                asm.Mov(Register(17), (ulong)DispatchStub);
+                asm.Blr(Register(17));
+                asm.Mov(guestAddress, Register(0));
+                asm.Cbz(guestAddress, 16);
+                asm.LdrRiUn(Register(17), context, NativeContext.GetRunningOffset());
+                asm.Cbz(Register(17), 8);
+                asm.B((loopStartIndex - writer.InstructionPointer) * 4);
+
+                EmitSyncFpContext(ref asm, context, Register(16, OperandType.I32), Register(17, OperandType.I32), false);
+
+                rsr.WriteEpilogue(ref asm);
+
+                asm.Ret();
+            }
+            else
+            {
+                throw new PlatformNotSupportedException();
+            }
+
+            IntPtr pointer = Map(writer.AsByteSpan());
+
+            return Marshal.GetDelegateForFunctionPointer<DispatcherFunction>(pointer);
+        }
+
+        private IntPtr Map(ReadOnlySpan<byte> code)
+        {
+            if (_noWxCache != null)
+            {
+                return _noWxCache.MapPageAligned(code);
+            }
+            else
+            {
+                return JitCache.Map(code);
+            }
+        }
+
+        private static Operand Register(int register, OperandType type = OperandType.I64)
+        {
+            return new Operand(register, RegisterType.Integer, type);
+        }
+
+        private static Operand Const(ulong value)
+        {
+            return new(OperandKind.Constant, OperandType.I64, value);
+        }
+    }
+}
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
index 4de00978..fde489ab 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContext.cs
@@ -87,6 +87,8 @@ namespace Ryujinx.HLE.HOS
                 _memoryManager = null;
                 _gpuContext.UnregisterProcess(_pid);
             }
+
+            _cpuContext.Dispose();
         }
     }
 }
diff --git a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
index bec2722e..06b8fd34 100644
--- a/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
+++ b/src/Ryujinx.HLE/HOS/ArmProcessContextFactory.cs
@@ -3,6 +3,7 @@ using Ryujinx.Common.Logging;
 using Ryujinx.Cpu;
 using Ryujinx.Cpu.AppleHv;
 using Ryujinx.Cpu.Jit;
+using Ryujinx.Cpu.LightningJit;
 using Ryujinx.Graphics.Gpu;
 using Ryujinx.HLE.HOS.Kernel;
 using Ryujinx.HLE.HOS.Kernel.Process;
@@ -46,7 +47,9 @@ namespace Ryujinx.HLE.HOS
         {
             IArmProcessContext processContext;
 
-            if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64 && for64Bit && context.Device.Configuration.UseHypervisor)
+            bool isArm64Host = RuntimeInformation.ProcessArchitecture == Architecture.Arm64;
+
+            if (OperatingSystem.IsMacOS() && isArm64Host && for64Bit && context.Device.Configuration.UseHypervisor)
             {
                 var cpuEngine = new HvEngine(_tickSource);
                 var memoryManager = new HvMemoryManager(context.Memory, addressSpaceSize, invalidAccessHandler);
@@ -63,7 +66,9 @@ namespace Ryujinx.HLE.HOS
                     mode = MemoryManagerMode.SoftwarePageTable;
                 }
 
-                var cpuEngine = new JitEngine(_tickSource);
+                ICpuEngine cpuEngine = isArm64Host && (mode == MemoryManagerMode.HostMapped || mode == MemoryManagerMode.HostMappedUnsafe)
+                    ? new LightningJitEngine(_tickSource)
+                    : new JitEngine(_tickSource);
 
                 AddressSpace addressSpace = null;