From 36e8e074c90f11480389560e3f019a161f82efbe Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Mon, 10 Dec 2018 22:58:52 -0200
Subject: [PATCH] Misc. CPU improvements (#519)

* Fix and simplify TranslatorCache

* Fix some assignment alignments, remove some unused usings

* Changes to ILEmitter, separate it from ILEmitterCtx

* Rename ILEmitter to ILMethodBuilder

* Rename LdrLit and *_Fix opcodes

* Revert TranslatorCache impl to the more performant one, fix a few issues with it

* Allow EmitOpCode to be called even after everything has been emitted

* Make Emit and AdvanceOpCode private, simplify it a bit now that it starts emiting from the entry point

* Remove unneeded temp use

* Add missing exit call on TestExclusive

* Use better hash

* Implement the == and != operators
---
 ChocolArm64/Decoders/Decoder.cs               |   40 +-
 ChocolArm64/Decoders/OpCodeAlu64.cs           |    5 +-
 ChocolArm64/Decoders/OpCodeAluRs64.cs         |    2 +-
 ChocolArm64/Decoders/OpCodeAluRx64.cs         |    4 +-
 ChocolArm64/Decoders/OpCodeBImmCmp64.cs       |    1 -
 ChocolArm64/Decoders/OpCodeCcmp64.cs          |    4 +-
 ChocolArm64/Decoders/OpCodeCsel64.cs          |    2 +-
 ChocolArm64/Decoders/OpCodeMemImm64.cs        |    2 +-
 ChocolArm64/Decoders/OpCodeMemReg64.cs        |    6 +-
 ChocolArm64/Decoders/OpCodeMov64.cs           |    1 -
 ChocolArm64/Decoders/OpCodeSimdCvt64.cs       |    1 -
 ChocolArm64/Decoders/OpCodeSimdImm64.cs       |    5 +-
 ChocolArm64/Decoders/OpCodeSimdMemMs64.cs     |    1 -
 ChocolArm64/Decoders/OpCodeSimdMemSs64.cs     |    1 -
 ChocolArm64/Decoders/ShiftType.cs             |    8 +-
 ChocolArm64/Instructions/InstEmitException.cs |    4 +-
 ChocolArm64/Instructions/InstEmitFlow.cs      |    5 +-
 ChocolArm64/Instructions/InstEmitMemory.cs    |    2 +-
 ChocolArm64/Instructions/InstEmitSimdCvt.cs   |    4 +-
 ChocolArm64/Memory/MemoryManager.cs           |    2 +
 ChocolArm64/OpCodeTable.cs                    | 1032 ++++++++---------
 ChocolArm64/TranslatedSub.cs                  |   20 +-
 ChocolArm64/Translation/IILEmit.cs            |    2 +-
 ChocolArm64/Translation/ILBarrier.cs          |    2 +-
 ChocolArm64/Translation/ILBlock.cs            |   40 +-
 ChocolArm64/Translation/ILEmitterCtx.cs       |  241 ++--
 ChocolArm64/Translation/ILLabel.cs            |    4 +-
 .../{ILEmitter.cs => ILMethodBuilder.cs}      |  106 +-
 ChocolArm64/Translation/ILOpCode.cs           |    2 +-
 ChocolArm64/Translation/ILOpCodeBranch.cs     |    2 +-
 ChocolArm64/Translation/ILOpCodeCall.cs       |    2 +-
 ChocolArm64/Translation/ILOpCodeConst.cs      |    2 +-
 ChocolArm64/Translation/ILOpCodeLoad.cs       |   37 +-
 ChocolArm64/Translation/ILOpCodeLoadState.cs  |   42 +
 ChocolArm64/Translation/ILOpCodeLog.cs        |    2 +-
 ChocolArm64/Translation/ILOpCodeStore.cs      |   37 +-
 ChocolArm64/Translation/ILOpCodeStoreState.cs |   42 +
 ChocolArm64/Translation/IoType.cs             |    5 -
 ChocolArm64/Translation/LocalAlloc.cs         |   61 +-
 ChocolArm64/Translator.cs                     |   56 +-
 ChocolArm64/TranslatorCache.cs                |   21 +-
 41 files changed, 943 insertions(+), 915 deletions(-)
 rename ChocolArm64/Translation/{ILEmitter.cs => ILMethodBuilder.cs} (51%)
 create mode 100644 ChocolArm64/Translation/ILOpCodeLoadState.cs
 create mode 100644 ChocolArm64/Translation/ILOpCodeStoreState.cs

diff --git a/ChocolArm64/Decoders/Decoder.cs b/ChocolArm64/Decoders/Decoder.cs
index db43ac4fe8..1d4f397ac0 100644
--- a/ChocolArm64/Decoders/Decoder.cs
+++ b/ChocolArm64/Decoders/Decoder.cs
@@ -28,11 +28,11 @@ namespace ChocolArm64.Decoders
             return block;
         }
 
-        public static (Block[] Graph, Block Root) DecodeSubroutine(
-            TranslatorCache  cache,
-            CpuThreadState   state,
-            MemoryManager    memory,
-            long             start)
+        public static Block DecodeSubroutine(
+            TranslatorCache cache,
+            CpuThreadState  state,
+            MemoryManager   memory,
+            long            start)
         {
             Dictionary<long, Block> visited    = new Dictionary<long, Block>();
             Dictionary<long, Block> visitedEnd = new Dictionary<long, Block>();
@@ -53,7 +53,7 @@ namespace ChocolArm64.Decoders
                 return output;
             }
 
-            Block root = Enqueue(start);
+            Block entry = Enqueue(start);
 
             while (blocks.Count > 0)
             {
@@ -118,33 +118,7 @@ namespace ChocolArm64.Decoders
                 visitedEnd.Add(current.EndPosition, current);
             }
 
-            //Make and sort Graph blocks array by position.
-            Block[] graph = new Block[visited.Count];
-
-            while (visited.Count > 0)
-            {
-                ulong firstPos = ulong.MaxValue;
-
-                foreach (Block block in visited.Values)
-                {
-                    if (firstPos > (ulong)block.Position)
-                        firstPos = (ulong)block.Position;
-                }
-
-                Block current = visited[(long)firstPos];
-
-                do
-                {
-                    graph[graph.Length - visited.Count] = current;
-
-                    visited.Remove(current.Position);
-
-                    current = current.Next;
-                }
-                while (current != null);
-            }
-
-            return (graph, root);
+            return entry;
         }
 
         private static void FillBlock(CpuThreadState state, MemoryManager memory, Block block)
diff --git a/ChocolArm64/Decoders/OpCodeAlu64.cs b/ChocolArm64/Decoders/OpCodeAlu64.cs
index 5f094572ef..b46fef4f7a 100644
--- a/ChocolArm64/Decoders/OpCodeAlu64.cs
+++ b/ChocolArm64/Decoders/OpCodeAlu64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
@@ -12,8 +11,8 @@ namespace ChocolArm64.Decoders
 
         public OpCodeAlu64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Rd     =           (opCode >>  0) & 0x1f;
-            Rn     =           (opCode >>  5) & 0x1f;
+            Rd     =          (opCode >>  0) & 0x1f;
+            Rn     =          (opCode >>  5) & 0x1f;
             DataOp = (DataOp)((opCode >> 24) & 0x3);
 
             RegisterSize = (opCode >> 31) != 0
diff --git a/ChocolArm64/Decoders/OpCodeAluRs64.cs b/ChocolArm64/Decoders/OpCodeAluRs64.cs
index f24c7f37bd..bed840b8ea 100644
--- a/ChocolArm64/Decoders/OpCodeAluRs64.cs
+++ b/ChocolArm64/Decoders/OpCodeAluRs64.cs
@@ -22,7 +22,7 @@ namespace ChocolArm64.Decoders
 
             Shift = shift;
 
-            Rm        =              (opCode >> 16) & 0x1f;
+            Rm        =             (opCode >> 16) & 0x1f;
             ShiftType = (ShiftType)((opCode >> 22) & 0x3);
         }
     }
diff --git a/ChocolArm64/Decoders/OpCodeAluRx64.cs b/ChocolArm64/Decoders/OpCodeAluRx64.cs
index a36f94ca89..24cee056cb 100644
--- a/ChocolArm64/Decoders/OpCodeAluRx64.cs
+++ b/ChocolArm64/Decoders/OpCodeAluRx64.cs
@@ -11,9 +11,9 @@ namespace ChocolArm64.Decoders
 
         public OpCodeAluRx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Shift   =            (opCode >> 10) & 0x7;
+            Shift   =           (opCode >> 10) & 0x7;
             IntType = (IntType)((opCode >> 13) & 0x7);
-            Rm      =            (opCode >> 16) & 0x1f;
+            Rm      =           (opCode >> 16) & 0x1f;
         }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeBImmCmp64.cs b/ChocolArm64/Decoders/OpCodeBImmCmp64.cs
index 6f43319918..2e674a54c3 100644
--- a/ChocolArm64/Decoders/OpCodeBImmCmp64.cs
+++ b/ChocolArm64/Decoders/OpCodeBImmCmp64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
diff --git a/ChocolArm64/Decoders/OpCodeCcmp64.cs b/ChocolArm64/Decoders/OpCodeCcmp64.cs
index e2aae96dee..8e91f15ae7 100644
--- a/ChocolArm64/Decoders/OpCodeCcmp64.cs
+++ b/ChocolArm64/Decoders/OpCodeCcmp64.cs
@@ -21,9 +21,9 @@ namespace ChocolArm64.Decoders
                 return;
             }
 
-            Nzcv  =         (opCode >>  0) & 0xf;
+            Nzcv  =        (opCode >>  0) & 0xf;
             Cond  = (Cond)((opCode >> 12) & 0xf);
-            RmImm =         (opCode >> 16) & 0x1f;
+            RmImm =        (opCode >> 16) & 0x1f;
 
             Rd = CpuThreadState.ZrIndex;
         }
diff --git a/ChocolArm64/Decoders/OpCodeCsel64.cs b/ChocolArm64/Decoders/OpCodeCsel64.cs
index d085a82378..d1a5a2dbee 100644
--- a/ChocolArm64/Decoders/OpCodeCsel64.cs
+++ b/ChocolArm64/Decoders/OpCodeCsel64.cs
@@ -10,7 +10,7 @@ namespace ChocolArm64.Decoders
 
         public OpCodeCsel64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Rm   =         (opCode >> 16) & 0x1f;
+            Rm   =        (opCode >> 16) & 0x1f;
             Cond = (Cond)((opCode >> 12) & 0xf);
         }
     }
diff --git a/ChocolArm64/Decoders/OpCodeMemImm64.cs b/ChocolArm64/Decoders/OpCodeMemImm64.cs
index edaa4970ae..d9f322eac2 100644
--- a/ChocolArm64/Decoders/OpCodeMemImm64.cs
+++ b/ChocolArm64/Decoders/OpCodeMemImm64.cs
@@ -41,7 +41,7 @@ namespace ChocolArm64.Decoders
             if (WBack || Unscaled)
             {
                 //9-bits Signed Immediate.
-                Imm = (opCode << 43) >> 55;
+                Imm = (opCode << 11) >> 23;
             }
             else
             {
diff --git a/ChocolArm64/Decoders/OpCodeMemReg64.cs b/ChocolArm64/Decoders/OpCodeMemReg64.cs
index 3dd210fbd2..2eb734aa39 100644
--- a/ChocolArm64/Decoders/OpCodeMemReg64.cs
+++ b/ChocolArm64/Decoders/OpCodeMemReg64.cs
@@ -11,10 +11,10 @@ namespace ChocolArm64.Decoders
 
         public OpCodeMemReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Shift    =           ((opCode >> 12) & 0x1) != 0;
+            Shift    =          ((opCode >> 12) & 0x1) != 0;
             IntType  = (IntType)((opCode >> 13) & 0x7);
-            Rm       =            (opCode >> 16) & 0x1f;
-            Extend64 =           ((opCode >> 22) & 0x3) == 2;
+            Rm       =           (opCode >> 16) & 0x1f;
+            Extend64 =          ((opCode >> 22) & 0x3) == 2;
         }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Decoders/OpCodeMov64.cs b/ChocolArm64/Decoders/OpCodeMov64.cs
