From 36e8e074c90f11480389560e3f019a161f82efbe Mon Sep 17 00:00:00 2001 From: gdkchan 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 db43ac4fe..1d4f397ac 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 visited = new Dictionary(); Dictionary visitedEnd = new Dictionary(); @@ -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 5f094572e..b46fef4f7 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 f24c7f37b..bed840b8e 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 a36f94ca8..24cee056c 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 6f4331991..2e674a54c 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 e2aae96de..8e91f15ae 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 d085a8237..d1a5a2dbe 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 edaa4970a..d9f322eac 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 3dd210fbd..2eb734aa3 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 f96978547..7dbd92472 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 6c68a3af2..eacd59409 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 3ef6a8c6e..37ee504d2 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 0748ef43f..83297c414 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 07ec8ab73..1b0ead331 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 5f6a7a4ca..cad431034 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 8325a3978..9444397ae 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 0e9f7cb01..758bf2120 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 96e45b3f7..96f782df6 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 fe8722af3..fd6146b37 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 68d9100b3..eacb53361 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 9b9b993a7..89510fbe3 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<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>101110000xxxxx00011101<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>00111110011101<1xxxxx110011xxxxxxxxxx", InstEmit.Fmls_V, typeof(OpCodeSimdReg64)); - SetA64("0>00111111011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmul_V, typeof(OpCodeSimdReg64)); - SetA64("0>00111110011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_V, typeof(OpCodeSimdReg64)); - SetA64("0>10111111011101<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<>>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<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>101110000xxxxx00011101<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>00111110011101<1xxxxx110011xxxxxxxxxx", InstEmit.Fmls_V, typeof(OpCodeSimdReg64)); + SetA64("0>00111111011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmul_V, typeof(OpCodeSimdReg64)); + SetA64("0>00111110011100<1xxxxx110111xxxxxxxxxx", InstEmit.Fmulx_V, typeof(OpCodeSimdReg64)); + SetA64("0>10111111011101<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<>>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 8b3ec3f01..653abcca9 100644 --- a/ChocolArm64/TranslatedSub.cs +++ b/ChocolArm64/TranslatedSub.cs @@ -24,7 +24,7 @@ namespace ChocolArm64 public DynamicMethod Method { get; private set; } - public ReadOnlyCollection Params { get; private set; } + public ReadOnlyCollection SubArgs { get; private set; } private HashSet _callers; @@ -34,20 +34,10 @@ namespace ChocolArm64 private bool _needsReJit; - public TranslatedSub(DynamicMethod method, List Params) + public TranslatedSub(DynamicMethod method, List 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(); @@ -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 3c3925ee0..320520eba 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 f931e9922..37f7558a7 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 d51e8d9ec..136579012 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 IlEmitters { get; private set; } + private List _emitters; + + public int Count => _emitters.Count; public ILBlock Next { get; set; } public ILBlock Branch { get; set; } public ILBlock() { - IlEmitters = new List(); + _emitters = new List(); } - 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 c1d1be366..778b29ade 100644 --- a/ChocolArm64/Translation/ILEmitterCtx.cs +++ b/ChocolArm64/Translation/ILEmitterCtx.cs @@ -14,15 +14,20 @@ namespace ChocolArm64.Translation private Dictionary _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 _visitedBlocks; + + private Queue _branchTargets; + + private List _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(); - _emitter = new ILEmitter(graph, root, subName); + _visitedBlocks = new Dictionary(); - _ilBlock = _emitter.GetIlBlock(0); + _visitedBlocks.Add(graph, new ILBlock()); - _opcIndex = -1; + _branchTargets = new Queue(); - if (graph.Length == 0 || !AdvanceOpCode()) - { - throw new ArgumentException(nameof(graph)); - } + _ilBlocks = new List(); + + _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 _branchOps = new Dictionary() + private Dictionary _branchOps = new Dictionary() { { 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 4f96edccf..f423a4256 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 543528d71..70d9a2db6 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(); - - _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 subArgs = new List(); - foreach (ILBlock ilBlock in _ilBlocks) - { - ilBlock.Emit(this); - } - - return _subroutine; - } - - private void InitSubroutine() - { - List Params = new List(); - - 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(); - 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 Params) + private Type[] GetArgumentTypes(IList 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 eb91639e6..4021603c0 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 b0ba23313..22b80b5d5 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 0b591d46c..8486a791b 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 5497eba16..2aaf8676e 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 9dae10cc4..c31e06bbd 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 000000000..ddab61101 --- /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 2c77021b1..ebb042b59 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 41326fe12..17a6259c6 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 000000000..458e9eda4 --- /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 290b159fc..c7710e0c6 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 8237bd545..763be6190 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(); _vecPaths = new Dictionary(); @@ -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 visited = new HashSet(); @@ -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 3bf06dc46..47a05ba2c 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 7d6503577..93da555ec 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 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 {