index f969785479..7dbd92472b 100644
--- a/ChocolArm64/Decoders/OpCodeMov64.cs
+++ b/ChocolArm64/Decoders/OpCodeMov64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
diff --git a/ChocolArm64/Decoders/OpCodeSimdCvt64.cs b/ChocolArm64/Decoders/OpCodeSimdCvt64.cs
index 6c68a3af26..eacd594099 100644
--- a/ChocolArm64/Decoders/OpCodeSimdCvt64.cs
+++ b/ChocolArm64/Decoders/OpCodeSimdCvt64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
diff --git a/ChocolArm64/Decoders/OpCodeSimdImm64.cs b/ChocolArm64/Decoders/OpCodeSimdImm64.cs
index 3ef6a8c6e2..37ee504d28 100644
--- a/ChocolArm64/Decoders/OpCodeSimdImm64.cs
+++ b/ChocolArm64/Decoders/OpCodeSimdImm64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
@@ -61,12 +60,12 @@ namespace ChocolArm64.Decoders
             else if ((modeHigh & 0b110) == 0b100)
             {
                 //16-bits shifted Immediate.
-                Size = 1; imm <<= (modeHigh & 1) << 3; 
+                Size = 1; imm <<= (modeHigh & 1) << 3;
             }
             else if ((modeHigh & 0b100) == 0b000)
             {
                 //32-bits shifted Immediate.
-                Size = 2; imm <<= modeHigh << 3; 
+                Size = 2; imm <<= modeHigh << 3;
             }
             else if ((modeHigh & 0b111) == 0b110)
             {
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs b/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
index 0748ef43f3..83297c4146 100644
--- a/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
+++ b/ChocolArm64/Decoders/OpCodeSimdMemMs64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
diff --git a/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs b/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
index 07ec8ab730..1b0ead3311 100644
--- a/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
+++ b/ChocolArm64/Decoders/OpCodeSimdMemSs64.cs
@@ -1,5 +1,4 @@
 using ChocolArm64.Instructions;
-using ChocolArm64.State;
 
 namespace ChocolArm64.Decoders
 {
diff --git a/ChocolArm64/Decoders/ShiftType.cs b/ChocolArm64/Decoders/ShiftType.cs
index 5f6a7a4ca8..cad4310346 100644
--- a/ChocolArm64/Decoders/ShiftType.cs
+++ b/ChocolArm64/Decoders/ShiftType.cs
@@ -2,9 +2,9 @@ namespace ChocolArm64.Decoders
 {
     enum ShiftType
     {
-        Lsl,
-        Lsr,
-        Asr,
-        Ror
+        Lsl = 0,
+        Lsr = 1,
+        Asr = 2,
+        Ror = 3
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Instructions/InstEmitException.cs b/ChocolArm64/Instructions/InstEmitException.cs
index 8325a3978f..9444397ae6 100644
--- a/ChocolArm64/Instructions/InstEmitException.cs
+++ b/ChocolArm64/Instructions/InstEmitException.cs
@@ -48,7 +48,7 @@ namespace ChocolArm64.Instructions
 
             if (context.CurrBlock.Next != null)
             {
-                context.EmitLoadState(context.CurrBlock.Next);
+                context.EmitLoadState();
             }
             else
             {
@@ -73,7 +73,7 @@ namespace ChocolArm64.Instructions
 
             if (context.CurrBlock.Next != null)
             {
-                context.EmitLoadState(context.CurrBlock.Next);
+                context.EmitLoadState();
             }
             else
             {
diff --git a/ChocolArm64/Instructions/InstEmitFlow.cs b/ChocolArm64/Instructions/InstEmitFlow.cs
index 0e9f7cb017..758bf2120c 100644
--- a/ChocolArm64/Instructions/InstEmitFlow.cs
+++ b/ChocolArm64/Instructions/InstEmitFlow.cs
@@ -58,7 +58,7 @@ namespace ChocolArm64.Instructions
 
                 context.Emit(OpCodes.Pop);
 
-                context.EmitLoadState(context.CurrBlock.Next);
+                context.EmitLoadState();
             }
             else
             {
@@ -73,13 +73,10 @@ namespace ChocolArm64.Instructions
             OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;
 
             context.EmitLdintzr(op.Rn);
-            context.EmitSttmp();
-
             context.EmitLdc_I(op.Position + 4);
             context.EmitStint(CpuThreadState.LrIndex);
             context.EmitStoreState();
 
-            context.EmitLdtmp();
             context.Emit(OpCodes.Ret);
         }
 
diff --git a/ChocolArm64/Instructions/InstEmitMemory.cs b/ChocolArm64/Instructions/InstEmitMemory.cs
index 96e45b3f74..96f782df64 100644
--- a/ChocolArm64/Instructions/InstEmitMemory.cs
+++ b/ChocolArm64/Instructions/InstEmitMemory.cs
@@ -60,7 +60,7 @@ namespace ChocolArm64.Instructions
             EmitWBackIfNeeded(context);
         }
 
-        public static void LdrLit(ILEmitterCtx context)
+        public static void Ldr_Literal(ILEmitterCtx context)
         {
             IOpCodeLit64 op = (IOpCodeLit64)context.CurrOp;
 
diff --git a/ChocolArm64/Instructions/InstEmitSimdCvt.cs b/ChocolArm64/Instructions/InstEmitSimdCvt.cs
index fe8722af3c..fd6146b376 100644
--- a/ChocolArm64/Instructions/InstEmitSimdCvt.cs
+++ b/ChocolArm64/Instructions/InstEmitSimdCvt.cs
@@ -244,7 +244,7 @@ namespace ChocolArm64.Instructions
             EmitFcvt_s_Gp(context, () => { });
         }
 
-        public static void Fcvtzs_Gp_Fix(ILEmitterCtx context)
+        public static void Fcvtzs_Gp_Fixed(ILEmitterCtx context)
         {
             EmitFcvtzs_Gp_Fix(context);
         }
@@ -264,7 +264,7 @@ namespace ChocolArm64.Instructions
             EmitFcvt_u_Gp(context, () => { });
         }
 
-        public static void Fcvtzu_Gp_Fix(ILEmitterCtx context)
+        public static void Fcvtzu_Gp_Fixed(ILEmitterCtx context)
         {
             EmitFcvtzu_Gp_Fix(context);
         }
diff --git a/ChocolArm64/Memory/MemoryManager.cs b/ChocolArm64/Memory/MemoryManager.cs
index 68d9100b3c..eacb533612 100644
--- a/ChocolArm64/Memory/MemoryManager.cs
+++ b/ChocolArm64/Memory/MemoryManager.cs
@@ -119,6 +119,8 @@ namespace ChocolArm64.Memory
 
             if (!_monitors.TryGetValue(core, out ArmMonitor threadMon))
             {
+                Monitor.Exit(_monitors);
+
                 return false;
             }
 
diff --git a/ChocolArm64/OpCodeTable.cs b/ChocolArm64/OpCodeTable.cs
index 9b9b993a7f..89510fbe39 100644
--- a/ChocolArm64/OpCodeTable.cs
+++ b/ChocolArm64/OpCodeTable.cs
@@ -21,524 +21,524 @@ namespace ChocolArm64
 
 #region "OpCode Table (AArch64)"
             //Integer
-            SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstEmit.Adc,           typeof(OpCodeAluRs64));
-            SetA64("x0111010000xxxxx000000xxxxxxxxxx", InstEmit.Adcs,          typeof(OpCodeAluRs64));
-            SetA64("x00100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Add,           typeof(OpCodeAluImm64));
-            SetA64("00001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Add,           typeof(OpCodeAluRs64));
-            SetA64("10001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Add,           typeof(OpCodeAluRs64));
-            SetA64("x0001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Add,           typeof(OpCodeAluRx64));
-            SetA64("x0001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Add,           typeof(OpCodeAluRx64));
-            SetA64("x01100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds,          typeof(OpCodeAluImm64));
-            SetA64("00101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Adds,          typeof(OpCodeAluRs64));
-            SetA64("10101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds,          typeof(OpCodeAluRs64));
-            SetA64("x0101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Adds,          typeof(OpCodeAluRx64));
-            SetA64("x0101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Adds,          typeof(OpCodeAluRx64));
-            SetA64("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adr,           typeof(OpCodeAdr64));
-            SetA64("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adrp,          typeof(OpCodeAdr64));
-            SetA64("0001001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.And,           typeof(OpCodeAluImm64));
-            SetA64("100100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.And,           typeof(OpCodeAluImm64));
-            SetA64("00001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.And,           typeof(OpCodeAluRs64));
-            SetA64("10001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.And,           typeof(OpCodeAluRs64));
-            SetA64("0111001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,          typeof(OpCodeAluImm64));
-            SetA64("111100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,          typeof(OpCodeAluImm64));
-            SetA64("01101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ands,          typeof(OpCodeAluRs64));
-            SetA64("11101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,          typeof(OpCodeAluRs64));
-            SetA64("x0011010110xxxxx001010xxxxxxxxxx", InstEmit.Asrv,          typeof(OpCodeAluRs64));
-            SetA64("000101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.B,             typeof(OpCodeBImmAl64));
-            SetA64("01010100xxxxxxxxxxxxxxxxxxx0xxxx", InstEmit.B_Cond,        typeof(OpCodeBImmCond64));
-            SetA64("00110011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bfm,           typeof(OpCodeBfm64));
-            SetA64("1011001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bfm,           typeof(OpCodeBfm64));
-            SetA64("00001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bic,           typeof(OpCodeAluRs64));
-            SetA64("10001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bic,           typeof(OpCodeAluRs64));
-            SetA64("01101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bics,          typeof(OpCodeAluRs64));
-            SetA64("11101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bics,          typeof(OpCodeAluRs64));
-            SetA64("100101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bl,            typeof(OpCodeBImmAl64));
-            SetA64("1101011000111111000000xxxxx00000", InstEmit.Blr,           typeof(OpCodeBReg64));
-            SetA64("1101011000011111000000xxxxx00000", InstEmit.Br,            typeof(OpCodeBReg64));
-            SetA64("11010100001xxxxxxxxxxxxxxxx00000", InstEmit.Brk,           typeof(OpCodeException64));
-            SetA64("x0110101xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbnz,          typeof(OpCodeBImmCmp64));
-            SetA64("x0110100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbz,           typeof(OpCodeBImmCmp64));
-            SetA64("x0111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmn,          typeof(OpCodeCcmpImm64));
-            SetA64("x0111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmn,          typeof(OpCodeCcmpReg64));
-            SetA64("x1111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmp,          typeof(OpCodeCcmpImm64));
-            SetA64("x1111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmp,          typeof(OpCodeCcmpReg64));
-            SetA64("11010101000000110011xxxx01011111", InstEmit.Clrex,         typeof(OpCodeSystem64));
-            SetA64("x101101011000000000101xxxxxxxxxx", InstEmit.Cls,           typeof(OpCodeAlu64));
-            SetA64("x101101011000000000100xxxxxxxxxx", InstEmit.Clz,           typeof(OpCodeAlu64));
-            SetA64("00011010110xxxxx010000xxxxxxxxxx", InstEmit.Crc32b,        typeof(OpCodeAluRs64));
-            SetA64("00011010110xxxxx010001xxxxxxxxxx", InstEmit.Crc32h,        typeof(OpCodeAluRs64));
-            SetA64("00011010110xxxxx010010xxxxxxxxxx", InstEmit.Crc32w,        typeof(OpCodeAluRs64));
-            SetA64("10011010110xxxxx010011xxxxxxxxxx", InstEmit.Crc32x,        typeof(OpCodeAluRs64));
-            SetA64("00011010110xxxxx010100xxxxxxxxxx", InstEmit.Crc32cb,       typeof(OpCodeAluRs64));
-            SetA64("00011010110xxxxx010101xxxxxxxxxx", InstEmit.Crc32ch,       typeof(OpCodeAluRs64));
-            SetA64("00011010110xxxxx010110xxxxxxxxxx", InstEmit.Crc32cw,       typeof(OpCodeAluRs64));
-            SetA64("10011010110xxxxx010111xxxxxxxxxx", InstEmit.Crc32cx,       typeof(OpCodeAluRs64));
-            SetA64("x0011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csel,          typeof(OpCodeCsel64));
-            SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csinc,         typeof(OpCodeCsel64));
-            SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csinv,         typeof(OpCodeCsel64));
-            SetA64("x1011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csneg,         typeof(OpCodeCsel64));
-            SetA64("11010101000000110011xxxx10111111", InstEmit.Dmb,           typeof(OpCodeSystem64));
-            SetA64("11010101000000110011xxxx10011111", InstEmit.Dsb,           typeof(OpCodeSystem64));
-            SetA64("01001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eon,           typeof(OpCodeAluRs64));
-            SetA64("11001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eon,           typeof(OpCodeAluRs64));
-            SetA64("0101001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,           typeof(OpCodeAluImm64));
-            SetA64("110100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,           typeof(OpCodeAluImm64));
-            SetA64("01001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eor,           typeof(OpCodeAluRs64));
-            SetA64("11001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,           typeof(OpCodeAluRs64));
-            SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstEmit.Extr,          typeof(OpCodeAluRs64));
-            SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Extr,          typeof(OpCodeAluRs64));
-            SetA64("11010101000000110010xxxxxxx11111", InstEmit.Hint,          typeof(OpCodeSystem64));
-            SetA64("11010101000000110011xxxx11011111", InstEmit.Isb,           typeof(OpCodeSystem64));
-            SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldar,          typeof(OpCodeMemEx64));
-            SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxp,         typeof(OpCodeMemEx64));
-            SetA64("xx001000010xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxr,         typeof(OpCodeMemEx64));
-            SetA64("<<10100xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp,           typeof(OpCodeMemPair64));
-            SetA64("xx111000010xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeMemImm64));
-            SetA64("xx11100101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeMemImm64));
-            SetA64("xx111000011xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeMemReg64));
-            SetA64("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.LdrLit,        typeof(OpCodeMemLit64));
-            SetA64("0x1110001x0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemImm64));
-            SetA64("0x1110011xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemImm64));
-            SetA64("10111000100xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemImm64));
-            SetA64("1011100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemImm64));
-            SetA64("0x1110001x1xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemReg64));
-            SetA64("10111000101xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs,          typeof(OpCodeMemReg64));
-            SetA64("xx001000010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxr,          typeof(OpCodeMemEx64));
-            SetA64("1x001000011xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxp,          typeof(OpCodeMemEx64));
-            SetA64("x0011010110xxxxx001000xxxxxxxxxx", InstEmit.Lslv,          typeof(OpCodeAluRs64));
-            SetA64("x0011010110xxxxx001001xxxxxxxxxx", InstEmit.Lsrv,          typeof(OpCodeAluRs64));
-            SetA64("x0011011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Madd,          typeof(OpCodeMul64));
-            SetA64("0111001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk,          typeof(OpCodeMov64));
-            SetA64("111100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk,          typeof(OpCodeMov64));
-            SetA64("0001001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn,          typeof(OpCodeMov64));
-            SetA64("100100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn,          typeof(OpCodeMov64));
-            SetA64("0101001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz,          typeof(OpCodeMov64));
-            SetA64("110100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz,          typeof(OpCodeMov64));
-            SetA64("110101010011xxxxxxxxxxxxxxxxxxxx", InstEmit.Mrs,           typeof(OpCodeSystem64));
-            SetA64("110101010001xxxxxxxxxxxxxxxxxxxx", InstEmit.Msr,           typeof(OpCodeSystem64));
-            SetA64("x0011011000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Msub,          typeof(OpCodeMul64));
-            SetA64("11010101000000110010000000011111", InstEmit.Nop,           typeof(OpCodeSystem64));
-            SetA64("00101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orn,           typeof(OpCodeAluRs64));
-            SetA64("10101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orn,           typeof(OpCodeAluRs64));
-            SetA64("0011001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,           typeof(OpCodeAluImm64));
-            SetA64("101100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,           typeof(OpCodeAluImm64));
-            SetA64("00101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orr,           typeof(OpCodeAluRs64));
-            SetA64("10101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,           typeof(OpCodeAluRs64));
-            SetA64("1111100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm,          typeof(OpCodeMemImm64));
-            SetA64("11111000100xxxxxxxxx00xxxxxxxxxx", InstEmit.Pfrm,          typeof(OpCodeMemImm64));
-            SetA64("11011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm,          typeof(OpCodeMemLit64));
-            SetA64("x101101011000000000000xxxxxxxxxx", InstEmit.Rbit,          typeof(OpCodeAlu64));
-            SetA64("1101011001011111000000xxxxx00000", InstEmit.Ret,           typeof(OpCodeBReg64));
-            SetA64("x101101011000000000001xxxxxxxxxx", InstEmit.Rev16,         typeof(OpCodeAlu64));
-            SetA64("x101101011000000000010xxxxxxxxxx", InstEmit.Rev32,         typeof(OpCodeAlu64));
-            SetA64("1101101011000000000011xxxxxxxxxx", InstEmit.Rev64,         typeof(OpCodeAlu64));
-            SetA64("x0011010110xxxxx001011xxxxxxxxxx", InstEmit.Rorv,          typeof(OpCodeAluRs64));
-            SetA64("x1011010000xxxxx000000xxxxxxxxxx", InstEmit.Sbc,           typeof(OpCodeAluRs64));
-            SetA64("x1111010000xxxxx000000xxxxxxxxxx", InstEmit.Sbcs,          typeof(OpCodeAluRs64));
-            SetA64("00010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sbfm,          typeof(OpCodeBfm64));
-            SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sbfm,          typeof(OpCodeBfm64));
-            SetA64("x0011010110xxxxx000011xxxxxxxxxx", InstEmit.Sdiv,          typeof(OpCodeAluRs64));
-            SetA64("10011011001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smaddl,        typeof(OpCodeMul64));
-            SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Smsubl,        typeof(OpCodeMul64));
-            SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smulh,         typeof(OpCodeMul64));
-            SetA64("xx001000100xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlr,          typeof(OpCodeMemEx64));
-            SetA64("1x001000001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxp,         typeof(OpCodeMemEx64));
-            SetA64("xx001000000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxr,         typeof(OpCodeMemEx64));
-            SetA64("x010100xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp,           typeof(OpCodeMemPair64));
-            SetA64("xx111000000xxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,           typeof(OpCodeMemImm64));
-            SetA64("xx11100100xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,           typeof(OpCodeMemImm64));
-            SetA64("xx111000001xxxxxxxxx10xxxxxxxxxx", InstEmit.Str,           typeof(OpCodeMemReg64));
-            SetA64("1x001000001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxp,          typeof(OpCodeMemEx64));
-            SetA64("xx001000000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxr,          typeof(OpCodeMemEx64));
-            SetA64("x10100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub,           typeof(OpCodeAluImm64));
-            SetA64("01001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sub,           typeof(OpCodeAluRs64));
-            SetA64("11001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub,           typeof(OpCodeAluRs64));
-            SetA64("x1001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Sub,           typeof(OpCodeAluRx64));
-            SetA64("x1001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Sub,           typeof(OpCodeAluRx64));
-            SetA64("x11100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs,          typeof(OpCodeAluImm64));
-            SetA64("01101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Subs,          typeof(OpCodeAluRs64));
-            SetA64("11101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs,          typeof(OpCodeAluRs64));
-            SetA64("x1101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Subs,          typeof(OpCodeAluRx64));
-            SetA64("x1101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Subs,          typeof(OpCodeAluRx64));
-            SetA64("11010100000xxxxxxxxxxxxxxxx00001", InstEmit.Svc,           typeof(OpCodeException64));
-            SetA64("1101010100001xxxxxxxxxxxxxxxxxxx", InstEmit.Sys,           typeof(OpCodeSystem64));
-            SetA64("x0110111xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbnz,          typeof(OpCodeBImmTest64));
-            SetA64("x0110110xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbz,           typeof(OpCodeBImmTest64));
-            SetA64("01010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ubfm,          typeof(OpCodeBfm64));
-            SetA64("1101001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ubfm,          typeof(OpCodeBfm64));
-            SetA64("x0011010110xxxxx000010xxxxxxxxxx", InstEmit.Udiv,          typeof(OpCodeAluRs64));
-            SetA64("10011011101xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umaddl,        typeof(OpCodeMul64));
-            SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstEmit.Umsubl,        typeof(OpCodeMul64));
-            SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umulh,         typeof(OpCodeMul64));
+            SetA64("x0011010000xxxxx000000xxxxxxxxxx", InstEmit.Adc,             typeof(OpCodeAluRs64));
+            SetA64("x0111010000xxxxx000000xxxxxxxxxx", InstEmit.Adcs,            typeof(OpCodeAluRs64));
+            SetA64("x00100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Add,             typeof(OpCodeAluImm64));
+            SetA64("00001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Add,             typeof(OpCodeAluRs64));
+            SetA64("10001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Add,             typeof(OpCodeAluRs64));
+            SetA64("x0001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Add,             typeof(OpCodeAluRx64));
+            SetA64("x0001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Add,             typeof(OpCodeAluRx64));
+            SetA64("x01100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds,            typeof(OpCodeAluImm64));
+            SetA64("00101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Adds,            typeof(OpCodeAluRs64));
+            SetA64("10101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Adds,            typeof(OpCodeAluRs64));
+            SetA64("x0101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Adds,            typeof(OpCodeAluRx64));
+            SetA64("x0101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Adds,            typeof(OpCodeAluRx64));
+            SetA64("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adr,             typeof(OpCodeAdr64));
+            SetA64("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Adrp,            typeof(OpCodeAdr64));
+            SetA64("0001001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.And,             typeof(OpCodeAluImm64));
+            SetA64("100100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.And,             typeof(OpCodeAluImm64));
+            SetA64("00001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.And,             typeof(OpCodeAluRs64));
+            SetA64("10001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.And,             typeof(OpCodeAluRs64));
+            SetA64("0111001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,            typeof(OpCodeAluImm64));
+            SetA64("111100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,            typeof(OpCodeAluImm64));
+            SetA64("01101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ands,            typeof(OpCodeAluRs64));
+            SetA64("11101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ands,            typeof(OpCodeAluRs64));
+            SetA64("x0011010110xxxxx001010xxxxxxxxxx", InstEmit.Asrv,            typeof(OpCodeAluRs64));
+            SetA64("000101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.B,               typeof(OpCodeBImmAl64));
+            SetA64("01010100xxxxxxxxxxxxxxxxxxx0xxxx", InstEmit.B_Cond,          typeof(OpCodeBImmCond64));
+            SetA64("00110011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bfm,             typeof(OpCodeBfm64));
+            SetA64("1011001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bfm,             typeof(OpCodeBfm64));
+            SetA64("00001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bic,             typeof(OpCodeAluRs64));
+            SetA64("10001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bic,             typeof(OpCodeAluRs64));
+            SetA64("01101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Bics,            typeof(OpCodeAluRs64));
+            SetA64("11101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Bics,            typeof(OpCodeAluRs64));
+            SetA64("100101xxxxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Bl,              typeof(OpCodeBImmAl64));
+            SetA64("1101011000111111000000xxxxx00000", InstEmit.Blr,             typeof(OpCodeBReg64));
+            SetA64("1101011000011111000000xxxxx00000", InstEmit.Br,              typeof(OpCodeBReg64));
+            SetA64("11010100001xxxxxxxxxxxxxxxx00000", InstEmit.Brk,             typeof(OpCodeException64));
+            SetA64("x0110101xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbnz,            typeof(OpCodeBImmCmp64));
+            SetA64("x0110100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Cbz,             typeof(OpCodeBImmCmp64));
+            SetA64("x0111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmn,            typeof(OpCodeCcmpImm64));
+            SetA64("x0111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmn,            typeof(OpCodeCcmpReg64));
+            SetA64("x1111010010xxxxxxxxx10xxxxx0xxxx", InstEmit.Ccmp,            typeof(OpCodeCcmpImm64));
+            SetA64("x1111010010xxxxxxxxx00xxxxx0xxxx", InstEmit.Ccmp,            typeof(OpCodeCcmpReg64));
+            SetA64("11010101000000110011xxxx01011111", InstEmit.Clrex,           typeof(OpCodeSystem64));
+            SetA64("x101101011000000000101xxxxxxxxxx", InstEmit.Cls,             typeof(OpCodeAlu64));
+            SetA64("x101101011000000000100xxxxxxxxxx", InstEmit.Clz,             typeof(OpCodeAlu64));
+            SetA64("00011010110xxxxx010000xxxxxxxxxx", InstEmit.Crc32b,          typeof(OpCodeAluRs64));
+            SetA64("00011010110xxxxx010001xxxxxxxxxx", InstEmit.Crc32h,          typeof(OpCodeAluRs64));
+            SetA64("00011010110xxxxx010010xxxxxxxxxx", InstEmit.Crc32w,          typeof(OpCodeAluRs64));
+            SetA64("10011010110xxxxx010011xxxxxxxxxx", InstEmit.Crc32x,          typeof(OpCodeAluRs64));
+            SetA64("00011010110xxxxx010100xxxxxxxxxx", InstEmit.Crc32cb,         typeof(OpCodeAluRs64));
+            SetA64("00011010110xxxxx010101xxxxxxxxxx", InstEmit.Crc32ch,         typeof(OpCodeAluRs64));
+            SetA64("00011010110xxxxx010110xxxxxxxxxx", InstEmit.Crc32cw,         typeof(OpCodeAluRs64));
+            SetA64("10011010110xxxxx010111xxxxxxxxxx", InstEmit.Crc32cx,         typeof(OpCodeAluRs64));
+            SetA64("x0011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csel,            typeof(OpCodeCsel64));
+            SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csinc,           typeof(OpCodeCsel64));
+            SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", InstEmit.Csinv,           typeof(OpCodeCsel64));
+            SetA64("x1011010100xxxxxxxxx01xxxxxxxxxx", InstEmit.Csneg,           typeof(OpCodeCsel64));
+            SetA64("11010101000000110011xxxx10111111", InstEmit.Dmb,             typeof(OpCodeSystem64));
+            SetA64("11010101000000110011xxxx10011111", InstEmit.Dsb,             typeof(OpCodeSystem64));
+            SetA64("01001010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eon,             typeof(OpCodeAluRs64));
+            SetA64("11001010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eon,             typeof(OpCodeAluRs64));
+            SetA64("0101001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,             typeof(OpCodeAluImm64));
+            SetA64("110100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,             typeof(OpCodeAluImm64));
+            SetA64("01001010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Eor,             typeof(OpCodeAluRs64));
+            SetA64("11001010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Eor,             typeof(OpCodeAluRs64));
+            SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstEmit.Extr,            typeof(OpCodeAluRs64));
+            SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Extr,            typeof(OpCodeAluRs64));
+            SetA64("11010101000000110010xxxxxxx11111", InstEmit.Hint,            typeof(OpCodeSystem64));
+            SetA64("11010101000000110011xxxx11011111", InstEmit.Isb,             typeof(OpCodeSystem64));
+            SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldar,            typeof(OpCodeMemEx64));
+            SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxp,           typeof(OpCodeMemEx64));
+            SetA64("xx001000010xxxxx1xxxxxxxxxxxxxxx", InstEmit.Ldaxr,           typeof(OpCodeMemEx64));
+            SetA64("<<10100xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp,             typeof(OpCodeMemPair64));
+            SetA64("xx111000010xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeMemImm64));
+            SetA64("xx11100101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeMemImm64));
+            SetA64("xx111000011xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeMemReg64));
+            SetA64("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr_Literal,     typeof(OpCodeMemLit64));
+            SetA64("0x1110001x0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemImm64));
+            SetA64("0x1110011xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemImm64));
+            SetA64("10111000100xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemImm64));
+            SetA64("1011100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemImm64));
+            SetA64("0x1110001x1xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemReg64));
+            SetA64("10111000101xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldrs,            typeof(OpCodeMemReg64));
+            SetA64("xx001000010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxr,            typeof(OpCodeMemEx64));
+            SetA64("1x001000011xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ldxp,            typeof(OpCodeMemEx64));
+            SetA64("x0011010110xxxxx001000xxxxxxxxxx", InstEmit.Lslv,            typeof(OpCodeAluRs64));
+            SetA64("x0011010110xxxxx001001xxxxxxxxxx", InstEmit.Lsrv,            typeof(OpCodeAluRs64));
+            SetA64("x0011011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Madd,            typeof(OpCodeMul64));
+            SetA64("0111001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk,            typeof(OpCodeMov64));
+            SetA64("111100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movk,            typeof(OpCodeMov64));
+            SetA64("0001001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn,            typeof(OpCodeMov64));
+            SetA64("100100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movn,            typeof(OpCodeMov64));
+            SetA64("0101001010xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz,            typeof(OpCodeMov64));
+            SetA64("110100101xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Movz,            typeof(OpCodeMov64));
+            SetA64("110101010011xxxxxxxxxxxxxxxxxxxx", InstEmit.Mrs,             typeof(OpCodeSystem64));
+            SetA64("110101010001xxxxxxxxxxxxxxxxxxxx", InstEmit.Msr,             typeof(OpCodeSystem64));
+            SetA64("x0011011000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Msub,            typeof(OpCodeMul64));
+            SetA64("11010101000000110010000000011111", InstEmit.Nop,             typeof(OpCodeSystem64));
+            SetA64("00101010xx1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orn,             typeof(OpCodeAluRs64));
+            SetA64("10101010xx1xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orn,             typeof(OpCodeAluRs64));
+            SetA64("0011001000xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,             typeof(OpCodeAluImm64));
+            SetA64("101100100xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,             typeof(OpCodeAluImm64));
+            SetA64("00101010xx0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Orr,             typeof(OpCodeAluRs64));
+            SetA64("10101010xx0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Orr,             typeof(OpCodeAluRs64));
+            SetA64("1111100110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm,            typeof(OpCodeMemImm64));
+            SetA64("11111000100xxxxxxxxx00xxxxxxxxxx", InstEmit.Pfrm,            typeof(OpCodeMemImm64));
+            SetA64("11011000xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Pfrm,            typeof(OpCodeMemLit64));
+            SetA64("x101101011000000000000xxxxxxxxxx", InstEmit.Rbit,            typeof(OpCodeAlu64));
+            SetA64("1101011001011111000000xxxxx00000", InstEmit.Ret,             typeof(OpCodeBReg64));
+            SetA64("x101101011000000000001xxxxxxxxxx", InstEmit.Rev16,           typeof(OpCodeAlu64));
+            SetA64("x101101011000000000010xxxxxxxxxx", InstEmit.Rev32,           typeof(OpCodeAlu64));
+            SetA64("1101101011000000000011xxxxxxxxxx", InstEmit.Rev64,           typeof(OpCodeAlu64));
+            SetA64("x0011010110xxxxx001011xxxxxxxxxx", InstEmit.Rorv,            typeof(OpCodeAluRs64));
+            SetA64("x1011010000xxxxx000000xxxxxxxxxx", InstEmit.Sbc,             typeof(OpCodeAluRs64));
+            SetA64("x1111010000xxxxx000000xxxxxxxxxx", InstEmit.Sbcs,            typeof(OpCodeAluRs64));
+            SetA64("00010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sbfm,            typeof(OpCodeBfm64));
+            SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sbfm,            typeof(OpCodeBfm64));
+            SetA64("x0011010110xxxxx000011xxxxxxxxxx", InstEmit.Sdiv,            typeof(OpCodeAluRs64));
+            SetA64("10011011001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smaddl,          typeof(OpCodeMul64));
+            SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Smsubl,          typeof(OpCodeMul64));
+            SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", InstEmit.Smulh,           typeof(OpCodeMul64));
+            SetA64("xx001000100xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlr,            typeof(OpCodeMemEx64));
+            SetA64("1x001000001xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxp,           typeof(OpCodeMemEx64));
+            SetA64("xx001000000xxxxx1xxxxxxxxxxxxxxx", InstEmit.Stlxr,           typeof(OpCodeMemEx64));
+            SetA64("x010100xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp,             typeof(OpCodeMemPair64));
+            SetA64("xx111000000xxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,             typeof(OpCodeMemImm64));
+            SetA64("xx11100100xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,             typeof(OpCodeMemImm64));
+            SetA64("xx111000001xxxxxxxxx10xxxxxxxxxx", InstEmit.Str,             typeof(OpCodeMemReg64));
+            SetA64("1x001000001xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxp,            typeof(OpCodeMemEx64));
+            SetA64("xx001000000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Stxr,            typeof(OpCodeMemEx64));
+            SetA64("x10100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub,             typeof(OpCodeAluImm64));
+            SetA64("01001011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Sub,             typeof(OpCodeAluRs64));
+            SetA64("11001011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Sub,             typeof(OpCodeAluRs64));
+            SetA64("x1001011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Sub,             typeof(OpCodeAluRx64));
+            SetA64("x1001011001xxxxxxxx100xxxxxxxxxx", InstEmit.Sub,             typeof(OpCodeAluRx64));
+            SetA64("x11100010xxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs,            typeof(OpCodeAluImm64));
+            SetA64("01101011<<0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Subs,            typeof(OpCodeAluRs64));
+            SetA64("11101011<<0xxxxxxxxxxxxxxxxxxxxx", InstEmit.Subs,            typeof(OpCodeAluRs64));
+            SetA64("x1101011001xxxxxxxx0xxxxxxxxxxxx", InstEmit.Subs,            typeof(OpCodeAluRx64));
+            SetA64("x1101011001xxxxxxxx100xxxxxxxxxx", InstEmit.Subs,            typeof(OpCodeAluRx64));
+            SetA64("11010100000xxxxxxxxxxxxxxxx00001", InstEmit.Svc,             typeof(OpCodeException64));
+            SetA64("1101010100001xxxxxxxxxxxxxxxxxxx", InstEmit.Sys,             typeof(OpCodeSystem64));
+            SetA64("x0110111xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbnz,            typeof(OpCodeBImmTest64));
+            SetA64("x0110110xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Tbz,             typeof(OpCodeBImmTest64));
+            SetA64("01010011000xxxxx0xxxxxxxxxxxxxxx", InstEmit.Ubfm,            typeof(OpCodeBfm64));
+            SetA64("1101001101xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ubfm,            typeof(OpCodeBfm64));
+            SetA64("x0011010110xxxxx000010xxxxxxxxxx", InstEmit.Udiv,            typeof(OpCodeAluRs64));
+            SetA64("10011011101xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umaddl,          typeof(OpCodeMul64));
+            SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstEmit.Umsubl,          typeof(OpCodeMul64));
+            SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstEmit.Umulh,           typeof(OpCodeMul64));
 
             //Vector
-            SetA64("0101111011100000101110xxxxxxxxxx", InstEmit.Abs_S,         typeof(OpCodeSimd64));
-            SetA64("0>001110<<100000101110xxxxxxxxxx", InstEmit.Abs_V,         typeof(OpCodeSimd64));
-            SetA64("01011110111xxxxx100001xxxxxxxxxx", InstEmit.Add_S,         typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", InstEmit.Add_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", InstEmit.Addhn_V,       typeof(OpCodeSimdReg64));
-            SetA64("0101111011110001101110xxxxxxxxxx", InstEmit.Addp_S,        typeof(OpCodeSimd64));
-            SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", InstEmit.Addp_V,        typeof(OpCodeSimdReg64));
-            SetA64("000011100x110001101110xxxxxxxxxx", InstEmit.Addv_V,        typeof(OpCodeSimd64));
-            SetA64("01001110<<110001101110xxxxxxxxxx", InstEmit.Addv_V,        typeof(OpCodeSimd64));
-            SetA64("0100111000101000010110xxxxxxxxxx", InstEmit.Aesd_V,        typeof(OpCodeSimd64));
-            SetA64("0100111000101000010010xxxxxxxxxx", InstEmit.Aese_V,        typeof(OpCodeSimd64));
-            SetA64("0100111000101000011110xxxxxxxxxx", InstEmit.Aesimc_V,      typeof(OpCodeSimd64));
-            SetA64("0100111000101000011010xxxxxxxxxx", InstEmit.Aesmc_V,       typeof(OpCodeSimd64));
-            SetA64("0x001110001xxxxx000111xxxxxxxxxx", InstEmit.And_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001110011xxxxx000111xxxxxxxxxx", InstEmit.Bic_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x10111100000xxx<<x101xxxxxxxxxx", InstEmit.Bic_Vi,        typeof(OpCodeSimdImm64));
-            SetA64("0x101110111xxxxx000111xxxxxxxxxx", InstEmit.Bif_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x101110101xxxxx000111xxxxxxxxxx", InstEmit.Bit_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x101110011xxxxx000111xxxxxxxxxx", InstEmit.Bsl_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<100000010010xxxxxxxxxx", InstEmit.Cls_V,         typeof(OpCodeSimd64));
-            SetA64("0x101110<<100000010010xxxxxxxxxx", InstEmit.Clz_V,         typeof(OpCodeSimd64));
-            SetA64("01111110111xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_S,        typeof(OpCodeSimdReg64));
-            SetA64("0101111011100000100110xxxxxxxxxx", InstEmit.Cmeq_S,        typeof(OpCodeSimd64));
-            SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<100000100110xxxxxxxxxx", InstEmit.Cmeq_V,        typeof(OpCodeSimd64));
-            SetA64("01011110111xxxxx001111xxxxxxxxxx", InstEmit.Cmge_S,        typeof(OpCodeSimdReg64));
-            SetA64("0111111011100000100010xxxxxxxxxx", InstEmit.Cmge_S,        typeof(OpCodeSimd64));
-            SetA64("0>001110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmge_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<100000100010xxxxxxxxxx", InstEmit.Cmge_V,        typeof(OpCodeSimd64));
-            SetA64("01011110111xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_S,        typeof(OpCodeSimdReg64));
-            SetA64("0101111011100000100010xxxxxxxxxx", InstEmit.Cmgt_S,        typeof(OpCodeSimd64));
-            SetA64("0>001110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<100000100010xxxxxxxxxx", InstEmit.Cmgt_V,        typeof(OpCodeSimd64));
-            SetA64("01111110111xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_V,        typeof(OpCodeSimdReg64));
-            SetA64("01111110111xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_V,        typeof(OpCodeSimdReg64));
-            SetA64("0111111011100000100110xxxxxxxxxx", InstEmit.Cmle_S,        typeof(OpCodeSimd64));
-            SetA64("0>101110<<100000100110xxxxxxxxxx", InstEmit.Cmle_V,        typeof(OpCodeSimd64));
-            SetA64("0101111011100000101010xxxxxxxxxx", InstEmit.Cmlt_S,        typeof(OpCodeSimd64));
-            SetA64("0>001110<<100000101010xxxxxxxxxx", InstEmit.Cmlt_V,        typeof(OpCodeSimd64));
-            SetA64("01011110111xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_S,       typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x00111000100000010110xxxxxxxxxx", InstEmit.Cnt_V,         typeof(OpCodeSimd64));
-            SetA64("0>001110000x<>>>000011xxxxxxxxxx", InstEmit.Dup_Gp,        typeof(OpCodeSimdIns64));
-            SetA64("01011110000xxxxx000001xxxxxxxxxx", InstEmit.Dup_S,         typeof(OpCodeSimdIns64));
-            SetA64("0>001110000x<>>>000001xxxxxxxxxx", InstEmit.Dup_V,         typeof(OpCodeSimdIns64));
-            SetA64("0x101110001xxxxx000111xxxxxxxxxx", InstEmit.Eor_V,         typeof(OpCodeSimdReg64));
-            SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", InstEmit.Ext_V,         typeof(OpCodeSimdExt64));
-            SetA64("011111101x1xxxxx110101xxxxxxxxxx", InstEmit.Fabd_S,        typeof(OpCodeSimdReg64));
-            SetA64("000111100x100000110000xxxxxxxxxx", InstEmit.Fabs_S,        typeof(OpCodeSimd64));
-            SetA64("0>0011101<100000111110xxxxxxxxxx", InstEmit.Fabs_V,        typeof(OpCodeSimd64));
-            SetA64("000111100x1xxxxx001010xxxxxxxxxx", InstEmit.Fadd_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", InstEmit.Fadd_V,        typeof(OpCodeSimdReg64));
-            SetA64("011111100x110000110110xxxxxxxxxx", InstEmit.Faddp_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", InstEmit.Faddp_V,       typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxxxxxx01xxxxx0xxxx", InstEmit.Fccmp_S,       typeof(OpCodeSimdFcond64));
-            SetA64("000111100x1xxxxxxxxx01xxxxx1xxxx", InstEmit.Fccmpe_S,      typeof(OpCodeSimdFcond64));
-            SetA64("010111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_S,       typeof(OpCodeSimdReg64));
-            SetA64("010111101x100000110110xxxxxxxxxx", InstEmit.Fcmeq_S,       typeof(OpCodeSimd64));
-            SetA64("0>0011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<100000110110xxxxxxxxxx", InstEmit.Fcmeq_V,       typeof(OpCodeSimd64));
-            SetA64("011111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_S,       typeof(OpCodeSimdReg64));
-            SetA64("011111101x100000110010xxxxxxxxxx", InstEmit.Fcmge_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>1011101<100000110010xxxxxxxxxx", InstEmit.Fcmge_V,       typeof(OpCodeSimd64));
-            SetA64("011111101x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_S,       typeof(OpCodeSimdReg64));
-            SetA64("010111101x100000110010xxxxxxxxxx", InstEmit.Fcmgt_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011101<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<100000110010xxxxxxxxxx", InstEmit.Fcmgt_V,       typeof(OpCodeSimd64));
-            SetA64("011111101x100000110110xxxxxxxxxx", InstEmit.Fcmle_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011101<100000110110xxxxxxxxxx", InstEmit.Fcmle_V,       typeof(OpCodeSimd64));
-            SetA64("010111101x100000111010xxxxxxxxxx", InstEmit.Fcmlt_S,       typeof(OpCodeSimd64));
-            SetA64("0>0011101<100000111010xxxxxxxxxx", InstEmit.Fcmlt_V,       typeof(OpCodeSimd64));
-            SetA64("000111100x1xxxxx001000xxxxx0x000", InstEmit.Fcmp_S,        typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx001000xxxxx1x000", InstEmit.Fcmpe_S,       typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", InstEmit.Fcsel_S,       typeof(OpCodeSimdFcond64));
-            SetA64("000111100x10001xx10000xxxxxxxxxx", InstEmit.Fcvt_S,        typeof(OpCodeSimd64));
-            SetA64("x00111100x100100000000xxxxxxxxxx", InstEmit.Fcvtas_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x100101000000xxxxxxxxxx", InstEmit.Fcvtau_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("0x0011100x100001011110xxxxxxxxxx", InstEmit.Fcvtl_V,       typeof(OpCodeSimd64));
-            SetA64("x00111100x110000000000xxxxxxxxxx", InstEmit.Fcvtms_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x110001000000xxxxxxxxxx", InstEmit.Fcvtmu_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("0x0011100x100001011010xxxxxxxxxx", InstEmit.Fcvtn_V,       typeof(OpCodeSimd64));
-            SetA64("010111100x100001101010xxxxxxxxxx", InstEmit.Fcvtns_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011100<100001101010xxxxxxxxxx", InstEmit.Fcvtns_V,      typeof(OpCodeSimd64));
-            SetA64("011111100x100001101010xxxxxxxxxx", InstEmit.Fcvtnu_S,      typeof(OpCodeSimd64));
-            SetA64("0>1011100<100001101010xxxxxxxxxx", InstEmit.Fcvtnu_V,      typeof(OpCodeSimd64));
-            SetA64("x00111100x101000000000xxxxxxxxxx", InstEmit.Fcvtps_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x101001000000xxxxxxxxxx", InstEmit.Fcvtpu_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x111000000000xxxxxxxxxx", InstEmit.Fcvtzs_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x011000xxxxxxxxxxxxxxxx", InstEmit.Fcvtzs_Gp_Fix, typeof(OpCodeSimdCvt64));
-            SetA64("010111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzs_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzs_V,      typeof(OpCodeSimd64));
-            SetA64("0x0011110>>xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzs_V,      typeof(OpCodeSimdShImm64));
-            SetA64("x00111100x111001000000xxxxxxxxxx", InstEmit.Fcvtzu_Gp,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x011001xxxxxxxxxxxxxxxx", InstEmit.Fcvtzu_Gp_Fix, typeof(OpCodeSimdCvt64));
-            SetA64("011111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzu_S,      typeof(OpCodeSimd64));
-            SetA64("0>1011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzu_V,      typeof(OpCodeSimd64));
-            SetA64("0x1011110>>xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzu_V,      typeof(OpCodeSimdShImm64));
-            SetA64("000111100x1xxxxx000110xxxxxxxxxx", InstEmit.Fdiv_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", InstEmit.Fdiv_V,        typeof(OpCodeSimdReg64));
-            SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fmadd_S,       typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx010010xxxxxxxxxx", InstEmit.Fmax_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmax_V,        typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx011010xxxxxxxxxx", InstEmit.Fmaxnm_S,      typeof(OpCodeSimdReg64));
-            SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", InstEmit.Fmaxnm_V,      typeof(OpCodeSimdReg64));
-            SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmaxp_V,       typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstEmit.Fmin_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fmin_V,        typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx011110xxxxxxxxxx", InstEmit.Fminnm_S,      typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", InstEmit.Fminnm_V,      typeof(OpCodeSimdReg64));
-            SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fminp_V,       typeof(OpCodeSimdReg64));
-            SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Se,       typeof(OpCodeSimdRegElemF64));
-            SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", InstEmit.Fmla_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Ve,       typeof(OpCodeSimdRegElemF64));
-            SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Se,       typeof(OpCodeSimdRegElemF64));
-            SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", InstEmit.Fmls_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Ve,       typeof(OpCodeSimdRegElemF64));
-            SetA64("000111100x100000010000xxxxxxxxxx", InstEmit.Fmov_S,        typeof(OpCodeSimd64));
-            SetA64("00011110xx1xxxxxxxx100xxxxxxxxxx", InstEmit.Fmov_Si,       typeof(OpCodeSimdFmov64));
-            SetA64("0xx0111100000xxx111101xxxxxxxxxx", InstEmit.Fmov_V,        typeof(OpCodeSimdImm64));
-            SetA64("x00111100x100110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi,     typeof(OpCodeSimdCvt64));
-            SetA64("x00111100x100111000000xxxxxxxxxx", InstEmit.Fmov_Itof,     typeof(OpCodeSimdCvt64));
-            SetA64("1001111010101110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi1,    typeof(OpCodeSimdCvt64));
-            SetA64("1001111010101111000000xxxxxxxxxx", InstEmit.Fmov_Itof1,    typeof(OpCodeSimdCvt64));
-            SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fmsub_S,       typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx000010xxxxxxxxxx", InstEmit.Fmul_S,        typeof(OpCodeSimdReg64));
-            SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Se,       typeof(OpCodeSimdRegElemF64));
-            SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmul_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Ve,       typeof(OpCodeSimdRegElemF64));
-            SetA64("010111100x1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_S,       typeof(OpCodeSimdReg64));
-            SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Se,      typeof(OpCodeSimdRegElemF64));
-            SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Ve,      typeof(OpCodeSimdRegElemF64));
-            SetA64("000111100x100001010000xxxxxxxxxx", InstEmit.Fneg_S,        typeof(OpCodeSimd64));
-            SetA64("0>1011101<100000111110xxxxxxxxxx", InstEmit.Fneg_V,        typeof(OpCodeSimd64));
-            SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fnmadd_S,      typeof(OpCodeSimdReg64));
-            SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fnmsub_S,      typeof(OpCodeSimdReg64));
-            SetA64("000111100x1xxxxx100010xxxxxxxxxx", InstEmit.Fnmul_S,       typeof(OpCodeSimdReg64));
-            SetA64("010111101x100001110110xxxxxxxxxx", InstEmit.Frecpe_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011101<100001110110xxxxxxxxxx", InstEmit.Frecpe_V,      typeof(OpCodeSimd64));
-            SetA64("010111100x1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_S,      typeof(OpCodeSimdReg64));
-            SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_V,      typeof(OpCodeSimdReg64));
-            SetA64("010111101x100001111110xxxxxxxxxx", InstEmit.Frecpx_S,      typeof(OpCodeSimd64));
-            SetA64("000111100x100110010000xxxxxxxxxx", InstEmit.Frinta_S,      typeof(OpCodeSimd64));
-            SetA64("0>1011100<100001100010xxxxxxxxxx", InstEmit.Frinta_V,      typeof(OpCodeSimd64));
-            SetA64("000111100x100111110000xxxxxxxxxx", InstEmit.Frinti_S,      typeof(OpCodeSimd64));
-            SetA64("0>1011101<100001100110xxxxxxxxxx", InstEmit.Frinti_V,      typeof(OpCodeSimd64));
-            SetA64("000111100x100101010000xxxxxxxxxx", InstEmit.Frintm_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011100<100001100110xxxxxxxxxx", InstEmit.Frintm_V,      typeof(OpCodeSimd64));
-            SetA64("000111100x100100010000xxxxxxxxxx", InstEmit.Frintn_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011100<100001100010xxxxxxxxxx", InstEmit.Frintn_V,      typeof(OpCodeSimd64));
-            SetA64("000111100x100100110000xxxxxxxxxx", InstEmit.Frintp_S,      typeof(OpCodeSimd64));
-            SetA64("0>0011101<100001100010xxxxxxxxxx", InstEmit.Frintp_V,      typeof(OpCodeSimd64));
-            SetA64("000111100x100111010000xxxxxxxxxx", InstEmit.Frintx_S,      typeof(OpCodeSimd64));
-            SetA64("0>1011100<100001100110xxxxxxxxxx", InstEmit.Frintx_V,      typeof(OpCodeSimd64));
-            SetA64("011111101x100001110110xxxxxxxxxx", InstEmit.Frsqrte_S,     typeof(OpCodeSimd64));
-            SetA64("0>1011101<100001110110xxxxxxxxxx", InstEmit.Frsqrte_V,     typeof(OpCodeSimd64));
-            SetA64("010111101x1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_S,     typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_V,     typeof(OpCodeSimdReg64));
-            SetA64("000111100x100001110000xxxxxxxxxx", InstEmit.Fsqrt_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011101<100001111110xxxxxxxxxx", InstEmit.Fsqrt_V,       typeof(OpCodeSimd64));
-            SetA64("000111100x1xxxxx001110xxxxxxxxxx", InstEmit.Fsub_S,        typeof(OpCodeSimdReg64));
-            SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", InstEmit.Fsub_V,        typeof(OpCodeSimdReg64));
-            SetA64("01001110000xxxxx000111xxxxxxxxxx", InstEmit.Ins_Gp,        typeof(OpCodeSimdIns64));
-            SetA64("01101110000xxxxx0xxxx1xxxxxxxxxx", InstEmit.Ins_V,         typeof(OpCodeSimdIns64));
-            SetA64("0x00110001000000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vms,       typeof(OpCodeSimdMemMs64));
-            SetA64("0x001100110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vms,       typeof(OpCodeSimdMemMs64));
-            SetA64("0x00110101x00000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vss,       typeof(OpCodeSimdMemSs64));
-            SetA64("0x00110111xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vss,       typeof(OpCodeSimdMemSs64));
-            SetA64("xx10110xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp,           typeof(OpCodeSimdMemPair64));
-            SetA64("xx111100x10xxxxxxxxx00xxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x10xxxxxxxxx01xxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x10xxxxxxxxx11xxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x11xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr,           typeof(OpCodeSimdMemReg64));
-            SetA64("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.LdrLit,        typeof(OpCodeSimdMemLit64));
-            SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mla_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", InstEmit.Mla_Ve,        typeof(OpCodeSimdRegElem64));
-            SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mls_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", InstEmit.Mls_Ve,        typeof(OpCodeSimdRegElem64));
-            SetA64("0x00111100000xxx0xx001xxxxxxxxxx", InstEmit.Movi_V,        typeof(OpCodeSimdImm64));
-            SetA64("0x00111100000xxx10x001xxxxxxxxxx", InstEmit.Movi_V,        typeof(OpCodeSimdImm64));
-            SetA64("0x00111100000xxx110x01xxxxxxxxxx", InstEmit.Movi_V,        typeof(OpCodeSimdImm64));
-            SetA64("0xx0111100000xxx111001xxxxxxxxxx", InstEmit.Movi_V,        typeof(OpCodeSimdImm64));
-            SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", InstEmit.Mul_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", InstEmit.Mul_Ve,        typeof(OpCodeSimdRegElem64));
-            SetA64("0x10111100000xxx0xx001xxxxxxxxxx", InstEmit.Mvni_V,        typeof(OpCodeSimdImm64));
-            SetA64("0x10111100000xxx10x001xxxxxxxxxx", InstEmit.Mvni_V,        typeof(OpCodeSimdImm64));
-            SetA64("0x10111100000xxx110x01xxxxxxxxxx", InstEmit.Mvni_V,        typeof(OpCodeSimdImm64));
-            SetA64("0111111011100000101110xxxxxxxxxx", InstEmit.Neg_S,         typeof(OpCodeSimd64));
-            SetA64("0>101110<<100000101110xxxxxxxxxx", InstEmit.Neg_V,         typeof(OpCodeSimd64));
-            SetA64("0x10111000100000010110xxxxxxxxxx", InstEmit.Not_V,         typeof(OpCodeSimd64));
-            SetA64("0x001110111xxxxx000111xxxxxxxxxx", InstEmit.Orn_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001110101xxxxx000111xxxxxxxxxx", InstEmit.Orr_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x00111100000xxx<<x101xxxxxxxxxx", InstEmit.Orr_Vi,        typeof(OpCodeSimdImm64));
-            SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", InstEmit.Raddhn_V,      typeof(OpCodeSimdReg64));
-            SetA64("0x10111001100000010110xxxxxxxxxx", InstEmit.Rbit_V,        typeof(OpCodeSimd64));
-            SetA64("0x00111000100000000110xxxxxxxxxx", InstEmit.Rev16_V,       typeof(OpCodeSimd64));
-            SetA64("0x1011100x100000000010xxxxxxxxxx", InstEmit.Rev32_V,       typeof(OpCodeSimd64));
-            SetA64("0x001110<<100000000010xxxxxxxxxx", InstEmit.Rev64_V,       typeof(OpCodeSimd64));
-            SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstEmit.Rshrn_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstEmit.Rsubhn_V,      typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstEmit.Saba_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstEmit.Sabal_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", InstEmit.Sabd_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", InstEmit.Sabdl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<100000011010xxxxxxxxxx", InstEmit.Sadalp_V,      typeof(OpCodeSimd64));
-            SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", InstEmit.Saddl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<100000001010xxxxxxxxxx", InstEmit.Saddlp_V,      typeof(OpCodeSimd64));
-            SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", InstEmit.Saddw_V,       typeof(OpCodeSimdReg64));
-            SetA64("x00111100x100010000000xxxxxxxxxx", InstEmit.Scvtf_Gp,      typeof(OpCodeSimdCvt64));
-            SetA64("010111100x100001110110xxxxxxxxxx", InstEmit.Scvtf_S,       typeof(OpCodeSimd64));
-            SetA64("0>0011100<100001110110xxxxxxxxxx", InstEmit.Scvtf_V,       typeof(OpCodeSimd64));
-            SetA64("01011110000xxxxx000000xxxxxxxxxx", InstEmit.Sha1c_V,       typeof(OpCodeSimdReg64));
-            SetA64("0101111000101000000010xxxxxxxxxx", InstEmit.Sha1h_V,       typeof(OpCodeSimd64));
-            SetA64("01011110000xxxxx001000xxxxxxxxxx", InstEmit.Sha1m_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110000xxxxx000100xxxxxxxxxx", InstEmit.Sha1p_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110000xxxxx001100xxxxxxxxxx", InstEmit.Sha1su0_V,     typeof(OpCodeSimdReg64));
-            SetA64("0101111000101000000110xxxxxxxxxx", InstEmit.Sha1su1_V,     typeof(OpCodeSimd64));
-            SetA64("01011110000xxxxx010000xxxxxxxxxx", InstEmit.Sha256h_V,     typeof(OpCodeSimdReg64));
-            SetA64("01011110000xxxxx010100xxxxxxxxxx", InstEmit.Sha256h2_V,    typeof(OpCodeSimdReg64));
-            SetA64("0101111000101000001010xxxxxxxxxx", InstEmit.Sha256su0_V,   typeof(OpCodeSimd64));
-            SetA64("01011110000xxxxx011000xxxxxxxxxx", InstEmit.Sha256su1_V,   typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstEmit.Shadd_V,       typeof(OpCodeSimdReg64));
-            SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_S,         typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstEmit.Shl_V,         typeof(OpCodeSimdShImm64));
-            SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_V,         typeof(OpCodeSimdShImm64));
-            SetA64("0x101110<<100001001110xxxxxxxxxx", InstEmit.Shll_V,        typeof(OpCodeSimd64));
-            SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstEmit.Shrn_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstEmit.Shsub_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstEmit.Sli_V,         typeof(OpCodeSimdShImm64));
-            SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstEmit.Smax_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstEmit.Smaxp_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstEmit.Smin_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstEmit.Sminp_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstEmit.Smlal_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstEmit.Smlsl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110000xxxxx001011xxxxxxxxxx", InstEmit.Smov_S,        typeof(OpCodeSimdIns64));
-            SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", InstEmit.Smull_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110xx100000011110xxxxxxxxxx", InstEmit.Sqabs_S,       typeof(OpCodeSimd64));
-            SetA64("0>001110<<100000011110xxxxxxxxxx", InstEmit.Sqabs_V,       typeof(OpCodeSimd64));
-            SetA64("01011110xx1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_S,       typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S,     typeof(OpCodeSimdReg64));
-            SetA64("01011110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S,     typeof(OpCodeSimdReg64));
-            SetA64("0x001110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V,     typeof(OpCodeSimdReg64));
-            SetA64("0x001110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V,     typeof(OpCodeSimdReg64));
-            SetA64("01111110xx100000011110xxxxxxxxxx", InstEmit.Sqneg_S,       typeof(OpCodeSimd64));
-            SetA64("0>101110<<100000011110xxxxxxxxxx", InstEmit.Sqneg_V,       typeof(OpCodeSimd64));
-            SetA64("01111110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S,    typeof(OpCodeSimdReg64));
-            SetA64("01111110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S,    typeof(OpCodeSimdReg64));
-            SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V,    typeof(OpCodeSimdReg64));
-            SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V,    typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstEmit.Sqrshl_V,      typeof(OpCodeSimdReg64));
-            SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_S,     typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_V,     typeof(OpCodeSimdShImm64));
-            SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_S,    typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_V,    typeof(OpCodeSimdShImm64));
-            SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstEmit.Sqshl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_S,      typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_V,      typeof(OpCodeSimdShImm64));
-            SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_S,     typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_V,     typeof(OpCodeSimdShImm64));
-            SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_S,       typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_S,       typeof(OpCodeSimd64));
-            SetA64("0x001110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_V,       typeof(OpCodeSimd64));
-            SetA64("01111110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_S,      typeof(OpCodeSimd64));
-            SetA64("0x101110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_V,      typeof(OpCodeSimd64));
-            SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstEmit.Srhadd_V,      typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstEmit.Srshl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_S,       typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstEmit.Srshr_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0100111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0101111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_S,       typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx001101xxxxxxxxxx", InstEmit.Srsra_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0100111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", InstEmit.Sshl_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x00111100>>>xxx101001xxxxxxxxxx", InstEmit.Sshll_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0101111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_S,        typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx000001xxxxxxxxxx", InstEmit.Sshr_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0100111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_S,        typeof(OpCodeSimdShImm64));
-            SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstEmit.Ssra_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstEmit.Ssubl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstEmit.Ssubw_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x00110000000000xxxxxxxxxxxxxxxx", InstEmit.St__Vms,       typeof(OpCodeSimdMemMs64));
-            SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vms,       typeof(OpCodeSimdMemMs64));
-            SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", InstEmit.St__Vss,       typeof(OpCodeSimdMemSs64));
-            SetA64("0x00110110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vss,       typeof(OpCodeSimdMemSs64));
-            SetA64("xx10110xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp,           typeof(OpCodeSimdMemPair64));
-            SetA64("xx111100x00xxxxxxxxx00xxxxxxxxxx", InstEmit.Str,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x00xxxxxxxxx01xxxxxxxxxx", InstEmit.Str,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x00xxxxxxxxx11xxxxxxxxxx", InstEmit.Str,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,           typeof(OpCodeSimdMemImm64));
-            SetA64("xx111100x01xxxxxxxxx10xxxxxxxxxx", InstEmit.Str,           typeof(OpCodeSimdMemReg64));
-            SetA64("01111110111xxxxx100001xxxxxxxxxx", InstEmit.Sub_S,         typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", InstEmit.Sub_V,         typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", InstEmit.Subhn_V,       typeof(OpCodeSimdReg64));
-            SetA64("01011110xx100000001110xxxxxxxxxx", InstEmit.Suqadd_S,      typeof(OpCodeSimd64));
-            SetA64("0>001110<<100000001110xxxxxxxxxx", InstEmit.Suqadd_V,      typeof(OpCodeSimd64));
-            SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", InstEmit.Tbl_V,         typeof(OpCodeSimdTbl64));
-            SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", InstEmit.Trn1_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", InstEmit.Trn2_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", InstEmit.Uaba_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", InstEmit.Uabal_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", InstEmit.Uabd_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", InstEmit.Uabdl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<100000011010xxxxxxxxxx", InstEmit.Uadalp_V,      typeof(OpCodeSimd64));
-            SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", InstEmit.Uaddl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<100000001010xxxxxxxxxx", InstEmit.Uaddlp_V,      typeof(OpCodeSimd64));
-            SetA64("001011100x110000001110xxxxxxxxxx", InstEmit.Uaddlv_V,      typeof(OpCodeSimd64));
-            SetA64("01101110<<110000001110xxxxxxxxxx", InstEmit.Uaddlv_V,      typeof(OpCodeSimd64));
-            SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", InstEmit.Uaddw_V,       typeof(OpCodeSimdReg64));
-            SetA64("x00111100x100011000000xxxxxxxxxx", InstEmit.Ucvtf_Gp,      typeof(OpCodeSimdCvt64));
-            SetA64("011111100x100001110110xxxxxxxxxx", InstEmit.Ucvtf_S,       typeof(OpCodeSimd64));
-            SetA64("0>1011100<100001110110xxxxxxxxxx", InstEmit.Ucvtf_V,       typeof(OpCodeSimd64));
-            SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", InstEmit.Uhadd_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstEmit.Uhsub_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstEmit.Umax_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstEmit.Umaxp_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstEmit.Umin_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstEmit.Uminp_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstEmit.Umlal_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstEmit.Umlsl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x001110000xxxxx001111xxxxxxxxxx", InstEmit.Umov_S,        typeof(OpCodeSimdIns64));
-            SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", InstEmit.Umull_V,       typeof(OpCodeSimdReg64));
-            SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_S,       typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstEmit.Uqrshl_V,      typeof(OpCodeSimdReg64));
-            SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_S,     typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_V,     typeof(OpCodeSimdShImm64));
-            SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstEmit.Uqshl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_S,      typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_V,      typeof(OpCodeSimdShImm64));
-            SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_S,       typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_V,       typeof(OpCodeSimdReg64));
-            SetA64("01111110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_S,       typeof(OpCodeSimd64));
-            SetA64("0x101110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_V,       typeof(OpCodeSimd64));
-            SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstEmit.Urhadd_V,      typeof(OpCodeSimdReg64));
-            SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstEmit.Urshl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_S,       typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstEmit.Urshr_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0110111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0111111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_S,       typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx001101xxxxxxxxxx", InstEmit.Ursra_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0110111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", InstEmit.Ushl_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x10111100>>>xxx101001xxxxxxxxxx", InstEmit.Ushll_V,       typeof(OpCodeSimdShImm64));
-            SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_S,        typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstEmit.Ushr_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_V,        typeof(OpCodeSimdShImm64));
-            SetA64("01111110xx100000001110xxxxxxxxxx", InstEmit.Usqadd_S,      typeof(OpCodeSimd64));
-            SetA64("0>101110<<100000001110xxxxxxxxxx", InstEmit.Usqadd_V,      typeof(OpCodeSimd64));
-            SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_S,        typeof(OpCodeSimdShImm64));
-            SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstEmit.Usra_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_V,        typeof(OpCodeSimdShImm64));
-            SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstEmit.Usubl_V,       typeof(OpCodeSimdReg64));
-            SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstEmit.Usubw_V,       typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", InstEmit.Uzp1_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", InstEmit.Uzp2_V,        typeof(OpCodeSimdReg64));
-            SetA64("0x001110<<100001001010xxxxxxxxxx", InstEmit.Xtn_V,         typeof(OpCodeSimd64));
-            SetA64("0>001110<<0xxxxx001110xxxxxxxxxx", InstEmit.Zip1_V,        typeof(OpCodeSimdReg64));
-            SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", InstEmit.Zip2_V,        typeof(OpCodeSimdReg64));
+            SetA64("0101111011100000101110xxxxxxxxxx", InstEmit.Abs_S,           typeof(OpCodeSimd64));
+            SetA64("0>001110<<100000101110xxxxxxxxxx", InstEmit.Abs_V,           typeof(OpCodeSimd64));
+            SetA64("01011110111xxxxx100001xxxxxxxxxx", InstEmit.Add_S,           typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", InstEmit.Add_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", InstEmit.Addhn_V,         typeof(OpCodeSimdReg64));
+            SetA64("0101111011110001101110xxxxxxxxxx", InstEmit.Addp_S,          typeof(OpCodeSimd64));
+            SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", InstEmit.Addp_V,          typeof(OpCodeSimdReg64));
+            SetA64("000011100x110001101110xxxxxxxxxx", InstEmit.Addv_V,          typeof(OpCodeSimd64));
+            SetA64("01001110<<110001101110xxxxxxxxxx", InstEmit.Addv_V,          typeof(OpCodeSimd64));
+            SetA64("0100111000101000010110xxxxxxxxxx", InstEmit.Aesd_V,          typeof(OpCodeSimd64));
+            SetA64("0100111000101000010010xxxxxxxxxx", InstEmit.Aese_V,          typeof(OpCodeSimd64));
+            SetA64("0100111000101000011110xxxxxxxxxx", InstEmit.Aesimc_V,        typeof(OpCodeSimd64));
+            SetA64("0100111000101000011010xxxxxxxxxx", InstEmit.Aesmc_V,         typeof(OpCodeSimd64));
+            SetA64("0x001110001xxxxx000111xxxxxxxxxx", InstEmit.And_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001110011xxxxx000111xxxxxxxxxx", InstEmit.Bic_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x10111100000xxx<<x101xxxxxxxxxx", InstEmit.Bic_Vi,          typeof(OpCodeSimdImm64));
+            SetA64("0x101110111xxxxx000111xxxxxxxxxx", InstEmit.Bif_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x101110101xxxxx000111xxxxxxxxxx", InstEmit.Bit_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x101110011xxxxx000111xxxxxxxxxx", InstEmit.Bsl_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<100000010010xxxxxxxxxx", InstEmit.Cls_V,           typeof(OpCodeSimd64));
+            SetA64("0x101110<<100000010010xxxxxxxxxx", InstEmit.Clz_V,           typeof(OpCodeSimd64));
+            SetA64("01111110111xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_S,          typeof(OpCodeSimdReg64));
+            SetA64("0101111011100000100110xxxxxxxxxx", InstEmit.Cmeq_S,          typeof(OpCodeSimd64));
+            SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmeq_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<100000100110xxxxxxxxxx", InstEmit.Cmeq_V,          typeof(OpCodeSimd64));
+            SetA64("01011110111xxxxx001111xxxxxxxxxx", InstEmit.Cmge_S,          typeof(OpCodeSimdReg64));
+            SetA64("0111111011100000100010xxxxxxxxxx", InstEmit.Cmge_S,          typeof(OpCodeSimd64));
+            SetA64("0>001110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmge_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<100000100010xxxxxxxxxx", InstEmit.Cmge_V,          typeof(OpCodeSimd64));
+            SetA64("01011110111xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_S,          typeof(OpCodeSimdReg64));
+            SetA64("0101111011100000100010xxxxxxxxxx", InstEmit.Cmgt_S,          typeof(OpCodeSimd64));
+            SetA64("0>001110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmgt_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<100000100010xxxxxxxxxx", InstEmit.Cmgt_V,          typeof(OpCodeSimd64));
+            SetA64("01111110111xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx001101xxxxxxxxxx", InstEmit.Cmhi_V,          typeof(OpCodeSimdReg64));
+            SetA64("01111110111xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx001111xxxxxxxxxx", InstEmit.Cmhs_V,          typeof(OpCodeSimdReg64));
+            SetA64("0111111011100000100110xxxxxxxxxx", InstEmit.Cmle_S,          typeof(OpCodeSimd64));
+            SetA64("0>101110<<100000100110xxxxxxxxxx", InstEmit.Cmle_V,          typeof(OpCodeSimd64));
+            SetA64("0101111011100000101010xxxxxxxxxx", InstEmit.Cmlt_S,          typeof(OpCodeSimd64));
+            SetA64("0>001110<<100000101010xxxxxxxxxx", InstEmit.Cmlt_V,          typeof(OpCodeSimd64));
+            SetA64("01011110111xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_S,         typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", InstEmit.Cmtst_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x00111000100000010110xxxxxxxxxx", InstEmit.Cnt_V,           typeof(OpCodeSimd64));
+            SetA64("0>001110000x<>>>000011xxxxxxxxxx", InstEmit.Dup_Gp,          typeof(OpCodeSimdIns64));
+            SetA64("01011110000xxxxx000001xxxxxxxxxx", InstEmit.Dup_S,           typeof(OpCodeSimdIns64));
+            SetA64("0>001110000x<>>>000001xxxxxxxxxx", InstEmit.Dup_V,           typeof(OpCodeSimdIns64));
+            SetA64("0x101110001xxxxx000111xxxxxxxxxx", InstEmit.Eor_V,           typeof(OpCodeSimdReg64));
+            SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", InstEmit.Ext_V,           typeof(OpCodeSimdExt64));
+            SetA64("011111101x1xxxxx110101xxxxxxxxxx", InstEmit.Fabd_S,          typeof(OpCodeSimdReg64));
+            SetA64("000111100x100000110000xxxxxxxxxx", InstEmit.Fabs_S,          typeof(OpCodeSimd64));
+            SetA64("0>0011101<100000111110xxxxxxxxxx", InstEmit.Fabs_V,          typeof(OpCodeSimd64));
+            SetA64("000111100x1xxxxx001010xxxxxxxxxx", InstEmit.Fadd_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", InstEmit.Fadd_V,          typeof(OpCodeSimdReg64));
+            SetA64("011111100x110000110110xxxxxxxxxx", InstEmit.Faddp_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", InstEmit.Faddp_V,         typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxxxxxx01xxxxx0xxxx", InstEmit.Fccmp_S,         typeof(OpCodeSimdFcond64));
+            SetA64("000111100x1xxxxxxxxx01xxxxx1xxxx", InstEmit.Fccmpe_S,        typeof(OpCodeSimdFcond64));
+            SetA64("010111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_S,         typeof(OpCodeSimdReg64));
+            SetA64("010111101x100000110110xxxxxxxxxx", InstEmit.Fcmeq_S,         typeof(OpCodeSimd64));
+            SetA64("0>0011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmeq_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<100000110110xxxxxxxxxx", InstEmit.Fcmeq_V,         typeof(OpCodeSimd64));
+            SetA64("011111100x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_S,         typeof(OpCodeSimdReg64));
+            SetA64("011111101x100000110010xxxxxxxxxx", InstEmit.Fcmge_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011100<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmge_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>1011101<100000110010xxxxxxxxxx", InstEmit.Fcmge_V,         typeof(OpCodeSimd64));
+            SetA64("011111101x1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_S,         typeof(OpCodeSimdReg64));
+            SetA64("010111101x100000110010xxxxxxxxxx", InstEmit.Fcmgt_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011101<1xxxxx111001xxxxxxxxxx", InstEmit.Fcmgt_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<100000110010xxxxxxxxxx", InstEmit.Fcmgt_V,         typeof(OpCodeSimd64));
+            SetA64("011111101x100000110110xxxxxxxxxx", InstEmit.Fcmle_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011101<100000110110xxxxxxxxxx", InstEmit.Fcmle_V,         typeof(OpCodeSimd64));
+            SetA64("010111101x100000111010xxxxxxxxxx", InstEmit.Fcmlt_S,         typeof(OpCodeSimd64));
+            SetA64("0>0011101<100000111010xxxxxxxxxx", InstEmit.Fcmlt_V,         typeof(OpCodeSimd64));
+            SetA64("000111100x1xxxxx001000xxxxx0x000", InstEmit.Fcmp_S,          typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx001000xxxxx1x000", InstEmit.Fcmpe_S,         typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", InstEmit.Fcsel_S,         typeof(OpCodeSimdFcond64));
+            SetA64("000111100x10001xx10000xxxxxxxxxx", InstEmit.Fcvt_S,          typeof(OpCodeSimd64));
+            SetA64("x00111100x100100000000xxxxxxxxxx", InstEmit.Fcvtas_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x100101000000xxxxxxxxxx", InstEmit.Fcvtau_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("0x0011100x100001011110xxxxxxxxxx", InstEmit.Fcvtl_V,         typeof(OpCodeSimd64));
+            SetA64("x00111100x110000000000xxxxxxxxxx", InstEmit.Fcvtms_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x110001000000xxxxxxxxxx", InstEmit.Fcvtmu_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("0x0011100x100001011010xxxxxxxxxx", InstEmit.Fcvtn_V,         typeof(OpCodeSimd64));
+            SetA64("010111100x100001101010xxxxxxxxxx", InstEmit.Fcvtns_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011100<100001101010xxxxxxxxxx", InstEmit.Fcvtns_V,        typeof(OpCodeSimd64));
+            SetA64("011111100x100001101010xxxxxxxxxx", InstEmit.Fcvtnu_S,        typeof(OpCodeSimd64));
+            SetA64("0>1011100<100001101010xxxxxxxxxx", InstEmit.Fcvtnu_V,        typeof(OpCodeSimd64));
+            SetA64("x00111100x101000000000xxxxxxxxxx", InstEmit.Fcvtps_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x101001000000xxxxxxxxxx", InstEmit.Fcvtpu_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x111000000000xxxxxxxxxx", InstEmit.Fcvtzs_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x011000xxxxxxxxxxxxxxxx", InstEmit.Fcvtzs_Gp_Fixed, typeof(OpCodeSimdCvt64));
+            SetA64("010111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzs_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzs_V,        typeof(OpCodeSimd64));
+            SetA64("0x0011110>>xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzs_V,        typeof(OpCodeSimdShImm64));
+            SetA64("x00111100x111001000000xxxxxxxxxx", InstEmit.Fcvtzu_Gp,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x011001xxxxxxxxxxxxxxxx", InstEmit.Fcvtzu_Gp_Fixed, typeof(OpCodeSimdCvt64));
+            SetA64("011111101x100001101110xxxxxxxxxx", InstEmit.Fcvtzu_S,        typeof(OpCodeSimd64));
+            SetA64("0>1011101<100001101110xxxxxxxxxx", InstEmit.Fcvtzu_V,        typeof(OpCodeSimd64));
+            SetA64("0x1011110>>xxxxx111111xxxxxxxxxx", InstEmit.Fcvtzu_V,        typeof(OpCodeSimdShImm64));
+            SetA64("000111100x1xxxxx000110xxxxxxxxxx", InstEmit.Fdiv_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", InstEmit.Fdiv_V,          typeof(OpCodeSimdReg64));
+            SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fmadd_S,         typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx010010xxxxxxxxxx", InstEmit.Fmax_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmax_V,          typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx011010xxxxxxxxxx", InstEmit.Fmaxnm_S,        typeof(OpCodeSimdReg64));
+            SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", InstEmit.Fmaxnm_V,        typeof(OpCodeSimdReg64));
+            SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", InstEmit.Fmaxp_V,         typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx010110xxxxxxxxxx", InstEmit.Fmin_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fmin_V,          typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx011110xxxxxxxxxx", InstEmit.Fminnm_S,        typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", InstEmit.Fminnm_V,        typeof(OpCodeSimdReg64));
+            SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", InstEmit.Fminp_V,         typeof(OpCodeSimdReg64));
+            SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Se,         typeof(OpCodeSimdRegElemF64));
+            SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", InstEmit.Fmla_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", InstEmit.Fmla_Ve,         typeof(OpCodeSimdRegElemF64));
+            SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Se,         typeof(OpCodeSimdRegElemF64));
+            SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", InstEmit.Fmls_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", InstEmit.Fmls_Ve,         typeof(OpCodeSimdRegElemF64));
+            SetA64("000111100x100000010000xxxxxxxxxx", InstEmit.Fmov_S,          typeof(OpCodeSimd64));
+            SetA64("00011110xx1xxxxxxxx100xxxxxxxxxx", InstEmit.Fmov_Si,         typeof(OpCodeSimdFmov64));
+            SetA64("0xx0111100000xxx111101xxxxxxxxxx", InstEmit.Fmov_V,          typeof(OpCodeSimdImm64));
+            SetA64("x00111100x100110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi,       typeof(OpCodeSimdCvt64));
+            SetA64("x00111100x100111000000xxxxxxxxxx", InstEmit.Fmov_Itof,       typeof(OpCodeSimdCvt64));
+            SetA64("1001111010101110000000xxxxxxxxxx", InstEmit.Fmov_Ftoi1,      typeof(OpCodeSimdCvt64));
+            SetA64("1001111010101111000000xxxxxxxxxx", InstEmit.Fmov_Itof1,      typeof(OpCodeSimdCvt64));
+            SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fmsub_S,         typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx000010xxxxxxxxxx", InstEmit.Fmul_S,          typeof(OpCodeSimdReg64));
+            SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Se,         typeof(OpCodeSimdRegElemF64));
+            SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmul_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmul_Ve,         typeof(OpCodeSimdRegElemF64));
+            SetA64("010111100x1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_S,         typeof(OpCodeSimdReg64));
+            SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Se,        typeof(OpCodeSimdRegElemF64));
+            SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", InstEmit.Fmulx_Ve,        typeof(OpCodeSimdRegElemF64));
+            SetA64("000111100x100001010000xxxxxxxxxx", InstEmit.Fneg_S,          typeof(OpCodeSimd64));
+            SetA64("0>1011101<100000111110xxxxxxxxxx", InstEmit.Fneg_V,          typeof(OpCodeSimd64));
+            SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", InstEmit.Fnmadd_S,        typeof(OpCodeSimdReg64));
+            SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", InstEmit.Fnmsub_S,        typeof(OpCodeSimdReg64));
+            SetA64("000111100x1xxxxx100010xxxxxxxxxx", InstEmit.Fnmul_S,         typeof(OpCodeSimdReg64));
+            SetA64("010111101x100001110110xxxxxxxxxx", InstEmit.Frecpe_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011101<100001110110xxxxxxxxxx", InstEmit.Frecpe_V,        typeof(OpCodeSimd64));
+            SetA64("010111100x1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_S,        typeof(OpCodeSimdReg64));
+            SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", InstEmit.Frecps_V,        typeof(OpCodeSimdReg64));
+            SetA64("010111101x100001111110xxxxxxxxxx", InstEmit.Frecpx_S,        typeof(OpCodeSimd64));
+            SetA64("000111100x100110010000xxxxxxxxxx", InstEmit.Frinta_S,        typeof(OpCodeSimd64));
+            SetA64("0>1011100<100001100010xxxxxxxxxx", InstEmit.Frinta_V,        typeof(OpCodeSimd64));
+            SetA64("000111100x100111110000xxxxxxxxxx", InstEmit.Frinti_S,        typeof(OpCodeSimd64));
+            SetA64("0>1011101<100001100110xxxxxxxxxx", InstEmit.Frinti_V,        typeof(OpCodeSimd64));
+            SetA64("000111100x100101010000xxxxxxxxxx", InstEmit.Frintm_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011100<100001100110xxxxxxxxxx", InstEmit.Frintm_V,        typeof(OpCodeSimd64));
+            SetA64("000111100x100100010000xxxxxxxxxx", InstEmit.Frintn_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011100<100001100010xxxxxxxxxx", InstEmit.Frintn_V,        typeof(OpCodeSimd64));
+            SetA64("000111100x100100110000xxxxxxxxxx", InstEmit.Frintp_S,        typeof(OpCodeSimd64));
+            SetA64("0>0011101<100001100010xxxxxxxxxx", InstEmit.Frintp_V,        typeof(OpCodeSimd64));
+            SetA64("000111100x100111010000xxxxxxxxxx", InstEmit.Frintx_S,        typeof(OpCodeSimd64));
+            SetA64("0>1011100<100001100110xxxxxxxxxx", InstEmit.Frintx_V,        typeof(OpCodeSimd64));
+            SetA64("011111101x100001110110xxxxxxxxxx", InstEmit.Frsqrte_S,       typeof(OpCodeSimd64));
+            SetA64("0>1011101<100001110110xxxxxxxxxx", InstEmit.Frsqrte_V,       typeof(OpCodeSimd64));
+            SetA64("010111101x1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_S,       typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", InstEmit.Frsqrts_V,       typeof(OpCodeSimdReg64));
+            SetA64("000111100x100001110000xxxxxxxxxx", InstEmit.Fsqrt_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011101<100001111110xxxxxxxxxx", InstEmit.Fsqrt_V,         typeof(OpCodeSimd64));
+            SetA64("000111100x1xxxxx001110xxxxxxxxxx", InstEmit.Fsub_S,          typeof(OpCodeSimdReg64));
+            SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", InstEmit.Fsub_V,          typeof(OpCodeSimdReg64));
+            SetA64("01001110000xxxxx000111xxxxxxxxxx", InstEmit.Ins_Gp,          typeof(OpCodeSimdIns64));
+            SetA64("01101110000xxxxx0xxxx1xxxxxxxxxx", InstEmit.Ins_V,           typeof(OpCodeSimdIns64));
+            SetA64("0x00110001000000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vms,         typeof(OpCodeSimdMemMs64));
+            SetA64("0x001100110xxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vms,         typeof(OpCodeSimdMemMs64));
+            SetA64("0x00110101x00000xxxxxxxxxxxxxxxx", InstEmit.Ld__Vss,         typeof(OpCodeSimdMemSs64));
+            SetA64("0x00110111xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ld__Vss,         typeof(OpCodeSimdMemSs64));
+            SetA64("xx10110xx1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldp,             typeof(OpCodeSimdMemPair64));
+            SetA64("xx111100x10xxxxxxxxx00xxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x10xxxxxxxxx01xxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x10xxxxxxxxx11xxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x11xxxxxxxxx10xxxxxxxxxx", InstEmit.Ldr,             typeof(OpCodeSimdMemReg64));
+            SetA64("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", InstEmit.Ldr_Literal,     typeof(OpCodeSimdMemLit64));
+            SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mla_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", InstEmit.Mla_Ve,          typeof(OpCodeSimdRegElem64));
+            SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", InstEmit.Mls_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", InstEmit.Mls_Ve,          typeof(OpCodeSimdRegElem64));
+            SetA64("0x00111100000xxx0xx001xxxxxxxxxx", InstEmit.Movi_V,          typeof(OpCodeSimdImm64));
+            SetA64("0x00111100000xxx10x001xxxxxxxxxx", InstEmit.Movi_V,          typeof(OpCodeSimdImm64));
+            SetA64("0x00111100000xxx110x01xxxxxxxxxx", InstEmit.Movi_V,          typeof(OpCodeSimdImm64));
+            SetA64("0xx0111100000xxx111001xxxxxxxxxx", InstEmit.Movi_V,          typeof(OpCodeSimdImm64));
+            SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", InstEmit.Mul_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", InstEmit.Mul_Ve,          typeof(OpCodeSimdRegElem64));
+            SetA64("0x10111100000xxx0xx001xxxxxxxxxx", InstEmit.Mvni_V,          typeof(OpCodeSimdImm64));
+            SetA64("0x10111100000xxx10x001xxxxxxxxxx", InstEmit.Mvni_V,          typeof(OpCodeSimdImm64));
+            SetA64("0x10111100000xxx110x01xxxxxxxxxx", InstEmit.Mvni_V,          typeof(OpCodeSimdImm64));
+            SetA64("0111111011100000101110xxxxxxxxxx", InstEmit.Neg_S,           typeof(OpCodeSimd64));
+            SetA64("0>101110<<100000101110xxxxxxxxxx", InstEmit.Neg_V,           typeof(OpCodeSimd64));
+            SetA64("0x10111000100000010110xxxxxxxxxx", InstEmit.Not_V,           typeof(OpCodeSimd64));
+            SetA64("0x001110111xxxxx000111xxxxxxxxxx", InstEmit.Orn_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001110101xxxxx000111xxxxxxxxxx", InstEmit.Orr_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x00111100000xxx<<x101xxxxxxxxxx", InstEmit.Orr_Vi,          typeof(OpCodeSimdImm64));
+            SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", InstEmit.Raddhn_V,        typeof(OpCodeSimdReg64));
+            SetA64("0x10111001100000010110xxxxxxxxxx", InstEmit.Rbit_V,          typeof(OpCodeSimd64));
+            SetA64("0x00111000100000000110xxxxxxxxxx", InstEmit.Rev16_V,         typeof(OpCodeSimd64));
+            SetA64("0x1011100x100000000010xxxxxxxxxx", InstEmit.Rev32_V,         typeof(OpCodeSimd64));
+            SetA64("0x001110<<100000000010xxxxxxxxxx", InstEmit.Rev64_V,         typeof(OpCodeSimd64));
+            SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstEmit.Rshrn_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstEmit.Rsubhn_V,        typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstEmit.Saba_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstEmit.Sabal_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", InstEmit.Sabd_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", InstEmit.Sabdl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<100000011010xxxxxxxxxx", InstEmit.Sadalp_V,        typeof(OpCodeSimd64));
+            SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", InstEmit.Saddl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<100000001010xxxxxxxxxx", InstEmit.Saddlp_V,        typeof(OpCodeSimd64));
+            SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", InstEmit.Saddw_V,         typeof(OpCodeSimdReg64));
+            SetA64("x00111100x100010000000xxxxxxxxxx", InstEmit.Scvtf_Gp,        typeof(OpCodeSimdCvt64));
+            SetA64("010111100x100001110110xxxxxxxxxx", InstEmit.Scvtf_S,         typeof(OpCodeSimd64));
+            SetA64("0>0011100<100001110110xxxxxxxxxx", InstEmit.Scvtf_V,         typeof(OpCodeSimd64));
+            SetA64("01011110000xxxxx000000xxxxxxxxxx", InstEmit.Sha1c_V,         typeof(OpCodeSimdReg64));
+            SetA64("0101111000101000000010xxxxxxxxxx", InstEmit.Sha1h_V,         typeof(OpCodeSimd64));
+            SetA64("01011110000xxxxx001000xxxxxxxxxx", InstEmit.Sha1m_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110000xxxxx000100xxxxxxxxxx", InstEmit.Sha1p_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110000xxxxx001100xxxxxxxxxx", InstEmit.Sha1su0_V,       typeof(OpCodeSimdReg64));
+            SetA64("0101111000101000000110xxxxxxxxxx", InstEmit.Sha1su1_V,       typeof(OpCodeSimd64));
+            SetA64("01011110000xxxxx010000xxxxxxxxxx", InstEmit.Sha256h_V,       typeof(OpCodeSimdReg64));
+            SetA64("01011110000xxxxx010100xxxxxxxxxx", InstEmit.Sha256h2_V,      typeof(OpCodeSimdReg64));
+            SetA64("0101111000101000001010xxxxxxxxxx", InstEmit.Sha256su0_V,     typeof(OpCodeSimd64));
+            SetA64("01011110000xxxxx011000xxxxxxxxxx", InstEmit.Sha256su1_V,     typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstEmit.Shadd_V,         typeof(OpCodeSimdReg64));
+            SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_S,           typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstEmit.Shl_V,           typeof(OpCodeSimdShImm64));
+            SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstEmit.Shl_V,           typeof(OpCodeSimdShImm64));
+            SetA64("0x101110<<100001001110xxxxxxxxxx", InstEmit.Shll_V,          typeof(OpCodeSimd64));
+            SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstEmit.Shrn_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstEmit.Shsub_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstEmit.Sli_V,           typeof(OpCodeSimdShImm64));
+            SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstEmit.Smax_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstEmit.Smaxp_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstEmit.Smin_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstEmit.Sminp_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstEmit.Smlal_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstEmit.Smlsl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110000xxxxx001011xxxxxxxxxx", InstEmit.Smov_S,          typeof(OpCodeSimdIns64));
+            SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", InstEmit.Smull_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110xx100000011110xxxxxxxxxx", InstEmit.Sqabs_S,         typeof(OpCodeSimd64));
+            SetA64("0>001110<<100000011110xxxxxxxxxx", InstEmit.Sqabs_V,         typeof(OpCodeSimd64));
+            SetA64("01011110xx1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_S,         typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", InstEmit.Sqadd_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S,       typeof(OpCodeSimdReg64));
+            SetA64("01011110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_S,       typeof(OpCodeSimdReg64));
+            SetA64("0x001110011xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V,       typeof(OpCodeSimdReg64));
+            SetA64("0x001110101xxxxx101101xxxxxxxxxx", InstEmit.Sqdmulh_V,       typeof(OpCodeSimdReg64));
+            SetA64("01111110xx100000011110xxxxxxxxxx", InstEmit.Sqneg_S,         typeof(OpCodeSimd64));
+            SetA64("0>101110<<100000011110xxxxxxxxxx", InstEmit.Sqneg_V,         typeof(OpCodeSimd64));
+            SetA64("01111110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S,      typeof(OpCodeSimdReg64));
+            SetA64("01111110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_S,      typeof(OpCodeSimdReg64));
+            SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V,      typeof(OpCodeSimdReg64));
+            SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstEmit.Sqrdmulh_V,      typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstEmit.Sqrshl_V,        typeof(OpCodeSimdReg64));
+            SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_S,       typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstEmit.Sqrshrn_V,       typeof(OpCodeSimdShImm64));
+            SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_S,      typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstEmit.Sqrshrun_V,      typeof(OpCodeSimdShImm64));
+            SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstEmit.Sqshl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_S,        typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstEmit.Sqshrn_V,        typeof(OpCodeSimdShImm64));
+            SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_S,       typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstEmit.Sqshrun_V,       typeof(OpCodeSimdShImm64));
+            SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_S,         typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstEmit.Sqsub_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_S,         typeof(OpCodeSimd64));
+            SetA64("0x001110<<100001010010xxxxxxxxxx", InstEmit.Sqxtn_V,         typeof(OpCodeSimd64));
+            SetA64("01111110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_S,        typeof(OpCodeSimd64));
+            SetA64("0x101110<<100001001010xxxxxxxxxx", InstEmit.Sqxtun_V,        typeof(OpCodeSimd64));
+            SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstEmit.Srhadd_V,        typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstEmit.Srshl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_S,         typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstEmit.Srshr_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0100111101xxxxxx001001xxxxxxxxxx", InstEmit.Srshr_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0101111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_S,         typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx001101xxxxxxxxxx", InstEmit.Srsra_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0100111101xxxxxx001101xxxxxxxxxx", InstEmit.Srsra_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", InstEmit.Sshl_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x00111100>>>xxx101001xxxxxxxxxx", InstEmit.Sshll_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0101111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_S,          typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx000001xxxxxxxxxx", InstEmit.Sshr_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0100111101xxxxxx000001xxxxxxxxxx", InstEmit.Sshr_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_S,          typeof(OpCodeSimdShImm64));
+            SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstEmit.Ssra_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstEmit.Ssra_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstEmit.Ssubl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstEmit.Ssubw_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x00110000000000xxxxxxxxxxxxxxxx", InstEmit.St__Vms,         typeof(OpCodeSimdMemMs64));
+            SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vms,         typeof(OpCodeSimdMemMs64));
+            SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", InstEmit.St__Vss,         typeof(OpCodeSimdMemSs64));
+            SetA64("0x00110110xxxxxxxxxxxxxxxxxxxxxx", InstEmit.St__Vss,         typeof(OpCodeSimdMemSs64));
+            SetA64("xx10110xx0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Stp,             typeof(OpCodeSimdMemPair64));
+            SetA64("xx111100x00xxxxxxxxx00xxxxxxxxxx", InstEmit.Str,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x00xxxxxxxxx01xxxxxxxxxx", InstEmit.Str,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x00xxxxxxxxx11xxxxxxxxxx", InstEmit.Str,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", InstEmit.Str,             typeof(OpCodeSimdMemImm64));
+            SetA64("xx111100x01xxxxxxxxx10xxxxxxxxxx", InstEmit.Str,             typeof(OpCodeSimdMemReg64));
+            SetA64("01111110111xxxxx100001xxxxxxxxxx", InstEmit.Sub_S,           typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", InstEmit.Sub_V,           typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", InstEmit.Subhn_V,         typeof(OpCodeSimdReg64));
+            SetA64("01011110xx100000001110xxxxxxxxxx", InstEmit.Suqadd_S,        typeof(OpCodeSimd64));
+            SetA64("0>001110<<100000001110xxxxxxxxxx", InstEmit.Suqadd_V,        typeof(OpCodeSimd64));
+            SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", InstEmit.Tbl_V,           typeof(OpCodeSimdTbl64));
+            SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", InstEmit.Trn1_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", InstEmit.Trn2_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", InstEmit.Uaba_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", InstEmit.Uabal_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", InstEmit.Uabd_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", InstEmit.Uabdl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<100000011010xxxxxxxxxx", InstEmit.Uadalp_V,        typeof(OpCodeSimd64));
+            SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", InstEmit.Uaddl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<100000001010xxxxxxxxxx", InstEmit.Uaddlp_V,        typeof(OpCodeSimd64));
+            SetA64("001011100x110000001110xxxxxxxxxx", InstEmit.Uaddlv_V,        typeof(OpCodeSimd64));
+            SetA64("01101110<<110000001110xxxxxxxxxx", InstEmit.Uaddlv_V,        typeof(OpCodeSimd64));
+            SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", InstEmit.Uaddw_V,         typeof(OpCodeSimdReg64));
+            SetA64("x00111100x100011000000xxxxxxxxxx", InstEmit.Ucvtf_Gp,        typeof(OpCodeSimdCvt64));
+            SetA64("011111100x100001110110xxxxxxxxxx", InstEmit.Ucvtf_S,         typeof(OpCodeSimd64));
+            SetA64("0>1011100<100001110110xxxxxxxxxx", InstEmit.Ucvtf_V,         typeof(OpCodeSimd64));
+            SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", InstEmit.Uhadd_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstEmit.Uhsub_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstEmit.Umax_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstEmit.Umaxp_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstEmit.Umin_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstEmit.Uminp_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstEmit.Umlal_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstEmit.Umlsl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x001110000xxxxx001111xxxxxxxxxx", InstEmit.Umov_S,          typeof(OpCodeSimdIns64));
+            SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", InstEmit.Umull_V,         typeof(OpCodeSimdReg64));
+            SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_S,         typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstEmit.Uqadd_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstEmit.Uqrshl_V,        typeof(OpCodeSimdReg64));
+            SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_S,       typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstEmit.Uqrshrn_V,       typeof(OpCodeSimdShImm64));
+            SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstEmit.Uqshl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_S,        typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstEmit.Uqshrn_V,        typeof(OpCodeSimdShImm64));
+            SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_S,         typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstEmit.Uqsub_V,         typeof(OpCodeSimdReg64));
+            SetA64("01111110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_S,         typeof(OpCodeSimd64));
+            SetA64("0x101110<<100001010010xxxxxxxxxx", InstEmit.Uqxtn_V,         typeof(OpCodeSimd64));
+            SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstEmit.Urhadd_V,        typeof(OpCodeSimdReg64));
+            SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstEmit.Urshl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_S,         typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstEmit.Urshr_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0110111101xxxxxx001001xxxxxxxxxx", InstEmit.Urshr_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0111111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_S,         typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx001101xxxxxxxxxx", InstEmit.Ursra_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0110111101xxxxxx001101xxxxxxxxxx", InstEmit.Ursra_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", InstEmit.Ushl_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x10111100>>>xxx101001xxxxxxxxxx", InstEmit.Ushll_V,         typeof(OpCodeSimdShImm64));
+            SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_S,          typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstEmit.Ushr_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstEmit.Ushr_V,          typeof(OpCodeSimdShImm64));
+            SetA64("01111110xx100000001110xxxxxxxxxx", InstEmit.Usqadd_S,        typeof(OpCodeSimd64));
+            SetA64("0>101110<<100000001110xxxxxxxxxx", InstEmit.Usqadd_V,        typeof(OpCodeSimd64));
+            SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_S,          typeof(OpCodeSimdShImm64));
+            SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstEmit.Usra_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstEmit.Usra_V,          typeof(OpCodeSimdShImm64));
+            SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstEmit.Usubl_V,         typeof(OpCodeSimdReg64));
+            SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstEmit.Usubw_V,         typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", InstEmit.Uzp1_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", InstEmit.Uzp2_V,          typeof(OpCodeSimdReg64));
+            SetA64("0x001110<<100001001010xxxxxxxxxx", InstEmit.Xtn_V,           typeof(OpCodeSimd64));
+            SetA64("0>001110<<0xxxxx001110xxxxxxxxxx", InstEmit.Zip1_V,          typeof(OpCodeSimdReg64));
+            SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", InstEmit.Zip2_V,          typeof(OpCodeSimdReg64));
 #endregion
 
 #region "Generate InstA64FastLookup Table (AArch64)"
diff --git a/ChocolArm64/TranslatedSub.cs b/ChocolArm64/TranslatedSub.cs
index 8b3ec3f013..653abcca90 100644
--- a/ChocolArm64/TranslatedSub.cs
+++ b/ChocolArm64/TranslatedSub.cs
@@ -24,7 +24,7 @@ namespace ChocolArm64
 
         public DynamicMethod Method { get; private set; }
 
-        public ReadOnlyCollection<Register> Params { get; private set; }
+        public ReadOnlyCollection<Register> SubArgs { get; private set; }
 
         private HashSet<long> _callers;
 
@@ -34,20 +34,10 @@ namespace ChocolArm64
 
         private bool _needsReJit;
 
-        public TranslatedSub(DynamicMethod method, List<Register> Params)
+        public TranslatedSub(DynamicMethod method, List<Register> subArgs)
         {
-            if (method == null)
-            {
-                throw new ArgumentNullException(nameof(method));
-            }
-
-            if (Params == null)
-            {
-                throw new ArgumentNullException(nameof(Params));
-            }
-
-            Method = method;
-            this.Params = Params.AsReadOnly();
+            Method  = method                ?? throw new ArgumentNullException(nameof(method));;
+            SubArgs = subArgs?.AsReadOnly() ?? throw new ArgumentNullException(nameof(subArgs));
 
             _callers = new HashSet<long>();
 
@@ -89,7 +79,7 @@ namespace ChocolArm64
 
             generator.EmitLdargSeq(FixedArgTypes.Length);
 
-            foreach (Register reg in Params)
+            foreach (Register reg in SubArgs)
             {
                 generator.EmitLdarg(StateArgIdx);
 
diff --git a/ChocolArm64/Translation/IILEmit.cs b/ChocolArm64/Translation/IILEmit.cs
index 3c3925ee0a..320520eba7 100644
--- a/ChocolArm64/Translation/IILEmit.cs
+++ b/ChocolArm64/Translation/IILEmit.cs
@@ -2,6 +2,6 @@ namespace ChocolArm64.Translation
 {
     interface IILEmit
     {
-        void Emit(ILEmitter context);
+        void Emit(ILMethodBuilder context);
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Translation/ILBarrier.cs b/ChocolArm64/Translation/ILBarrier.cs
index f931e9922d..37f7558a75 100644
--- a/ChocolArm64/Translation/ILBarrier.cs
+++ b/ChocolArm64/Translation/ILBarrier.cs
@@ -2,6 +2,6 @@ namespace ChocolArm64.Translation
 {
     struct ILBarrier : IILEmit
     {
-        public void Emit(ILEmitter context) { }
+        public void Emit(ILMethodBuilder context) { }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Translation/ILBlock.cs b/ChocolArm64/Translation/ILBlock.cs
index d51e8d9ec3..136579012b 100644
--- a/ChocolArm64/Translation/ILBlock.cs
+++ b/ChocolArm64/Translation/ILBlock.cs
@@ -14,19 +14,21 @@ namespace ChocolArm64.Translation
 
         public bool HasStateStore { get; private set; }
 
-        public List<IILEmit> IlEmitters { get; private set; }
+        private List<IILEmit> _emitters;
+
+        public int Count => _emitters.Count;
 
         public ILBlock Next   { get; set; }
         public ILBlock Branch { get; set; }
 
         public ILBlock()
         {
-            IlEmitters = new List<IILEmit>();
+            _emitters = new List<IILEmit>();
         }
 
-        public void Add(IILEmit ilEmitter)
+        public void Add(IILEmit emitter)
         {
-            if (ilEmitter is ILBarrier)
+            if (emitter is ILBarrier)
             {
                 //Those barriers are used to separate the groups of CIL
                 //opcodes emitted by each ARM instruction.
@@ -35,7 +37,7 @@ namespace ChocolArm64.Translation
                 IntAwOutputs = IntOutputs;
                 VecAwOutputs = VecOutputs;
             }
-            else if (ilEmitter is IlOpCodeLoad ld && ILEmitter.IsRegIndex(ld.Index))
+            else if (emitter is ILOpCodeLoad ld && ILMethodBuilder.IsRegIndex(ld.Index))
             {
                 switch (ld.IoType)
                 {
@@ -44,30 +46,26 @@ namespace ChocolArm64.Translation
                     case IoType.Vector: VecInputs |=  (1L << ld.Index)        & ~VecAwOutputs; break;
                 }
             }
-            else if (ilEmitter is IlOpCodeStore st)
+            else if (emitter is ILOpCodeStore st && ILMethodBuilder.IsRegIndex(st.Index))
             {
-                if (ILEmitter.IsRegIndex(st.Index))
+                switch (st.IoType)
                 {
-                    switch (st.IoType)
-                    {
-                        case IoType.Flag:   IntOutputs |= (1L << st.Index) << 32; break;
-                        case IoType.Int:    IntOutputs |=  1L << st.Index;        break;
-                        case IoType.Vector: VecOutputs |=  1L << st.Index;        break;
-                    }
-                }
-
-                if (st.IoType == IoType.Fields)
-                {
-                    HasStateStore = true;
+                    case IoType.Flag:   IntOutputs |= (1L << st.Index) << 32; break;
+                    case IoType.Int:    IntOutputs |=  1L << st.Index;        break;
+                    case IoType.Vector: VecOutputs |=  1L << st.Index;        break;
                 }
             }
+            else if (emitter is ILOpCodeStoreState)
+            {
+                HasStateStore = true;
+            }
 
-            IlEmitters.Add(ilEmitter);
+            _emitters.Add(emitter);
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
-            foreach (IILEmit ilEmitter in IlEmitters)
+            foreach (IILEmit ilEmitter in _emitters)
             {
                 ilEmitter.Emit(context);
             }
diff --git a/ChocolArm64/Translation/ILEmitterCtx.cs b/ChocolArm64/Translation/ILEmitterCtx.cs
index c1d1be366e..778b29ade9 100644
--- a/ChocolArm64/Translation/ILEmitterCtx.cs
+++ b/ChocolArm64/Translation/ILEmitterCtx.cs
@@ -14,15 +14,20 @@ namespace ChocolArm64.Translation
 
         private Dictionary<long, ILLabel> _labels;
 
-        private int _blkIndex;
+        private long _subPosition;
+
         private int _opcIndex;
 
-        private Block[]   _graph;
-        private Block     _root;
-        public  Block     CurrBlock => _graph[_blkIndex];
-        public  OpCode64  CurrOp    => _graph[_blkIndex].OpCodes[_opcIndex];
+        private Block _currBlock;
 
-        private ILEmitter _emitter;
+        public Block    CurrBlock => _currBlock;
+        public OpCode64 CurrOp    => _currBlock?.OpCodes[_opcIndex];
+
+        private Dictionary<Block, ILBlock> _visitedBlocks;
+
+        private Queue<Block> _branchTargets;
+
+        private List<ILBlock> _ilBlocks;
 
         private ILBlock _ilBlock;
 
@@ -33,69 +38,61 @@ namespace ChocolArm64.Translation
         //values needed by some functions, since IL doesn't have a swap instruction.
         //You can use any value here as long it doesn't conflict with the indices
         //for the other registers. Any value >= 64 or < 0 will do.
-        private const int Tmp1Index = -1;
-        private const int Tmp2Index = -2;
-        private const int Tmp3Index = -3;
-        private const int Tmp4Index = -4;
-        private const int Tmp5Index = -5;
-        private const int Tmp6Index = -6;
+        private const int IntTmpIndex     = -1;
+        private const int RorTmpIndex     = -2;
+        private const int CmpOptTmp1Index = -3;
+        private const int CmpOptTmp2Index = -4;
+        private const int VecTmp1Index    = -5;
+        private const int VecTmp2Index    = -6;
 
-        public ILEmitterCtx(
-            TranslatorCache cache,
-            Block[]         graph,
-            Block           root,
-            string          subName)
+        public ILEmitterCtx(TranslatorCache cache, Block graph)
         {
-            _cache = cache ?? throw new ArgumentNullException(nameof(cache));
-            _graph = graph ?? throw new ArgumentNullException(nameof(graph));
-            _root  = root  ?? throw new ArgumentNullException(nameof(root));
+            _cache     = cache ?? throw new ArgumentNullException(nameof(cache));
+            _currBlock = graph ?? throw new ArgumentNullException(nameof(graph));
 
             _labels = new Dictionary<long, ILLabel>();
 
-            _emitter = new ILEmitter(graph, root, subName);
+            _visitedBlocks = new Dictionary<Block, ILBlock>();
 
-            _ilBlock = _emitter.GetIlBlock(0);
+            _visitedBlocks.Add(graph, new ILBlock());
 
-            _opcIndex = -1;
+            _branchTargets = new Queue<Block>();
 
-            if (graph.Length == 0 || !AdvanceOpCode())
-            {
-                throw new ArgumentException(nameof(graph));
-            }
+            _ilBlocks = new List<ILBlock>();
+
+            _subPosition = graph.Position;
+
+            ResetBlockState();
+
+            AdvanceOpCode();
         }
 
-        public TranslatedSub GetSubroutine()
+        public ILBlock[] GetILBlocks()
         {
-            return _emitter.GetSubroutine();
+            EmitAllOpCodes();
+
+            return _ilBlocks.ToArray();
         }
 
-        public bool AdvanceOpCode()
+        private void EmitAllOpCodes()
         {
-            if (_opcIndex + 1 == CurrBlock.OpCodes.Count &&
-                _blkIndex + 1 == _graph.Length)
+            do
             {
-                return false;
+                EmitOpCode();
             }
-
-            while (++_opcIndex >= (CurrBlock?.OpCodes.Count ?? 0))
-            {
-                _blkIndex++;
-                _opcIndex = -1;
-
-                _optOpLastFlagSet = null;
-                _optOpLastCompare = null;
-
-                _ilBlock = _emitter.GetIlBlock(_blkIndex);
-            }
-
-            return true;
+            while (AdvanceOpCode());
         }
 
-        public void EmitOpCode()
+        private void EmitOpCode()
         {
+            if (_currBlock == null)
+            {
+                return;
+            }
+
             if (_opcIndex == 0)
             {
-                MarkLabel(GetLabel(CurrBlock.Position));
+                MarkLabel(GetLabel(_currBlock.Position));
 
                 EmitSynchronization();
             }
@@ -109,7 +106,7 @@ namespace ChocolArm64.Translation
         {
             EmitLdarg(TranslatedSub.StateArgIdx);
 
-            EmitLdc_I4(CurrBlock.OpCodes.Count);
+            EmitLdc_I4(_currBlock.OpCodes.Count);
 
             EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.Synchronize));
 
@@ -126,9 +123,86 @@ namespace ChocolArm64.Translation
             MarkLabel(lblContinue);
         }
 
+        private bool AdvanceOpCode()
+        {
+            if (_currBlock == null)
+            {
+                return false;
+            }
+
+            while (++_opcIndex >= _currBlock.OpCodes.Count)
+            {
+                if (!AdvanceBlock())
+                {
+                    return false;
+                }
+
+                ResetBlockState();
+            }
+
+            return true;
+        }
+
+        private bool AdvanceBlock()
+        {
+            if (_currBlock.Branch != null)
+            {
+                if (_visitedBlocks.TryAdd(_currBlock.Branch, _ilBlock.Branch))
+                {
+                    _branchTargets.Enqueue(_currBlock.Branch);
+                }
+            }
+
+            if (_currBlock.Next != null)
+            {
+                if (_visitedBlocks.TryAdd(_currBlock.Next, _ilBlock.Next))
+                {
+                    _currBlock = _currBlock.Next;
+
+                    return true;
+                }
+                else
+                {
+                    Emit(OpCodes.Br, GetLabel(_currBlock.Next.Position));
+                }
+            }
+
+            return _branchTargets.TryDequeue(out _currBlock);
+        }
+
+        private void ResetBlockState()
+        {
+            _ilBlock = _visitedBlocks[_currBlock];
+
+            _ilBlocks.Add(_ilBlock);
+
+            _ilBlock.Next   = GetOrCreateILBlock(_currBlock.Next);
+            _ilBlock.Branch = GetOrCreateILBlock(_currBlock.Branch);
+
+            _opcIndex = -1;
+
+            _optOpLastFlagSet = null;
+            _optOpLastCompare = null;
+        }
+
+        private ILBlock GetOrCreateILBlock(Block block)
+        {
+            if (block == null)
+            {
+                return null;
+            }
+
+            if (_visitedBlocks.TryGetValue(block, out ILBlock ilBlock))
+            {
+                return ilBlock;
+            }
+
+            return new ILBlock();
+        }
+
         public bool TryOptEmitSubroutineCall()
         {
-            if (CurrBlock.Next == null)
+            if (_currBlock.Next == null)
             {
                 return false;
             }
@@ -148,7 +222,7 @@ namespace ChocolArm64.Translation
                 EmitLdarg(index);
             }
 
-            foreach (Register reg in subroutine.Params)
+            foreach (Register reg in subroutine.SubArgs)
             {
                 switch (reg.Type)
                 {
@@ -160,7 +234,7 @@ namespace ChocolArm64.Translation
 
             EmitCall(subroutine.Method);
 
-            subroutine.AddCaller(_root.Position);
+            subroutine.AddCaller(_subPosition);
 
             return true;
         }
@@ -171,11 +245,11 @@ namespace ChocolArm64.Translation
 
             InstEmitAluHelper.EmitDataLoadOpers(this);
 
-            Stloc(Tmp4Index, IoType.Int);
-            Stloc(Tmp3Index, IoType.Int);
+            Stloc(CmpOptTmp2Index, IoType.Int);
+            Stloc(CmpOptTmp1Index, IoType.Int);
         }
 
-        private Dictionary<Cond, System.Reflection.Emit.OpCode> _branchOps = new Dictionary<Cond, System.Reflection.Emit.OpCode>()
+        private Dictionary<Cond, OpCode> _branchOps = new Dictionary<Cond, OpCode>()
         {
             { Cond.Eq,   OpCodes.Beq    },
             { Cond.Ne,   OpCodes.Bne_Un },
@@ -191,15 +265,15 @@ namespace ChocolArm64.Translation
 
         public void EmitCondBranch(ILLabel target, Cond cond)
         {
-            System.Reflection.Emit.OpCode ilOp;
+            OpCode ilOp;
 
             int intCond = (int)cond;
 
             if (_optOpLastCompare != null &&
                 _optOpLastCompare == _optOpLastFlagSet && _branchOps.ContainsKey(cond))
             {
-                Ldloc(Tmp3Index, IoType.Int, _optOpLastCompare.RegisterSize);
-                Ldloc(Tmp4Index, IoType.Int, _optOpLastCompare.RegisterSize);
+                Ldloc(CmpOptTmp1Index, IoType.Int, _optOpLastCompare.RegisterSize);
+                Ldloc(CmpOptTmp2Index, IoType.Int, _optOpLastCompare.RegisterSize);
 
                 ilOp = _branchOps[cond];
             }
@@ -285,11 +359,11 @@ namespace ChocolArm64.Translation
             }
         }
 
-        public void EmitLsl(int amount) => EmitIlShift(amount, OpCodes.Shl);
-        public void EmitLsr(int amount) => EmitIlShift(amount, OpCodes.Shr_Un);
-        public void EmitAsr(int amount) => EmitIlShift(amount, OpCodes.Shr);
+        public void EmitLsl(int amount) => EmitILShift(amount, OpCodes.Shl);
+        public void EmitLsr(int amount) => EmitILShift(amount, OpCodes.Shr_Un);
+        public void EmitAsr(int amount) => EmitILShift(amount, OpCodes.Shr);
 
-        private void EmitIlShift(int amount, System.Reflection.Emit.OpCode ilOp)
+        private void EmitILShift(int amount, OpCode ilOp)
         {
             if (amount > 0)
             {
@@ -303,14 +377,14 @@ namespace ChocolArm64.Translation
         {
             if (amount > 0)
             {
-                Stloc(Tmp2Index, IoType.Int);
-                Ldloc(Tmp2Index, IoType.Int);
+                Stloc(RorTmpIndex, IoType.Int);
+                Ldloc(RorTmpIndex, IoType.Int);
 
                 EmitLdc_I4(amount);
 
                 Emit(OpCodes.Shr_Un);
 
-                Ldloc(Tmp2Index, IoType.Int);
+                Ldloc(RorTmpIndex, IoType.Int);
 
                 EmitLdc_I4(CurrOp.GetBitsCount() - amount);
 
@@ -336,12 +410,12 @@ namespace ChocolArm64.Translation
             _ilBlock.Add(label);
         }
 
-        public void Emit(System.Reflection.Emit.OpCode ilOp)
+        public void Emit(OpCode ilOp)
         {
             _ilBlock.Add(new ILOpCode(ilOp));
         }
 
-        public void Emit(System.Reflection.Emit.OpCode ilOp, ILLabel label)
+        public void Emit(OpCode ilOp, ILLabel label)
         {
             _ilBlock.Add(new ILOpCodeBranch(ilOp, label));
         }
@@ -353,7 +427,7 @@ namespace ChocolArm64.Translation
 
         public void EmitLdarg(int index)
         {
-            _ilBlock.Add(new IlOpCodeLoad(index, IoType.Arg));
+            _ilBlock.Add(new ILOpCodeLoad(index, IoType.Arg));
         }
 
         public void EmitLdintzr(int index)
@@ -380,24 +454,29 @@ namespace ChocolArm64.Translation
             }
         }
 
-        public void EmitLoadState(Block retBlk)
+        public void EmitLoadState()
         {
-            _ilBlock.Add(new IlOpCodeLoad(Array.IndexOf(_graph, retBlk), IoType.Fields));
+            if (_ilBlock.Next == null)
+            {
+                throw new InvalidOperationException("Can't load state for next block, because there's no next block.");
+            }
+
+            _ilBlock.Add(new ILOpCodeLoadState(_ilBlock.Next));
         }
 
         public void EmitStoreState()
         {
-            _ilBlock.Add(new IlOpCodeStore(Array.IndexOf(_graph, CurrBlock), IoType.Fields));
+            _ilBlock.Add(new ILOpCodeStoreState(_ilBlock));
         }
 
-        public void EmitLdtmp() => EmitLdint(Tmp1Index);
-        public void EmitSttmp() => EmitStint(Tmp1Index);
+        public void EmitLdtmp() => EmitLdint(IntTmpIndex);
+        public void EmitSttmp() => EmitStint(IntTmpIndex);
 
-        public void EmitLdvectmp() => EmitLdvec(Tmp5Index);
-        public void EmitStvectmp() => EmitStvec(Tmp5Index);
+        public void EmitLdvectmp() => EmitLdvec(VecTmp1Index);
+        public void EmitStvectmp() => EmitStvec(VecTmp1Index);
 
-        public void EmitLdvectmp2() => EmitLdvec(Tmp6Index);
-        public void EmitStvectmp2() => EmitStvec(Tmp6Index);
+        public void EmitLdvectmp2() => EmitLdvec(VecTmp2Index);
+        public void EmitStvectmp2() => EmitStvec(VecTmp2Index);
 
         public void EmitLdint(int index) => Ldloc(index, IoType.Int);
         public void EmitStint(int index) => Stloc(index, IoType.Int);
@@ -415,17 +494,17 @@ namespace ChocolArm64.Translation
 
         private void Ldloc(int index, IoType ioType)
         {
-            _ilBlock.Add(new IlOpCodeLoad(index, ioType, CurrOp.RegisterSize));
+            _ilBlock.Add(new ILOpCodeLoad(index, ioType, CurrOp.RegisterSize));
         }
 
         private void Ldloc(int index, IoType ioType, RegisterSize registerSize)
         {
-            _ilBlock.Add(new IlOpCodeLoad(index, ioType, registerSize));
+            _ilBlock.Add(new ILOpCodeLoad(index, ioType, registerSize));
         }
 
         private void Stloc(int index, IoType ioType)
         {
-            _ilBlock.Add(new IlOpCodeStore(index, ioType, CurrOp.RegisterSize));
+            _ilBlock.Add(new ILOpCodeStore(index, ioType, CurrOp.RegisterSize));
         }
 
         public void EmitCallPropGet(Type objType, string propName)
@@ -536,7 +615,7 @@ namespace ChocolArm64.Translation
             EmitZnCheck(OpCodes.Clt, (int)PState.NBit);
         }
 
-        private void EmitZnCheck(System.Reflection.Emit.OpCode ilCmpOp, int flag)
+        private void EmitZnCheck(OpCode ilCmpOp, int flag)
         {
             Emit(OpCodes.Dup);
             Emit(OpCodes.Ldc_I4_0);
diff --git a/ChocolArm64/Translation/ILLabel.cs b/ChocolArm64/Translation/ILLabel.cs
index 4f96edccf1..f423a4256c 100644
--- a/ChocolArm64/Translation/ILLabel.cs
+++ b/ChocolArm64/Translation/ILLabel.cs
@@ -8,12 +8,12 @@ namespace ChocolArm64.Translation
 
         private Label _lbl;
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             context.Generator.MarkLabel(GetLabel(context));
         }
 
-        public Label GetLabel(ILEmitter context)
+        public Label GetLabel(ILMethodBuilder context)
         {
             if (!_hasLabel)
             {
diff --git a/ChocolArm64/Translation/ILEmitter.cs b/ChocolArm64/Translation/ILMethodBuilder.cs
similarity index 51%
rename from ChocolArm64/Translation/ILEmitter.cs
rename to ChocolArm64/Translation/ILMethodBuilder.cs
index 543528d716..70d9a2db65 100644
--- a/ChocolArm64/Translation/ILEmitter.cs
+++ b/ChocolArm64/Translation/ILMethodBuilder.cs
@@ -1,4 +1,3 @@
-using ChocolArm64.Decoders;
 using ChocolArm64.State;
 using System;
 using System.Collections.Generic;
@@ -7,7 +6,7 @@ using System.Runtime.Intrinsics;
 
 namespace ChocolArm64.Translation
 {
-    class ILEmitter
+    class ILMethodBuilder
     {
         public LocalAlloc LocalAlloc { get; private set; }
 
@@ -17,70 +16,23 @@ namespace ChocolArm64.Translation
 
         private ILBlock[] _ilBlocks;
 
-        private ILBlock _root;
-
-        private TranslatedSub _subroutine;
-
         private string _subName;
 
         private int _localsCount;
 
-        public ILEmitter(Block[] graph, Block root, string subName)
+        public ILMethodBuilder(ILBlock[] ilBlocks, string subName)
         {
-            _subName = subName;
-
-            _locals = new Dictionary<Register, int>();
-
-            _ilBlocks = new ILBlock[graph.Length];
-
-            ILBlock GetBlock(int index)
-            {
-                if (index < 0 || index >= _ilBlocks.Length)
-                {
-                    return null;
-                }
-
-                if (_ilBlocks[index] == null)
-                {
-                    _ilBlocks[index] = new ILBlock();
-                }
-
-                return _ilBlocks[index];
-            }
-
-            for (int index = 0; index < _ilBlocks.Length; index++)
-            {
-                ILBlock block = GetBlock(index);
-
-                block.Next   = GetBlock(Array.IndexOf(graph, graph[index].Next));
-                block.Branch = GetBlock(Array.IndexOf(graph, graph[index].Branch));
-            }
-
-            _root = _ilBlocks[Array.IndexOf(graph, root)];
+            _ilBlocks = ilBlocks;
+            _subName  = subName;
         }
 
-        public ILBlock GetIlBlock(int index) => _ilBlocks[index];
-
         public TranslatedSub GetSubroutine()
         {
-            LocalAlloc = new LocalAlloc(_ilBlocks, _root);
+            LocalAlloc = new LocalAlloc(_ilBlocks, _ilBlocks[0]);
 
-            InitSubroutine();
-            InitLocals();
+            List<Register> subArgs = new List<Register>();
 
-            foreach (ILBlock ilBlock in _ilBlocks)
-            {
-                ilBlock.Emit(this);
-            }
-
-            return _subroutine;
-        }
-
-        private void InitSubroutine()
-        {
-            List<Register> Params = new List<Register>();
-
-            void SetParams(long inputs, RegisterType baseType)
+            void SetArgs(long inputs, RegisterType baseType)
             {
                 for (int bit = 0; bit < 64; bit++)
                 {
@@ -88,37 +40,43 @@ namespace ChocolArm64.Translation
 
                     if ((inputs & mask) != 0)
                     {
-                        Params.Add(GetRegFromBit(bit, baseType));
+                        subArgs.Add(GetRegFromBit(bit, baseType));
                     }
                 }
             }
 
-            SetParams(LocalAlloc.GetIntInputs(_root), RegisterType.Int);
-            SetParams(LocalAlloc.GetVecInputs(_root), RegisterType.Vector);
+            SetArgs(LocalAlloc.GetIntInputs(_ilBlocks[0]), RegisterType.Int);
+            SetArgs(LocalAlloc.GetVecInputs(_ilBlocks[0]), RegisterType.Vector);
 
-            DynamicMethod mthd = new DynamicMethod(_subName, typeof(long), GetParamTypes(Params));
+            DynamicMethod method = new DynamicMethod(_subName, typeof(long), GetArgumentTypes(subArgs));
 
-            Generator = mthd.GetILGenerator();
+            Generator = method.GetILGenerator();
 
-            _subroutine = new TranslatedSub(mthd, Params);
-        }
+            TranslatedSub subroutine = new TranslatedSub(method, subArgs);
 
-        private void InitLocals()
-        {
-            int paramsStart = TranslatedSub.FixedArgTypes.Length;
+            int argsStart = TranslatedSub.FixedArgTypes.Length;
 
             _locals = new Dictionary<Register, int>();
 
-            for (int index = 0; index < _subroutine.Params.Count; index++)
-            {
-                Register reg = _subroutine.Params[index];
+            _localsCount = 0;
 
-                Generator.EmitLdarg(index + paramsStart);
+            for (int index = 0; index < subroutine.SubArgs.Count; index++)
+            {
+                Register reg = subroutine.SubArgs[index];
+
+                Generator.EmitLdarg(index + argsStart);
                 Generator.EmitStloc(GetLocalIndex(reg));
             }
+
+            foreach (ILBlock ilBlock in _ilBlocks)
+            {
+                ilBlock.Emit(this);
+            }
+
+            return subroutine;
         }
 
-        private Type[] GetParamTypes(IList<Register> Params)
+        private Type[] GetArgumentTypes(IList<Register> Params)
         {
             Type[] fixedArgs = TranslatedSub.FixedArgTypes;
 
@@ -140,7 +98,7 @@ namespace ChocolArm64.Translation
         {
             if (!_locals.TryGetValue(reg, out int index))
             {
-                Generator.DeclareLocal(GetLocalType(reg));
+                Generator.DeclareLocal(GetFieldType(reg.Type));
 
                 index = _localsCount++;
 
@@ -150,9 +108,7 @@ namespace ChocolArm64.Translation
             return index;
         }
 
-        public Type GetLocalType(Register reg) => GetFieldType(reg.Type);
-
-        public Type GetFieldType(RegisterType regType)
+        private static Type GetFieldType(RegisterType regType)
         {
             switch (regType)
             {
@@ -182,7 +138,7 @@ namespace ChocolArm64.Translation
 
         public static bool IsRegIndex(int index)
         {
-            return index >= 0 && index < 32;
+            return (uint)index < 32;
         }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Translation/ILOpCode.cs b/ChocolArm64/Translation/ILOpCode.cs
index eb91639e63..4021603c01 100644
--- a/ChocolArm64/Translation/ILOpCode.cs
+++ b/ChocolArm64/Translation/ILOpCode.cs
@@ -11,7 +11,7 @@ namespace ChocolArm64.Translation
             _ilOp = ilOp;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             context.Generator.Emit(_ilOp);
         }
diff --git a/ChocolArm64/Translation/ILOpCodeBranch.cs b/ChocolArm64/Translation/ILOpCodeBranch.cs
index b0ba23313f..22b80b5d52 100644
--- a/ChocolArm64/Translation/ILOpCodeBranch.cs
+++ b/ChocolArm64/Translation/ILOpCodeBranch.cs
@@ -13,7 +13,7 @@ namespace ChocolArm64.Translation
             _label = label;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             context.Generator.Emit(_ilOp, _label.GetLabel(context));
         }
diff --git a/ChocolArm64/Translation/ILOpCodeCall.cs b/ChocolArm64/Translation/ILOpCodeCall.cs
index 0b591d46ce..8486a791b1 100644
--- a/ChocolArm64/Translation/ILOpCodeCall.cs
+++ b/ChocolArm64/Translation/ILOpCodeCall.cs
@@ -12,7 +12,7 @@ namespace ChocolArm64.Translation
             _mthdInfo = mthdInfo;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             context.Generator.Emit(OpCodes.Call, _mthdInfo);
         }
diff --git a/ChocolArm64/Translation/ILOpCodeConst.cs b/ChocolArm64/Translation/ILOpCodeConst.cs
index 5497eba16f..2aaf8676ee 100644
--- a/ChocolArm64/Translation/ILOpCodeConst.cs
+++ b/ChocolArm64/Translation/ILOpCodeConst.cs
@@ -51,7 +51,7 @@ namespace ChocolArm64.Translation
             _value = new ImmVal { R8 = value };
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             switch (_type)
             {
diff --git a/ChocolArm64/Translation/ILOpCodeLoad.cs b/ChocolArm64/Translation/ILOpCodeLoad.cs
index 9dae10cc4b..c31e06bbd9 100644
--- a/ChocolArm64/Translation/ILOpCodeLoad.cs
+++ b/ChocolArm64/Translation/ILOpCodeLoad.cs
@@ -3,7 +3,7 @@ using System.Reflection.Emit;
 
 namespace ChocolArm64.Translation
 {
-    struct IlOpCodeLoad : IILEmit
+    struct ILOpCodeLoad : IILEmit
     {
         public int Index { get; private set; }
 
@@ -11,55 +11,26 @@ namespace ChocolArm64.Translation
 
         public RegisterSize RegisterSize { get; private set; }
 
-        public IlOpCodeLoad(int index, IoType ioType, RegisterSize registerSize = 0)
+        public ILOpCodeLoad(int index, IoType ioType, RegisterSize registerSize = 0)
         {
             Index        = index;
             IoType       = ioType;
             RegisterSize = registerSize;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             switch (IoType)
             {
                 case IoType.Arg: context.Generator.EmitLdarg(Index); break;
 
-                case IoType.Fields:
-                {
-                    long intInputs = context.LocalAlloc.GetIntInputs(context.GetIlBlock(Index));
-                    long vecInputs = context.LocalAlloc.GetVecInputs(context.GetIlBlock(Index));
-
-                    LoadLocals(context, intInputs, RegisterType.Int);
-                    LoadLocals(context, vecInputs, RegisterType.Vector);
-
-                    break;
-                }
-
                 case IoType.Flag:   EmitLdloc(context, Index, RegisterType.Flag);   break;
                 case IoType.Int:    EmitLdloc(context, Index, RegisterType.Int);    break;
                 case IoType.Vector: EmitLdloc(context, Index, RegisterType.Vector); break;
             }
         }
 
-        private void LoadLocals(ILEmitter context, long inputs, RegisterType baseType)
-        {
-            for (int bit = 0; bit < 64; bit++)
-            {
-                long mask = 1L << bit;
-
-                if ((inputs & mask) != 0)
-                {
-                    Register reg = ILEmitter.GetRegFromBit(bit, baseType);
-
-                    context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
-                    context.Generator.Emit(OpCodes.Ldfld, reg.GetField());
-
-                    context.Generator.EmitStloc(context.GetLocalIndex(reg));
-                }
-            }
-        }
-
-        private void EmitLdloc(ILEmitter context, int index, RegisterType registerType)
+        private void EmitLdloc(ILMethodBuilder context, int index, RegisterType registerType)
         {
             Register reg = new Register(index, registerType);
 
diff --git a/ChocolArm64/Translation/ILOpCodeLoadState.cs b/ChocolArm64/Translation/ILOpCodeLoadState.cs
new file mode 100644
index 0000000000..ddab611019
--- /dev/null
+++ b/ChocolArm64/Translation/ILOpCodeLoadState.cs
@@ -0,0 +1,42 @@
+using ChocolArm64.State;
+using System.Reflection.Emit;
+
+namespace ChocolArm64.Translation
+{
+    struct ILOpCodeLoadState : IILEmit
+    {
+        private ILBlock _block;
+
+        public ILOpCodeLoadState(ILBlock block)
+        {
+            _block = block;
+        }
+
+        public void Emit(ILMethodBuilder context)
+        {
+            long intInputs = context.LocalAlloc.GetIntInputs(_block);
+            long vecInputs = context.LocalAlloc.GetVecInputs(_block);
+
+            LoadLocals(context, intInputs, RegisterType.Int);
+            LoadLocals(context, vecInputs, RegisterType.Vector);
+        }
+
+        private void LoadLocals(ILMethodBuilder context, long inputs, RegisterType baseType)
+        {
+            for (int bit = 0; bit < 64; bit++)
+            {
+                long mask = 1L << bit;
+
+                if ((inputs & mask) != 0)
+                {
+                    Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
+
+                    context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
+                    context.Generator.Emit(OpCodes.Ldfld, reg.GetField());
+
+                    context.Generator.EmitStloc(context.GetLocalIndex(reg));
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ChocolArm64/Translation/ILOpCodeLog.cs b/ChocolArm64/Translation/ILOpCodeLog.cs
index 2c77021b10..ebb042b596 100644
--- a/ChocolArm64/Translation/ILOpCodeLog.cs
+++ b/ChocolArm64/Translation/ILOpCodeLog.cs
@@ -9,7 +9,7 @@ namespace ChocolArm64.Translation
             _text = text;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             context.Generator.EmitWriteLine(_text);
         }
diff --git a/ChocolArm64/Translation/ILOpCodeStore.cs b/ChocolArm64/Translation/ILOpCodeStore.cs
index 41326fe127..17a6259c6f 100644
--- a/ChocolArm64/Translation/ILOpCodeStore.cs
+++ b/ChocolArm64/Translation/ILOpCodeStore.cs
@@ -3,7 +3,7 @@ using System.Reflection.Emit;
 
 namespace ChocolArm64.Translation
 {
-    struct IlOpCodeStore : IILEmit
+    struct ILOpCodeStore : IILEmit
     {
         public int Index { get; private set; }
 
@@ -11,55 +11,26 @@ namespace ChocolArm64.Translation
 
         public RegisterSize RegisterSize { get; private set; }
 
-        public IlOpCodeStore(int index, IoType ioType, RegisterSize registerSize = 0)
+        public ILOpCodeStore(int index, IoType ioType, RegisterSize registerSize = 0)
         {
             Index        = index;
             IoType       = ioType;
             RegisterSize = registerSize;
         }
 
-        public void Emit(ILEmitter context)
+        public void Emit(ILMethodBuilder context)
         {
             switch (IoType)
             {
                 case IoType.Arg: context.Generator.EmitStarg(Index); break;
 
-                case IoType.Fields:
-                {
-                    long intOutputs = context.LocalAlloc.GetIntOutputs(context.GetIlBlock(Index));
-                    long vecOutputs = context.LocalAlloc.GetVecOutputs(context.GetIlBlock(Index));
-
-                    StoreLocals(context, intOutputs, RegisterType.Int);
-                    StoreLocals(context, vecOutputs, RegisterType.Vector);
-                    
-                    break;
-                }
-
                 case IoType.Flag:   EmitStloc(context, Index, RegisterType.Flag);   break;
                 case IoType.Int:    EmitStloc(context, Index, RegisterType.Int);    break;
                 case IoType.Vector: EmitStloc(context, Index, RegisterType.Vector); break;
             }
         }
 
-        private void StoreLocals(ILEmitter context, long outputs, RegisterType baseType)
-        {
-            for (int bit = 0; bit < 64; bit++)
-            {
-                long mask = 1L << bit;
-
-                if ((outputs & mask) != 0)
-                {
-                    Register reg = ILEmitter.GetRegFromBit(bit, baseType);
-
-                    context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
-                    context.Generator.EmitLdloc(context.GetLocalIndex(reg));
-
-                    context.Generator.Emit(OpCodes.Stfld, reg.GetField());
-                }
-            }
-        }
-
-        private void EmitStloc(ILEmitter context, int index, RegisterType registerType)
+        private void EmitStloc(ILMethodBuilder context, int index, RegisterType registerType)
         {
             Register reg = new Register(index, registerType);
 
diff --git a/ChocolArm64/Translation/ILOpCodeStoreState.cs b/ChocolArm64/Translation/ILOpCodeStoreState.cs
new file mode 100644
index 0000000000..458e9eda43
--- /dev/null
+++ b/ChocolArm64/Translation/ILOpCodeStoreState.cs
@@ -0,0 +1,42 @@
+using ChocolArm64.State;
+using System.Reflection.Emit;
+
+namespace ChocolArm64.Translation
+{
+    struct ILOpCodeStoreState : IILEmit
+    {
+        private ILBlock _block;
+
+        public ILOpCodeStoreState(ILBlock block)
+        {
+            _block = block;
+        }
+
+        public void Emit(ILMethodBuilder context)
+        {
+            long intOutputs = context.LocalAlloc.GetIntOutputs(_block);
+            long vecOutputs = context.LocalAlloc.GetVecOutputs(_block);
+
+            StoreLocals(context, intOutputs, RegisterType.Int);
+            StoreLocals(context, vecOutputs, RegisterType.Vector);
+        }
+
+        private void StoreLocals(ILMethodBuilder context, long outputs, RegisterType baseType)
+        {
+            for (int bit = 0; bit < 64; bit++)
+            {
+                long mask = 1L << bit;
+
+                if ((outputs & mask) != 0)
+                {
+                    Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
+
+                    context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
+                    context.Generator.EmitLdloc(context.GetLocalIndex(reg));
+
+                    context.Generator.Emit(OpCodes.Stfld, reg.GetField());
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ChocolArm64/Translation/IoType.cs b/ChocolArm64/Translation/IoType.cs
index 290b159fc5..c7710e0c67 100644
--- a/ChocolArm64/Translation/IoType.cs
+++ b/ChocolArm64/Translation/IoType.cs
@@ -1,15 +1,10 @@
-using System;
-
 namespace ChocolArm64.Translation
 {
-    [Flags]
     enum IoType
     {
         Arg,
-        Fields,
         Flag,
         Int,
-        Float,
         Vector
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/Translation/LocalAlloc.cs b/ChocolArm64/Translation/LocalAlloc.cs
index 8237bd5454..763be6190d 100644
--- a/ChocolArm64/Translation/LocalAlloc.cs
+++ b/ChocolArm64/Translation/LocalAlloc.cs
@@ -1,3 +1,4 @@
+using System;
 using System.Collections.Generic;
 
 namespace ChocolArm64.Translation
@@ -65,11 +66,41 @@ namespace ChocolArm64.Translation
             public long VecInputs;
             public long IntOutputs;
             public long VecOutputs;
+
+            public override bool Equals(object obj)
+            {
+                if (!(obj is BlockIo other))
+                {
+                    return false;
+                }
+
+                return other.Block      == Block      &&
+                       other.Entry      == Entry      &&
+                       other.IntInputs  == IntInputs  &&
+                       other.VecInputs  == VecInputs  &&
+                       other.IntOutputs == IntOutputs &&
+                       other.VecOutputs == VecOutputs;
+            }
+
+            public override int GetHashCode()
+            {
+                return HashCode.Combine(Block, Entry, IntInputs, VecInputs, IntOutputs, VecOutputs);
+            }
+
+            public static bool operator ==(BlockIo lhs, BlockIo rhs)
+            {
+                return lhs.Equals(rhs);
+            }
+
+            public static bool operator !=(BlockIo lhs, BlockIo rhs)
+            {
+                return !(lhs == rhs);
+            }
         }
 
         private const int MaxOptGraphLength = 40;
 
-        public LocalAlloc(ILBlock[] graph, ILBlock root)
+        public LocalAlloc(ILBlock[] graph, ILBlock entry)
         {
             _intPaths = new Dictionary<ILBlock, PathIo>();
             _vecPaths = new Dictionary<ILBlock, PathIo>();
@@ -77,7 +108,7 @@ namespace ChocolArm64.Translation
             if (graph.Length > 1 &&
                 graph.Length < MaxOptGraphLength)
             {
-                InitializeOptimal(graph, root);
+                InitializeOptimal(graph, entry);
             }
             else
             {
@@ -85,7 +116,7 @@ namespace ChocolArm64.Translation
             }
         }
 
-        private void InitializeOptimal(ILBlock[] graph, ILBlock root)
+        private void InitializeOptimal(ILBlock[] graph, ILBlock entry)
         {
             //This will go through all possible paths on the graph,
             //and store all inputs/outputs for each block. A register
@@ -93,7 +124,7 @@ namespace ChocolArm64.Translation
             //When a block can be reached by more than one path, then the
             //output from all paths needs to be set for this block, and
             //only outputs present in all of the parent blocks can be considered
-            //when doing input elimination. Each block chain have a root, that's where
+            //when doing input elimination. Each block chain have a entry, that's where
             //the code starts executing. They are present on the subroutine start point,
             //and on call return points too (address written to X30 by BL).
             HashSet<BlockIo> visited = new HashSet<BlockIo>();
@@ -112,8 +143,8 @@ namespace ChocolArm64.Translation
 
             Enqueue(new BlockIo()
             {
-                Block = root,
-                Entry = root
+                Block = entry,
+                Entry = entry
             });
 
             while (unvisited.Count > 0)
@@ -146,22 +177,22 @@ namespace ChocolArm64.Translation
 
                 void EnqueueFromCurrent(ILBlock block, bool retTarget)
                 {
-                    BlockIo blkIO = new BlockIo() { Block = block };
+                    BlockIo blockIo = new BlockIo() { Block = block };
 
                     if (retTarget)
                     {
-                        blkIO.Entry = block;
+                        blockIo.Entry = block;
                     }
                     else
                     {
-                        blkIO.Entry      = current.Entry;
-                        blkIO.IntInputs  = current.IntInputs;
-                        blkIO.VecInputs  = current.VecInputs;
-                        blkIO.IntOutputs = current.IntOutputs;
-                        blkIO.VecOutputs = current.VecOutputs;
+                        blockIo.Entry      = current.Entry;
+                        blockIo.IntInputs  = current.IntInputs;
+                        blockIo.VecInputs  = current.VecInputs;
+                        blockIo.IntOutputs = current.IntOutputs;
+                        blockIo.VecOutputs = current.VecOutputs;
                     }
 
-                    Enqueue(blkIO);
+                    Enqueue(blockIo);
                 }
 
                 if (current.Block.Next != null)
@@ -179,7 +210,7 @@ namespace ChocolArm64.Translation
         private void InitializeFast(ILBlock[] graph)
         {
             //This is WAY faster than InitializeOptimal, but results in
-            //uneeded loads and stores, so the resulting code will be slower.
+            //unneeded loads and stores, so the resulting code will be slower.
             long intInputs = 0, intOutputs = 0;
             long vecInputs = 0, vecOutputs = 0;
 
diff --git a/ChocolArm64/Translator.cs b/ChocolArm64/Translator.cs
index 3bf06dc469..47a05ba2c5 100644
--- a/ChocolArm64/Translator.cs
+++ b/ChocolArm64/Translator.cs
@@ -83,47 +83,45 @@ namespace ChocolArm64
         {
             Block block = Decoder.DecodeBasicBlock(state, memory, position);
 
-            Block[] graph = new Block[] { block };
+            ILEmitterCtx context = new ILEmitterCtx(_cache, block);
 
             string subName = GetSubroutineName(position);
 
-            ILEmitterCtx context = new ILEmitterCtx(_cache, graph, block, subName);
+            ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName);
 
-            do
-            {
-                context.EmitOpCode();
-            }
-            while (context.AdvanceOpCode());
-
-            TranslatedSub subroutine = context.GetSubroutine();
+            TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
 
             subroutine.SetType(TranslatedSubType.SubTier0);
 
             _cache.AddOrUpdate(position, subroutine, block.OpCodes.Count);
 
-            OpCode64 lastOp = block.GetLastOp();
-
             return subroutine;
         }
 
         private void TranslateTier1(CpuThreadState state, MemoryManager memory, long position)
         {
-            (Block[] graph, Block root) = Decoder.DecodeSubroutine(_cache, state, memory, position);
+            Block graph = Decoder.DecodeSubroutine(_cache, state, memory, position);
+
+            ILEmitterCtx context = new ILEmitterCtx(_cache, graph);
+
+            ILBlock[] ilBlocks = context.GetILBlocks();
 
             string subName = GetSubroutineName(position);
 
-            ILEmitterCtx context = new ILEmitterCtx(_cache, graph, root, subName);
+            ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName);
 
-            if (context.CurrBlock.Position != position)
+            TranslatedSub subroutine = ilMthdBuilder.GetSubroutine();
+
+            subroutine.SetType(TranslatedSubType.SubTier1);
+
+            int ilOpCount = 0;
+
+            foreach (ILBlock ilBlock in ilBlocks)
             {
-                context.Emit(OpCodes.Br, context.GetLabel(position));
+                ilOpCount += ilBlock.Count;
             }
 
-            do
-            {
-                context.EmitOpCode();
-            }
-            while (context.AdvanceOpCode());
+            _cache.AddOrUpdate(position, subroutine, ilOpCount);
 
             //Mark all methods that calls this method for ReJiting,
             //since we can now call it directly which is faster.
@@ -137,29 +135,11 @@ namespace ChocolArm64
                     }
                 }
             }
-
-            TranslatedSub subroutine = context.GetSubroutine();
-
-            subroutine.SetType(TranslatedSubType.SubTier1);
-
-            _cache.AddOrUpdate(position, subroutine, GetGraphInstCount(graph));
         }
 
         private string GetSubroutineName(long position)
         {
             return $"Sub{position:x16}";
         }
-
-        private int GetGraphInstCount(Block[] graph)
-        {
-            int size = 0;
-
-            foreach (Block block in graph)
-            {
-                size += block.OpCodes.Count;
-            }
-
-            return size;
-        }
     }
 }
\ No newline at end of file
diff --git a/ChocolArm64/TranslatorCache.cs b/ChocolArm64/TranslatorCache.cs
index 7d65035777..93da555ec8 100644
--- a/ChocolArm64/TranslatorCache.cs
+++ b/ChocolArm64/TranslatorCache.cs
@@ -9,8 +9,8 @@ namespace ChocolArm64
 {
     class TranslatorCache
     {
-        //Maximum size of the cache, in bytes, measured in ARM code size.
-        private const int MaxTotalSize = 4 * 1024 * 256;
+        //Maximum size of the cache, the unit used is completely arbitrary.
+        private const int MaxTotalSize = 0x800000;
 
         //Minimum time required in milliseconds for a method to be eligible for deletion.
         private const int MinTimeDelta = 2 * 60000;
@@ -63,10 +63,10 @@ namespace ChocolArm64
         {
             ClearCacheIfNeeded();
 
-            _totalSize += size;
-
             lock (_sortedCache)
             {
+                _totalSize += size;
+
                 LinkedListNode<long> node = _sortedCache.AddLast(position);
 
                 CacheBucket newBucket = new CacheBucket(subroutine, node, size);
@@ -98,11 +98,18 @@ namespace ChocolArm64
                     {
                         try
                         {
-                            bucket.CallCount = 0;
+                            //The bucket value on the dictionary may have changed between the
+                            //time we get the value from the dictionary, and we acquire the
+                            //lock. So we need to ensure we are working with the latest value,
+                            //we can do that by getting the value again, inside the lock.
+                            if (_cache.TryGetValue(position, out CacheBucket latestBucket))
+                            {
+                                latestBucket.CallCount = 0;
 
-                            _sortedCache.Remove(bucket.Node);
+                                _sortedCache.Remove(latestBucket.Node);
 
-                            bucket.UpdateNode(_sortedCache.AddLast(position));
+                                latestBucket.UpdateNode(_sortedCache.AddLast(position));
+                            }
                         }
                         finally
                         {