Переглянути джерело

Adjust naming conventions for Ryujinx and ChocolArm64 projects (#484)

* Change naming convention for Ryujinx project

* Change naming convention for ChocolArm64 project

* Fix NaN

* Remove unneeded this. from Ryujinx project

* Adjust naming from new PRs

* Name changes based on feedback

* How did this get removed?

* Rebasing fix

* Change FP enum case

* Remove prefix from ChocolArm64 classes - Part 1

* Remove prefix from ChocolArm64 classes - Part 2

* Fix alignment from last commit's renaming

* Rename namespaces

* Rename stragglers

* Fix alignment

* Rename OpCode class

* Missed a few

* Adjust alignment
Alex Barney 7 роки тому
батько
коміт
9cb57fb4bb
100 змінених файлів з 1013 додано та 2896 видалено
  1. 0 49
      ChocolArm64/ABitUtils.cs
  2. 0 713
      ChocolArm64/AOpCodeTable.cs
  3. 0 18
      ChocolArm64/AOptimizations.cs
  4. 0 150
      ChocolArm64/ATranslatedSub.cs
  5. 0 165
      ChocolArm64/ATranslator.cs
  6. 0 165
      ChocolArm64/ATranslatorCache.cs
  7. 49 0
      ChocolArm64/BitUtils.cs
  8. 13 13
      ChocolArm64/CpuThread.cs
  9. 0 35
      ChocolArm64/Decoder/ABlock.cs
  10. 0 22
      ChocolArm64/Decoder/ACond.cs
  11. 0 239
      ChocolArm64/Decoder/ADecoder.cs
  12. 0 107
      ChocolArm64/Decoder/ADecoderHelper.cs
  13. 0 40
      ChocolArm64/Decoder/AOpCode.cs
  14. 0 18
      ChocolArm64/Decoder/AOpCodeAdr.cs
  15. 0 24
      ChocolArm64/Decoder/AOpCodeAlu.cs
  16. 0 39
      ChocolArm64/Decoder/AOpCodeAluImm.cs
  17. 0 29
      ChocolArm64/Decoder/AOpCodeAluRs.cs
  18. 0 19
      ChocolArm64/Decoder/AOpCodeAluRx.cs
  19. 0 11
      ChocolArm64/Decoder/AOpCodeBImm.cs
  20. 0 12
      ChocolArm64/Decoder/AOpCodeBImmAl.cs
  21. 0 21
      ChocolArm64/Decoder/AOpCodeBImmCmp.cs
  22. 0 25
      ChocolArm64/Decoder/AOpCodeBImmCond.cs
  23. 0 20
      ChocolArm64/Decoder/AOpCodeBImmTest.cs
  24. 0 24
      ChocolArm64/Decoder/AOpCodeBReg.cs
  25. 0 29
      ChocolArm64/Decoder/AOpCodeBfm.cs
  26. 0 31
      ChocolArm64/Decoder/AOpCodeCcmp.cs
  27. 0 11
      ChocolArm64/Decoder/AOpCodeCcmpImm.cs
  28. 0 15
      ChocolArm64/Decoder/AOpCodeCcmpReg.cs
  29. 0 17
      ChocolArm64/Decoder/AOpCodeCsel.cs
  30. 0 14
      ChocolArm64/Decoder/AOpCodeException.cs
  31. 0 19
      ChocolArm64/Decoder/AOpCodeMem.cs
  32. 0 16
      ChocolArm64/Decoder/AOpCodeMemEx.cs
  33. 0 25
      ChocolArm64/Decoder/AOpCodeMemPair.cs
  34. 0 20
      ChocolArm64/Decoder/AOpCodeMemReg.cs
  35. 0 36
      ChocolArm64/Decoder/AOpCodeMov.cs
  36. 0 16
      ChocolArm64/Decoder/AOpCodeMul.cs
  37. 0 25
      ChocolArm64/Decoder/AOpCodeSimd.cs
  38. 0 31
      ChocolArm64/Decoder/AOpCodeSimdCvt.cs
  39. 0 14
      ChocolArm64/Decoder/AOpCodeSimdExt.cs
  40. 0 17
      ChocolArm64/Decoder/AOpCodeSimdFcond.cs
  41. 0 33
      ChocolArm64/Decoder/AOpCodeSimdFmov.cs
  42. 0 101
      ChocolArm64/Decoder/AOpCodeSimdImm.cs
  43. 0 36
      ChocolArm64/Decoder/AOpCodeSimdIns.cs
  44. 0 19
      ChocolArm64/Decoder/AOpCodeSimdMemImm.cs
  45. 0 31
      ChocolArm64/Decoder/AOpCodeSimdMemLit.cs
  46. 0 16
      ChocolArm64/Decoder/AOpCodeSimdMemPair.cs
  47. 0 14
      ChocolArm64/Decoder/AOpCodeSimdMemReg.cs
  48. 0 98
      ChocolArm64/Decoder/AOpCodeSimdMemSs.cs
  49. 0 18
      ChocolArm64/Decoder/AOpCodeSimdReg.cs
  50. 0 31
      ChocolArm64/Decoder/AOpCodeSimdRegElem.cs
  51. 0 33
      ChocolArm64/Decoder/AOpCodeSimdRegElemF.cs
  52. 0 16
      ChocolArm64/Decoder/AOpCodeSimdShImm.cs
  53. 0 12
      ChocolArm64/Decoder/AOpCodeSimdTbl.cs
  54. 0 24
      ChocolArm64/Decoder/AOpCodeSystem.cs
  55. 0 13
      ChocolArm64/Decoder/IAOpCode.cs
  56. 0 10
      ChocolArm64/Decoder/IAOpCodeAlu.cs
  57. 0 7
      ChocolArm64/Decoder/IAOpCodeAluImm.cs
  58. 0 10
      ChocolArm64/Decoder/IAOpCodeAluRs.cs
  59. 0 10
      ChocolArm64/Decoder/IAOpCodeAluRx.cs
  60. 0 7
      ChocolArm64/Decoder/IAOpCodeCond.cs
  61. 0 7
      ChocolArm64/Decoder/IAOpCodeSimd.cs
  62. 0 15
      ChocolArm64/Decoder32/A32OpCode.cs
  63. 0 16
      ChocolArm64/Decoder32/A32OpCodeBImmAl.cs
  64. 35 0
      ChocolArm64/Decoders/Block.cs
  65. 22 0
      ChocolArm64/Decoders/Cond.cs
  66. 2 2
      ChocolArm64/Decoders/DataOp.cs
  67. 239 0
      ChocolArm64/Decoders/Decoder.cs
  68. 107 0
      ChocolArm64/Decoders/DecoderHelper.cs
  69. 13 0
      ChocolArm64/Decoders/IOpCode64.cs
  70. 10 0
      ChocolArm64/Decoders/IOpCodeAlu64.cs
  71. 7 0
      ChocolArm64/Decoders/IOpCodeAluImm64.cs
  72. 10 0
      ChocolArm64/Decoders/IOpCodeAluRs64.cs
  73. 10 0
      ChocolArm64/Decoders/IOpCodeAluRx64.cs
  74. 7 0
      ChocolArm64/Decoders/IOpCodeCond64.cs
  75. 2 2
      ChocolArm64/Decoders/IOpCodeLit64.cs
  76. 7 0
      ChocolArm64/Decoders/IOpCodeSimd64.cs
  77. 2 2
      ChocolArm64/Decoders/IntType.cs
  78. 40 0
      ChocolArm64/Decoders/OpCode64.cs
  79. 18 0
      ChocolArm64/Decoders/OpCodeAdr64.cs
  80. 24 0
      ChocolArm64/Decoders/OpCodeAlu64.cs
  81. 39 0
      ChocolArm64/Decoders/OpCodeAluImm64.cs
  82. 29 0
      ChocolArm64/Decoders/OpCodeAluRs64.cs
  83. 19 0
      ChocolArm64/Decoders/OpCodeAluRx64.cs
  84. 11 0
      ChocolArm64/Decoders/OpCodeBImm64.cs
  85. 12 0
      ChocolArm64/Decoders/OpCodeBImmAl64.cs
  86. 21 0
      ChocolArm64/Decoders/OpCodeBImmCmp64.cs
  87. 25 0
      ChocolArm64/Decoders/OpCodeBImmCond64.cs
  88. 20 0
      ChocolArm64/Decoders/OpCodeBImmTest64.cs
  89. 24 0
      ChocolArm64/Decoders/OpCodeBReg64.cs
  90. 29 0
      ChocolArm64/Decoders/OpCodeBfm64.cs
  91. 31 0
      ChocolArm64/Decoders/OpCodeCcmp64.cs
  92. 11 0
      ChocolArm64/Decoders/OpCodeCcmpImm64.cs
  93. 15 0
      ChocolArm64/Decoders/OpCodeCcmpReg64.cs
  94. 17 0
      ChocolArm64/Decoders/OpCodeCsel64.cs
  95. 14 0
      ChocolArm64/Decoders/OpCodeException64.cs
  96. 19 0
      ChocolArm64/Decoders/OpCodeMem64.cs
  97. 16 0
      ChocolArm64/Decoders/OpCodeMemEx64.cs
  98. 12 12
      ChocolArm64/Decoders/OpCodeMemImm64.cs
  99. 7 7
      ChocolArm64/Decoders/OpCodeMemLit64.cs
  100. 25 0
      ChocolArm64/Decoders/OpCodeMemPair64.cs

+ 0 - 49
ChocolArm64/ABitUtils.cs

@@ -1,49 +0,0 @@
-namespace ChocolArm64
-{
-    static class ABitUtils
-    {
-        public static int HighestBitSet32(int Value)
-        {
-            for (int Bit = 31; Bit >= 0; Bit--)
-            {
-                if (((Value >> Bit) & 1) != 0)
-                {
-                    return Bit;
-                }
-            }
-
-            return -1;
-        }
-
-        private static readonly sbyte[] HbsNibbleTbl = { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
-
-        public static int HighestBitSetNibble(int Value) => HbsNibbleTbl[Value & 0b1111];
-
-        public static long Replicate(long Bits, int Size)
-        {
-            long Output = 0;
-
-            for (int Bit = 0; Bit < 64; Bit += Size)
-            {
-                Output |= Bits << Bit;
-            }
-
-            return Output;
-        }
-
-        public static long FillWithOnes(int Bits)
-        {
-            return Bits == 64 ? -1L : (1L << Bits) - 1;
-        }
-
-        public static long RotateRight(long Bits, int Shift, int Size)
-        {
-            return (long)RotateRight((ulong)Bits, Shift, Size);
-        }
-
-        public static ulong RotateRight(ulong Bits, int Shift, int Size)
-        {
-            return (Bits >> Shift) | (Bits << (Size - Shift));
-        }
-    }
-}

+ 0 - 713
ChocolArm64/AOpCodeTable.cs

@@ -1,713 +0,0 @@
-using ChocolArm64.Decoder;
-using ChocolArm64.Decoder32;
-using ChocolArm64.Instruction;
-using ChocolArm64.Instruction32;
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-
-namespace ChocolArm64
-{
-    static class AOpCodeTable
-    {
-        static AOpCodeTable()
-        {
-#region "OpCode Table (AArch32)"
-            //Integer
-            SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.B,      typeof(A32OpCodeBImmAl));
-            SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Bl,     typeof(A32OpCodeBImmAl));
-            SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Blx,    typeof(A32OpCodeBImmAl));
-#endregion
-
-#region "OpCode Table (AArch64)"
-            //Integer
-            SetA64("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc,           typeof(AOpCodeAluRs));
-            SetA64("x0111010000xxxxx000000xxxxxxxxxx", AInstEmit.Adcs,          typeof(AOpCodeAluRs));
-            SetA64("x00100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add,           typeof(AOpCodeAluImm));
-            SetA64("00001011<<0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Add,           typeof(AOpCodeAluRs));
-            SetA64("10001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add,           typeof(AOpCodeAluRs));
-            SetA64("x0001011001xxxxxxxx0xxxxxxxxxxxx", AInstEmit.Add,           typeof(AOpCodeAluRx));
-            SetA64("x0001011001xxxxxxxx100xxxxxxxxxx", AInstEmit.Add,           typeof(AOpCodeAluRx));
-            SetA64("x01100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds,          typeof(AOpCodeAluImm));
-            SetA64("00101011<<0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Adds,          typeof(AOpCodeAluRs));
-            SetA64("10101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds,          typeof(AOpCodeAluRs));
-            SetA64("x0101011001xxxxxxxx0xxxxxxxxxxxx", AInstEmit.Adds,          typeof(AOpCodeAluRx));
-            SetA64("x0101011001xxxxxxxx100xxxxxxxxxx", AInstEmit.Adds,          typeof(AOpCodeAluRx));
-            SetA64("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adr,           typeof(AOpCodeAdr));
-            SetA64("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adrp,          typeof(AOpCodeAdr));
-            SetA64("0001001000xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.And,           typeof(AOpCodeAluImm));
-            SetA64("100100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.And,           typeof(AOpCodeAluImm));
-            SetA64("00001010xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.And,           typeof(AOpCodeAluRs));
-            SetA64("10001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.And,           typeof(AOpCodeAluRs));
-            SetA64("0111001000xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ands,          typeof(AOpCodeAluImm));
-            SetA64("111100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ands,          typeof(AOpCodeAluImm));
-            SetA64("01101010xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Ands,          typeof(AOpCodeAluRs));
-            SetA64("11101010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ands,          typeof(AOpCodeAluRs));
-            SetA64("x0011010110xxxxx001010xxxxxxxxxx", AInstEmit.Asrv,          typeof(AOpCodeAluRs));
-            SetA64("000101xxxxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.B,             typeof(AOpCodeBImmAl));
-            SetA64("01010100xxxxxxxxxxxxxxxxxxx0xxxx", AInstEmit.B_Cond,        typeof(AOpCodeBImmCond));
-            SetA64("00110011000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Bfm,           typeof(AOpCodeBfm));
-            SetA64("1011001101xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Bfm,           typeof(AOpCodeBfm));
-            SetA64("00001010xx1xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Bic,           typeof(AOpCodeAluRs));
-            SetA64("10001010xx1xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Bic,           typeof(AOpCodeAluRs));
-            SetA64("01101010xx1xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Bics,          typeof(AOpCodeAluRs));
-            SetA64("11101010xx1xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Bics,          typeof(AOpCodeAluRs));
-            SetA64("100101xxxxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Bl,            typeof(AOpCodeBImmAl));
-            SetA64("1101011000111111000000xxxxx00000", AInstEmit.Blr,           typeof(AOpCodeBReg));
-            SetA64("1101011000011111000000xxxxx00000", AInstEmit.Br,            typeof(AOpCodeBReg));
-            SetA64("11010100001xxxxxxxxxxxxxxxx00000", AInstEmit.Brk,           typeof(AOpCodeException));
-            SetA64("x0110101xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Cbnz,          typeof(AOpCodeBImmCmp));
-            SetA64("x0110100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Cbz,           typeof(AOpCodeBImmCmp));
-            SetA64("x0111010010xxxxxxxxx10xxxxx0xxxx", AInstEmit.Ccmn,          typeof(AOpCodeCcmpImm));
-            SetA64("x0111010010xxxxxxxxx00xxxxx0xxxx", AInstEmit.Ccmn,          typeof(AOpCodeCcmpReg));
-            SetA64("x1111010010xxxxxxxxx10xxxxx0xxxx", AInstEmit.Ccmp,          typeof(AOpCodeCcmpImm));
-            SetA64("x1111010010xxxxxxxxx00xxxxx0xxxx", AInstEmit.Ccmp,          typeof(AOpCodeCcmpReg));
-            SetA64("11010101000000110011xxxx01011111", AInstEmit.Clrex,         typeof(AOpCodeSystem));
-            SetA64("x101101011000000000101xxxxxxxxxx", AInstEmit.Cls,           typeof(AOpCodeAlu));
-            SetA64("x101101011000000000100xxxxxxxxxx", AInstEmit.Clz,           typeof(AOpCodeAlu));
-            SetA64("00011010110xxxxx010000xxxxxxxxxx", AInstEmit.Crc32b,        typeof(AOpCodeAluRs));
-            SetA64("00011010110xxxxx010001xxxxxxxxxx", AInstEmit.Crc32h,        typeof(AOpCodeAluRs));
-            SetA64("00011010110xxxxx010010xxxxxxxxxx", AInstEmit.Crc32w,        typeof(AOpCodeAluRs));
-            SetA64("10011010110xxxxx010011xxxxxxxxxx", AInstEmit.Crc32x,        typeof(AOpCodeAluRs));
-            SetA64("00011010110xxxxx010100xxxxxxxxxx", AInstEmit.Crc32cb,       typeof(AOpCodeAluRs));
-            SetA64("00011010110xxxxx010101xxxxxxxxxx", AInstEmit.Crc32ch,       typeof(AOpCodeAluRs));
-            SetA64("00011010110xxxxx010110xxxxxxxxxx", AInstEmit.Crc32cw,       typeof(AOpCodeAluRs));
-            SetA64("10011010110xxxxx010111xxxxxxxxxx", AInstEmit.Crc32cx,       typeof(AOpCodeAluRs));
-            SetA64("x0011010100xxxxxxxxx00xxxxxxxxxx", AInstEmit.Csel,          typeof(AOpCodeCsel));
-            SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", AInstEmit.Csinc,         typeof(AOpCodeCsel));
-            SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", AInstEmit.Csinv,         typeof(AOpCodeCsel));
-            SetA64("x1011010100xxxxxxxxx01xxxxxxxxxx", AInstEmit.Csneg,         typeof(AOpCodeCsel));
-            SetA64("11010101000000110011xxxx10111111", AInstEmit.Dmb,           typeof(AOpCodeSystem));
-            SetA64("11010101000000110011xxxx10011111", AInstEmit.Dsb,           typeof(AOpCodeSystem));
-            SetA64("01001010xx1xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Eon,           typeof(AOpCodeAluRs));
-            SetA64("11001010xx1xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eon,           typeof(AOpCodeAluRs));
-            SetA64("0101001000xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluImm));
-            SetA64("110100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluImm));
-            SetA64("01001010xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluRs));
-            SetA64("11001010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Eor,           typeof(AOpCodeAluRs));
-            SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Extr,          typeof(AOpCodeAluRs));
-            SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Extr,          typeof(AOpCodeAluRs));
-            SetA64("11010101000000110010xxxxxxx11111", AInstEmit.Hint,          typeof(AOpCodeSystem));
-            SetA64("11010101000000110011xxxx11011111", AInstEmit.Isb,           typeof(AOpCodeSystem));
-            SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldar,          typeof(AOpCodeMemEx));
-            SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxp,         typeof(AOpCodeMemEx));
-            SetA64("xx001000010xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Ldaxr,         typeof(AOpCodeMemEx));
-            SetA64("<<10100xx1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldp,           typeof(AOpCodeMemPair));
-            SetA64("xx111000010xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemImm));
-            SetA64("xx11100101xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemImm));
-            SetA64("xx111000011xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemReg));
-            SetA64("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit,        typeof(AOpCodeMemLit));
-            SetA64("0x1110001x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
-            SetA64("0x1110011xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
-            SetA64("10111000100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
-            SetA64("1011100110xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
-            SetA64("0x1110001x1xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemReg));
-            SetA64("10111000101xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemReg));
-            SetA64("xx001000010xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Ldxr,          typeof(AOpCodeMemEx));
-            SetA64("1x001000011xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Ldxp,          typeof(AOpCodeMemEx));
-            SetA64("x0011010110xxxxx001000xxxxxxxxxx", AInstEmit.Lslv,          typeof(AOpCodeAluRs));
-            SetA64("x0011010110xxxxx001001xxxxxxxxxx", AInstEmit.Lsrv,          typeof(AOpCodeAluRs));
-            SetA64("x0011011000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Madd,          typeof(AOpCodeMul));
-            SetA64("0111001010xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movk,          typeof(AOpCodeMov));
-            SetA64("111100101xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movk,          typeof(AOpCodeMov));
-            SetA64("0001001010xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movn,          typeof(AOpCodeMov));
-            SetA64("100100101xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movn,          typeof(AOpCodeMov));
-            SetA64("0101001010xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movz,          typeof(AOpCodeMov));
-            SetA64("110100101xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Movz,          typeof(AOpCodeMov));
-            SetA64("110101010011xxxxxxxxxxxxxxxxxxxx", AInstEmit.Mrs,           typeof(AOpCodeSystem));
-            SetA64("110101010001xxxxxxxxxxxxxxxxxxxx", AInstEmit.Msr,           typeof(AOpCodeSystem));
-            SetA64("x0011011000xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Msub,          typeof(AOpCodeMul));
-            SetA64("11010101000000110010000000011111", AInstEmit.Nop,           typeof(AOpCodeSystem));
-            SetA64("00101010xx1xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Orn,           typeof(AOpCodeAluRs));
-            SetA64("10101010xx1xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Orn,           typeof(AOpCodeAluRs));
-            SetA64("0011001000xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Orr,           typeof(AOpCodeAluImm));
-            SetA64("101100100xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Orr,           typeof(AOpCodeAluImm));
-            SetA64("00101010xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Orr,           typeof(AOpCodeAluRs));
-            SetA64("10101010xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Orr,           typeof(AOpCodeAluRs));
-            SetA64("1111100110xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Pfrm,          typeof(AOpCodeMemImm));
-            SetA64("11111000100xxxxxxxxx00xxxxxxxxxx", AInstEmit.Pfrm,          typeof(AOpCodeMemImm));
-            SetA64("11011000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Pfrm,          typeof(AOpCodeMemLit));
-            SetA64("x101101011000000000000xxxxxxxxxx", AInstEmit.Rbit,          typeof(AOpCodeAlu));
-            SetA64("1101011001011111000000xxxxx00000", AInstEmit.Ret,           typeof(AOpCodeBReg));
-            SetA64("x101101011000000000001xxxxxxxxxx", AInstEmit.Rev16,         typeof(AOpCodeAlu));
-            SetA64("x101101011000000000010xxxxxxxxxx", AInstEmit.Rev32,         typeof(AOpCodeAlu));
-            SetA64("1101101011000000000011xxxxxxxxxx", AInstEmit.Rev64,         typeof(AOpCodeAlu));
-            SetA64("x0011010110xxxxx001011xxxxxxxxxx", AInstEmit.Rorv,          typeof(AOpCodeAluRs));
-            SetA64("x1011010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbc,           typeof(AOpCodeAluRs));
-            SetA64("x1111010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbcs,          typeof(AOpCodeAluRs));
-            SetA64("00010011000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Sbfm,          typeof(AOpCodeBfm));
-            SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sbfm,          typeof(AOpCodeBfm));
-            SetA64("x0011010110xxxxx000011xxxxxxxxxx", AInstEmit.Sdiv,          typeof(AOpCodeAluRs));
-            SetA64("10011011001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Smaddl,        typeof(AOpCodeMul));
-            SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Smsubl,        typeof(AOpCodeMul));
-            SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Smulh,         typeof(AOpCodeMul));
-            SetA64("xx001000100xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Stlr,          typeof(AOpCodeMemEx));
-            SetA64("1x001000001xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Stlxp,         typeof(AOpCodeMemEx));
-            SetA64("xx001000000xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Stlxr,         typeof(AOpCodeMemEx));
-            SetA64("x010100xx0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Stp,           typeof(AOpCodeMemPair));
-            SetA64("xx111000000xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeMemImm));
-            SetA64("xx11100100xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeMemImm));
-            SetA64("xx111000001xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeMemReg));
-            SetA64("1x001000001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxp,          typeof(AOpCodeMemEx));
-            SetA64("xx001000000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxr,          typeof(AOpCodeMemEx));
-            SetA64("x10100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub,           typeof(AOpCodeAluImm));
-            SetA64("01001011<<0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Sub,           typeof(AOpCodeAluRs));
-            SetA64("11001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub,           typeof(AOpCodeAluRs));
-            SetA64("x1001011001xxxxxxxx0xxxxxxxxxxxx", AInstEmit.Sub,           typeof(AOpCodeAluRx));
-            SetA64("x1001011001xxxxxxxx100xxxxxxxxxx", AInstEmit.Sub,           typeof(AOpCodeAluRx));
-            SetA64("x11100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs,          typeof(AOpCodeAluImm));
-            SetA64("01101011<<0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Subs,          typeof(AOpCodeAluRs));
-            SetA64("11101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs,          typeof(AOpCodeAluRs));
-            SetA64("x1101011001xxxxxxxx0xxxxxxxxxxxx", AInstEmit.Subs,          typeof(AOpCodeAluRx));
-            SetA64("x1101011001xxxxxxxx100xxxxxxxxxx", AInstEmit.Subs,          typeof(AOpCodeAluRx));
-            SetA64("11010100000xxxxxxxxxxxxxxxx00001", AInstEmit.Svc,           typeof(AOpCodeException));
-            SetA64("1101010100001xxxxxxxxxxxxxxxxxxx", AInstEmit.Sys,           typeof(AOpCodeSystem));
-            SetA64("x0110111xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Tbnz,          typeof(AOpCodeBImmTest));
-            SetA64("x0110110xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Tbz,           typeof(AOpCodeBImmTest));
-            SetA64("01010011000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Ubfm,          typeof(AOpCodeBfm));
-            SetA64("1101001101xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ubfm,          typeof(AOpCodeBfm));
-            SetA64("x0011010110xxxxx000010xxxxxxxxxx", AInstEmit.Udiv,          typeof(AOpCodeAluRs));
-            SetA64("10011011101xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umaddl,        typeof(AOpCodeMul));
-            SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Umsubl,        typeof(AOpCodeMul));
-            SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umulh,         typeof(AOpCodeMul));
-
-            //Vector
-            SetA64("0101111011100000101110xxxxxxxxxx", AInstEmit.Abs_S,         typeof(AOpCodeSimd));
-            SetA64("0>001110<<100000101110xxxxxxxxxx", AInstEmit.Abs_V,         typeof(AOpCodeSimd));
-            SetA64("01011110111xxxxx100001xxxxxxxxxx", AInstEmit.Add_S,         typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx010000xxxxxxxxxx", AInstEmit.Addhn_V,       typeof(AOpCodeSimdReg));
-            SetA64("0101111011110001101110xxxxxxxxxx", AInstEmit.Addp_S,        typeof(AOpCodeSimd));
-            SetA64("0>001110<<1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V,        typeof(AOpCodeSimdReg));
-            SetA64("000011100x110001101110xxxxxxxxxx", AInstEmit.Addv_V,        typeof(AOpCodeSimd));
-            SetA64("01001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V,        typeof(AOpCodeSimd));
-            SetA64("0100111000101000010110xxxxxxxxxx", AInstEmit.Aesd_V,        typeof(AOpCodeSimd));
-            SetA64("0100111000101000010010xxxxxxxxxx", AInstEmit.Aese_V,        typeof(AOpCodeSimd));
-            SetA64("0100111000101000011110xxxxxxxxxx", AInstEmit.Aesimc_V,      typeof(AOpCodeSimd));
-            SetA64("0100111000101000011010xxxxxxxxxx", AInstEmit.Aesmc_V,       typeof(AOpCodeSimd));
-            SetA64("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi,        typeof(AOpCodeSimdImm));
-            SetA64("0x101110111xxxxx000111xxxxxxxxxx", AInstEmit.Bif_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x101110101xxxxx000111xxxxxxxxxx", AInstEmit.Bit_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<100000010010xxxxxxxxxx", AInstEmit.Cls_V,         typeof(AOpCodeSimd));
-            SetA64("0x101110<<100000010010xxxxxxxxxx", AInstEmit.Clz_V,         typeof(AOpCodeSimd));
-            SetA64("01111110111xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_S,        typeof(AOpCodeSimdReg));
-            SetA64("0101111011100000100110xxxxxxxxxx", AInstEmit.Cmeq_S,        typeof(AOpCodeSimd));
-            SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V,        typeof(AOpCodeSimd));
-            SetA64("01011110111xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_S,        typeof(AOpCodeSimdReg));
-            SetA64("0111111011100000100010xxxxxxxxxx", AInstEmit.Cmge_S,        typeof(AOpCodeSimd));
-            SetA64("0>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V,        typeof(AOpCodeSimd));
-            SetA64("01011110111xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_S,        typeof(AOpCodeSimdReg));
-            SetA64("0101111011100000100010xxxxxxxxxx", AInstEmit.Cmgt_S,        typeof(AOpCodeSimd));
-            SetA64("0>001110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V,        typeof(AOpCodeSimd));
-            SetA64("01111110111xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V,        typeof(AOpCodeSimdReg));
-            SetA64("01111110111xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V,        typeof(AOpCodeSimdReg));
-            SetA64("0111111011100000100110xxxxxxxxxx", AInstEmit.Cmle_S,        typeof(AOpCodeSimd));
-            SetA64("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V,        typeof(AOpCodeSimd));
-            SetA64("0101111011100000101010xxxxxxxxxx", AInstEmit.Cmlt_S,        typeof(AOpCodeSimd));
-            SetA64("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V,        typeof(AOpCodeSimd));
-            SetA64("01011110111xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_S,       typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V,         typeof(AOpCodeSimd));
-            SetA64("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp,        typeof(AOpCodeSimdIns));
-            SetA64("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S,         typeof(AOpCodeSimdIns));
-            SetA64("0x001110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_V,         typeof(AOpCodeSimdIns));
-            SetA64("0x101110001xxxxx000111xxxxxxxxxx", AInstEmit.Eor_V,         typeof(AOpCodeSimdReg));
-            SetA64("0>101110000xxxxx0<xxx0xxxxxxxxxx", AInstEmit.Ext_V,         typeof(AOpCodeSimdExt));
-            SetA64("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S,        typeof(AOpCodeSimdReg));
-            SetA64("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S,        typeof(AOpCodeSimd));
-            SetA64("0>0011101<100000111110xxxxxxxxxx", AInstEmit.Fabs_V,        typeof(AOpCodeSimd));
-            SetA64("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V,        typeof(AOpCodeSimdReg));
-            SetA64("011111100x110000110110xxxxxxxxxx", AInstEmit.Faddp_S,       typeof(AOpCodeSimd));
-            SetA64("0>1011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Faddp_V,       typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxxxxxx01xxxxx0xxxx", AInstEmit.Fccmp_S,       typeof(AOpCodeSimdFcond));
-            SetA64("000111100x1xxxxxxxxx01xxxxx1xxxx", AInstEmit.Fccmpe_S,      typeof(AOpCodeSimdFcond));
-            SetA64("010111100x1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmeq_S,       typeof(AOpCodeSimdReg));
-            SetA64("010111101x100000110110xxxxxxxxxx", AInstEmit.Fcmeq_S,       typeof(AOpCodeSimd));
-            SetA64("0>0011100<1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmeq_V,       typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<100000110110xxxxxxxxxx", AInstEmit.Fcmeq_V,       typeof(AOpCodeSimd));
-            SetA64("011111100x1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmge_S,       typeof(AOpCodeSimdReg));
-            SetA64("011111101x100000110010xxxxxxxxxx", AInstEmit.Fcmge_S,       typeof(AOpCodeSimd));
-            SetA64("0>1011100<1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmge_V,       typeof(AOpCodeSimdReg));
-            SetA64("0>1011101<100000110010xxxxxxxxxx", AInstEmit.Fcmge_V,       typeof(AOpCodeSimd));
-            SetA64("011111101x1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmgt_S,       typeof(AOpCodeSimdReg));
-            SetA64("010111101x100000110010xxxxxxxxxx", AInstEmit.Fcmgt_S,       typeof(AOpCodeSimd));
-            SetA64("0>1011101<1xxxxx111001xxxxxxxxxx", AInstEmit.Fcmgt_V,       typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<100000110010xxxxxxxxxx", AInstEmit.Fcmgt_V,       typeof(AOpCodeSimd));
-            SetA64("011111101x100000110110xxxxxxxxxx", AInstEmit.Fcmle_S,       typeof(AOpCodeSimd));
-            SetA64("0>1011101<100000110110xxxxxxxxxx", AInstEmit.Fcmle_V,       typeof(AOpCodeSimd));
-            SetA64("010111101x100000111010xxxxxxxxxx", AInstEmit.Fcmlt_S,       typeof(AOpCodeSimd));
-            SetA64("0>0011101<100000111010xxxxxxxxxx", AInstEmit.Fcmlt_V,       typeof(AOpCodeSimd));
-            SetA64("000111100x1xxxxx001000xxxxx0x000", AInstEmit.Fcmp_S,        typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S,       typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S,       typeof(AOpCodeSimdFcond));
-            SetA64("000111100x10001xx10000xxxxxxxxxx", AInstEmit.Fcvt_S,        typeof(AOpCodeSimd));
-            SetA64("x00111100x100100000000xxxxxxxxxx", AInstEmit.Fcvtas_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x100101000000xxxxxxxxxx", AInstEmit.Fcvtau_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("0x0011100x100001011110xxxxxxxxxx", AInstEmit.Fcvtl_V,       typeof(AOpCodeSimd));
-            SetA64("x00111100x110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x110001000000xxxxxxxxxx", AInstEmit.Fcvtmu_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("0x0011100x100001011010xxxxxxxxxx", AInstEmit.Fcvtn_V,       typeof(AOpCodeSimd));
-            SetA64("010111100x100001101010xxxxxxxxxx", AInstEmit.Fcvtns_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011100<100001101010xxxxxxxxxx", AInstEmit.Fcvtns_V,      typeof(AOpCodeSimd));
-            SetA64("011111100x100001101010xxxxxxxxxx", AInstEmit.Fcvtnu_S,      typeof(AOpCodeSimd));
-            SetA64("0>1011100<100001101010xxxxxxxxxx", AInstEmit.Fcvtnu_V,      typeof(AOpCodeSimd));
-            SetA64("x00111100x101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x101001000000xxxxxxxxxx", AInstEmit.Fcvtpu_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Gp_Fix, typeof(AOpCodeSimdCvt));
-            SetA64("010111101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011101<100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V,      typeof(AOpCodeSimd));
-            SetA64("0x0011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzs_V,      typeof(AOpCodeSimdShImm));
-            SetA64("x00111100x111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_Gp,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Gp_Fix, typeof(AOpCodeSimdCvt));
-            SetA64("011111101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_S,      typeof(AOpCodeSimd));
-            SetA64("0>1011101<100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V,      typeof(AOpCodeSimd));
-            SetA64("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V,      typeof(AOpCodeSimdShImm));
-            SetA64("000111100x1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>1011100<1xxxxx111111xxxxxxxxxx", AInstEmit.Fdiv_V,        typeof(AOpCodeSimdReg));
-            SetA64("000111110x0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S,       typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011100<1xxxxx111101xxxxxxxxxx", AInstEmit.Fmax_V,        typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx011010xxxxxxxxxx", AInstEmit.Fmaxnm_S,      typeof(AOpCodeSimdReg));
-            SetA64("0>0011100<1xxxxx110001xxxxxxxxxx", AInstEmit.Fmaxnm_V,      typeof(AOpCodeSimdReg));
-            SetA64("0>1011100<1xxxxx111101xxxxxxxxxx", AInstEmit.Fmaxp_V,       typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx010110xxxxxxxxxx", AInstEmit.Fmin_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<1xxxxx111101xxxxxxxxxx", AInstEmit.Fmin_V,        typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx011110xxxxxxxxxx", AInstEmit.Fminnm_S,      typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<1xxxxx110001xxxxxxxxxx", AInstEmit.Fminnm_V,      typeof(AOpCodeSimdReg));
-            SetA64("0>1011101<1xxxxx111101xxxxxxxxxx", AInstEmit.Fminp_V,       typeof(AOpCodeSimdReg));
-            SetA64("010111111xxxxxxx0001x0xxxxxxxxxx", AInstEmit.Fmla_Se,       typeof(AOpCodeSimdRegElemF));
-            SetA64("0>0011100<1xxxxx110011xxxxxxxxxx", AInstEmit.Fmla_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011111<xxxxxx0001x0xxxxxxxxxx", AInstEmit.Fmla_Ve,       typeof(AOpCodeSimdRegElemF));
-            SetA64("010111111xxxxxxx0101x0xxxxxxxxxx", AInstEmit.Fmls_Se,       typeof(AOpCodeSimdRegElemF));
-            SetA64("0>0011101<1xxxxx110011xxxxxxxxxx", AInstEmit.Fmls_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011111<xxxxxx0101x0xxxxxxxxxx", AInstEmit.Fmls_Ve,       typeof(AOpCodeSimdRegElemF));
-            SetA64("000111100x100000010000xxxxxxxxxx", AInstEmit.Fmov_S,        typeof(AOpCodeSimd));
-            SetA64("00011110xx1xxxxxxxx100xxxxxxxxxx", AInstEmit.Fmov_Si,       typeof(AOpCodeSimdFmov));
-            SetA64("0xx0111100000xxx111101xxxxxxxxxx", AInstEmit.Fmov_V,        typeof(AOpCodeSimdImm));
-            SetA64("x00111100x100110000000xxxxxxxxxx", AInstEmit.Fmov_Ftoi,     typeof(AOpCodeSimdCvt));
-            SetA64("x00111100x100111000000xxxxxxxxxx", AInstEmit.Fmov_Itof,     typeof(AOpCodeSimdCvt));
-            SetA64("1001111010101110000000xxxxxxxxxx", AInstEmit.Fmov_Ftoi1,    typeof(AOpCodeSimdCvt));
-            SetA64("1001111010101111000000xxxxxxxxxx", AInstEmit.Fmov_Itof1,    typeof(AOpCodeSimdCvt));
-            SetA64("000111110x0xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fmsub_S,       typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx000010xxxxxxxxxx", AInstEmit.Fmul_S,        typeof(AOpCodeSimdReg));
-            SetA64("010111111xxxxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Se,       typeof(AOpCodeSimdRegElemF));
-            SetA64("0>1011100<1xxxxx110111xxxxxxxxxx", AInstEmit.Fmul_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011111<xxxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Ve,       typeof(AOpCodeSimdRegElemF));
-            SetA64("010111100x1xxxxx110111xxxxxxxxxx", AInstEmit.Fmulx_S,       typeof(AOpCodeSimdReg));
-            SetA64("011111111xxxxxxx1001x0xxxxxxxxxx", AInstEmit.Fmulx_Se,      typeof(AOpCodeSimdRegElemF));
-            SetA64("0>0011100<1xxxxx110111xxxxxxxxxx", AInstEmit.Fmulx_V,       typeof(AOpCodeSimdReg));
-            SetA64("0>1011111<xxxxxx1001x0xxxxxxxxxx", AInstEmit.Fmulx_Ve,      typeof(AOpCodeSimdRegElemF));
-            SetA64("000111100x100001010000xxxxxxxxxx", AInstEmit.Fneg_S,        typeof(AOpCodeSimd));
-            SetA64("0>1011101<100000111110xxxxxxxxxx", AInstEmit.Fneg_V,        typeof(AOpCodeSimd));
-            SetA64("000111110x1xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fnmadd_S,      typeof(AOpCodeSimdReg));
-            SetA64("000111110x1xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fnmsub_S,      typeof(AOpCodeSimdReg));
-            SetA64("000111100x1xxxxx100010xxxxxxxxxx", AInstEmit.Fnmul_S,       typeof(AOpCodeSimdReg));
-            SetA64("010111101x100001110110xxxxxxxxxx", AInstEmit.Frecpe_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011101<100001110110xxxxxxxxxx", AInstEmit.Frecpe_V,      typeof(AOpCodeSimd));
-            SetA64("010111100x1xxxxx111111xxxxxxxxxx", AInstEmit.Frecps_S,      typeof(AOpCodeSimdReg));
-            SetA64("0>0011100<1xxxxx111111xxxxxxxxxx", AInstEmit.Frecps_V,      typeof(AOpCodeSimdReg));
-            SetA64("010111101x100001111110xxxxxxxxxx", AInstEmit.Frecpx_S,      typeof(AOpCodeSimd));
-            SetA64("000111100x100110010000xxxxxxxxxx", AInstEmit.Frinta_S,      typeof(AOpCodeSimd));
-            SetA64("0>1011100<100001100010xxxxxxxxxx", AInstEmit.Frinta_V,      typeof(AOpCodeSimd));
-            SetA64("000111100x100111110000xxxxxxxxxx", AInstEmit.Frinti_S,      typeof(AOpCodeSimd));
-            SetA64("0>1011101<100001100110xxxxxxxxxx", AInstEmit.Frinti_V,      typeof(AOpCodeSimd));
-            SetA64("000111100x100101010000xxxxxxxxxx", AInstEmit.Frintm_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011100<100001100110xxxxxxxxxx", AInstEmit.Frintm_V,      typeof(AOpCodeSimd));
-            SetA64("000111100x100100010000xxxxxxxxxx", AInstEmit.Frintn_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011100<100001100010xxxxxxxxxx", AInstEmit.Frintn_V,      typeof(AOpCodeSimd));
-            SetA64("000111100x100100110000xxxxxxxxxx", AInstEmit.Frintp_S,      typeof(AOpCodeSimd));
-            SetA64("0>0011101<100001100010xxxxxxxxxx", AInstEmit.Frintp_V,      typeof(AOpCodeSimd));
-            SetA64("000111100x100111010000xxxxxxxxxx", AInstEmit.Frintx_S,      typeof(AOpCodeSimd));
-            SetA64("0>1011100<100001100110xxxxxxxxxx", AInstEmit.Frintx_V,      typeof(AOpCodeSimd));
-            SetA64("011111101x100001110110xxxxxxxxxx", AInstEmit.Frsqrte_S,     typeof(AOpCodeSimd));
-            SetA64("0>1011101<100001110110xxxxxxxxxx", AInstEmit.Frsqrte_V,     typeof(AOpCodeSimd));
-            SetA64("010111101x1xxxxx111111xxxxxxxxxx", AInstEmit.Frsqrts_S,     typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<1xxxxx111111xxxxxxxxxx", AInstEmit.Frsqrts_V,     typeof(AOpCodeSimdReg));
-            SetA64("000111100x100001110000xxxxxxxxxx", AInstEmit.Fsqrt_S,       typeof(AOpCodeSimd));
-            SetA64("0>1011101<100001111110xxxxxxxxxx", AInstEmit.Fsqrt_V,       typeof(AOpCodeSimd));
-            SetA64("000111100x1xxxxx001110xxxxxxxxxx", AInstEmit.Fsub_S,        typeof(AOpCodeSimdReg));
-            SetA64("0>0011101<1xxxxx110101xxxxxxxxxx", AInstEmit.Fsub_V,        typeof(AOpCodeSimdReg));
-            SetA64("01001110000xxxxx000111xxxxxxxxxx", AInstEmit.Ins_Gp,        typeof(AOpCodeSimdIns));
-            SetA64("01101110000xxxxx0xxxx1xxxxxxxxxx", AInstEmit.Ins_V,         typeof(AOpCodeSimdIns));
-            SetA64("0x00110001000000xxxxxxxxxxxxxxxx", AInstEmit.Ld__Vms,       typeof(AOpCodeSimdMemMs));
-            SetA64("0x001100110xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ld__Vms,       typeof(AOpCodeSimdMemMs));
-            SetA64("0x00110101x00000xxxxxxxxxxxxxxxx", AInstEmit.Ld__Vss,       typeof(AOpCodeSimdMemSs));
-            SetA64("0x00110111xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ld__Vss,       typeof(AOpCodeSimdMemSs));
-            SetA64("xx10110xx1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldp,           typeof(AOpCodeSimdMemPair));
-            SetA64("xx111100x10xxxxxxxxx00xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x10xxxxxxxxx01xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x10xxxxxxxxx11xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeSimdMemReg));
-            SetA64("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit,        typeof(AOpCodeSimdMemLit));
-            SetA64("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x101111xxxxxxxx0000x0xxxxxxxxxx", AInstEmit.Mla_Ve,        typeof(AOpCodeSimdRegElem));
-            SetA64("0x101110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mls_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x101111xxxxxxxx0100x0xxxxxxxxxx", AInstEmit.Mls_Ve,        typeof(AOpCodeSimdRegElem));
-            SetA64("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
-            SetA64("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
-            SetA64("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
-            SetA64("0xx0111100000xxx111001xxxxxxxxxx", AInstEmit.Movi_V,        typeof(AOpCodeSimdImm));
-            SetA64("0x001110<<1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001111xxxxxxxx1000x0xxxxxxxxxx", AInstEmit.Mul_Ve,        typeof(AOpCodeSimdRegElem));
-            SetA64("0x10111100000xxx0xx001xxxxxxxxxx", AInstEmit.Mvni_V,        typeof(AOpCodeSimdImm));
-            SetA64("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V,        typeof(AOpCodeSimdImm));
-            SetA64("0x10111100000xxx110x01xxxxxxxxxx", AInstEmit.Mvni_V,        typeof(AOpCodeSimdImm));
-            SetA64("0111111011100000101110xxxxxxxxxx", AInstEmit.Neg_S,         typeof(AOpCodeSimd));
-            SetA64("0>101110<<100000101110xxxxxxxxxx", AInstEmit.Neg_V,         typeof(AOpCodeSimd));
-            SetA64("0x10111000100000010110xxxxxxxxxx", AInstEmit.Not_V,         typeof(AOpCodeSimd));
-            SetA64("0x001110111xxxxx000111xxxxxxxxxx", AInstEmit.Orn_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi,        typeof(AOpCodeSimdImm));
-            SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", AInstEmit.Raddhn_V,      typeof(AOpCodeSimdReg));
-            SetA64("0x10111001100000010110xxxxxxxxxx", AInstEmit.Rbit_V,        typeof(AOpCodeSimd));
-            SetA64("0x00111000100000000110xxxxxxxxxx", AInstEmit.Rev16_V,       typeof(AOpCodeSimd));
-            SetA64("0x1011100x100000000010xxxxxxxxxx", AInstEmit.Rev32_V,       typeof(AOpCodeSimd));
-            SetA64("0x001110<<100000000010xxxxxxxxxx", AInstEmit.Rev64_V,       typeof(AOpCodeSimd));
-            SetA64("0x00111100>>>xxx100011xxxxxxxxxx", AInstEmit.Rshrn_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", AInstEmit.Rsubhn_V,      typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Saba_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Sabal_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Sabd_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Sabdl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<100000011010xxxxxxxxxx", AInstEmit.Sadalp_V,      typeof(AOpCodeSimd));
-            SetA64("0x001110<<1xxxxx000000xxxxxxxxxx", AInstEmit.Saddl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<100000001010xxxxxxxxxx", AInstEmit.Saddlp_V,      typeof(AOpCodeSimd));
-            SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V,       typeof(AOpCodeSimdReg));
-            SetA64("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp,      typeof(AOpCodeSimdCvt));
-            SetA64("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S,       typeof(AOpCodeSimd));
-            SetA64("0x0011100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_V,       typeof(AOpCodeSimd));
-            SetA64("01011110000xxxxx000000xxxxxxxxxx", AInstEmit.Sha1c_V,       typeof(AOpCodeSimdReg));
-            SetA64("0101111000101000000010xxxxxxxxxx", AInstEmit.Sha1h_V,       typeof(AOpCodeSimd));
-            SetA64("01011110000xxxxx001000xxxxxxxxxx", AInstEmit.Sha1m_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110000xxxxx000100xxxxxxxxxx", AInstEmit.Sha1p_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110000xxxxx001100xxxxxxxxxx", AInstEmit.Sha1su0_V,     typeof(AOpCodeSimdReg));
-            SetA64("0101111000101000000110xxxxxxxxxx", AInstEmit.Sha1su1_V,     typeof(AOpCodeSimd));
-            SetA64("01011110000xxxxx010000xxxxxxxxxx", AInstEmit.Sha256h_V,     typeof(AOpCodeSimdReg));
-            SetA64("01011110000xxxxx010100xxxxxxxxxx", AInstEmit.Sha256h2_V,    typeof(AOpCodeSimdReg));
-            SetA64("0101111000101000001010xxxxxxxxxx", AInstEmit.Sha256su0_V,   typeof(AOpCodeSimd));
-            SetA64("01011110000xxxxx011000xxxxxxxxxx", AInstEmit.Sha256su1_V,   typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Shadd_V,       typeof(AOpCodeSimdReg));
-            SetA64("0101111101xxxxxx010101xxxxxxxxxx", AInstEmit.Shl_S,         typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V,         typeof(AOpCodeSimdShImm));
-            SetA64("0100111101xxxxxx010101xxxxxxxxxx", AInstEmit.Shl_V,         typeof(AOpCodeSimdShImm));
-            SetA64("0x101110<<100001001110xxxxxxxxxx", AInstEmit.Shll_V,        typeof(AOpCodeSimd));
-            SetA64("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", AInstEmit.Shsub_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Sli_V,         typeof(AOpCodeSimdShImm));
-            SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Smaxp_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Sminp_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", AInstEmit.Smlsl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110000xxxxx001011xxxxxxxxxx", AInstEmit.Smov_S,        typeof(AOpCodeSimdIns));
-            SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110xx100000011110xxxxxxxxxx", AInstEmit.Sqabs_S,       typeof(AOpCodeSimd));
-            SetA64("0>001110<<100000011110xxxxxxxxxx", AInstEmit.Sqabs_V,       typeof(AOpCodeSimd));
-            SetA64("01011110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Sqadd_S,       typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<1xxxxx000011xxxxxxxxxx", AInstEmit.Sqadd_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110011xxxxx101101xxxxxxxxxx", AInstEmit.Sqdmulh_S,     typeof(AOpCodeSimdReg));
-            SetA64("01011110101xxxxx101101xxxxxxxxxx", AInstEmit.Sqdmulh_S,     typeof(AOpCodeSimdReg));
-            SetA64("0x001110011xxxxx101101xxxxxxxxxx", AInstEmit.Sqdmulh_V,     typeof(AOpCodeSimdReg));
-            SetA64("0x001110101xxxxx101101xxxxxxxxxx", AInstEmit.Sqdmulh_V,     typeof(AOpCodeSimdReg));
-            SetA64("01111110xx100000011110xxxxxxxxxx", AInstEmit.Sqneg_S,       typeof(AOpCodeSimd));
-            SetA64("0>101110<<100000011110xxxxxxxxxx", AInstEmit.Sqneg_V,       typeof(AOpCodeSimd));
-            SetA64("01111110011xxxxx101101xxxxxxxxxx", AInstEmit.Sqrdmulh_S,    typeof(AOpCodeSimdReg));
-            SetA64("01111110101xxxxx101101xxxxxxxxxx", AInstEmit.Sqrdmulh_S,    typeof(AOpCodeSimdReg));
-            SetA64("0x101110011xxxxx101101xxxxxxxxxx", AInstEmit.Sqrdmulh_V,    typeof(AOpCodeSimdReg));
-            SetA64("0x101110101xxxxx101101xxxxxxxxxx", AInstEmit.Sqrdmulh_V,    typeof(AOpCodeSimdReg));
-            SetA64("0101111100>>>xxx100111xxxxxxxxxx", AInstEmit.Sqrshrn_S,     typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx100111xxxxxxxxxx", AInstEmit.Sqrshrn_V,     typeof(AOpCodeSimdShImm));
-            SetA64("0111111100>>>xxx100011xxxxxxxxxx", AInstEmit.Sqrshrun_S,    typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx100011xxxxxxxxxx", AInstEmit.Sqrshrun_V,    typeof(AOpCodeSimdShImm));
-            SetA64("0101111100>>>xxx100101xxxxxxxxxx", AInstEmit.Sqshrn_S,      typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx100101xxxxxxxxxx", AInstEmit.Sqshrn_V,      typeof(AOpCodeSimdShImm));
-            SetA64("0111111100>>>xxx100001xxxxxxxxxx", AInstEmit.Sqshrun_S,     typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx100001xxxxxxxxxx", AInstEmit.Sqshrun_V,     typeof(AOpCodeSimdShImm));
-            SetA64("01011110xx1xxxxx001011xxxxxxxxxx", AInstEmit.Sqsub_S,       typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", AInstEmit.Sqsub_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S,       typeof(AOpCodeSimd));
-            SetA64("0x001110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_V,       typeof(AOpCodeSimd));
-            SetA64("01111110<<100001001010xxxxxxxxxx", AInstEmit.Sqxtun_S,      typeof(AOpCodeSimd));
-            SetA64("0x101110<<100001001010xxxxxxxxxx", AInstEmit.Sqxtun_V,      typeof(AOpCodeSimd));
-            SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", AInstEmit.Srhadd_V,      typeof(AOpCodeSimdReg));
-            SetA64("0101111101xxxxxx001001xxxxxxxxxx", AInstEmit.Srshr_S,       typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx001001xxxxxxxxxx", AInstEmit.Srshr_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0100111101xxxxxx001001xxxxxxxxxx", AInstEmit.Srshr_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0101111101xxxxxx001101xxxxxxxxxx", AInstEmit.Srsra_S,       typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx001101xxxxxxxxxx", AInstEmit.Srsra_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0100111101xxxxxx001101xxxxxxxxxx", AInstEmit.Srsra_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0101111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_S,        typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0101111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_S,        typeof(AOpCodeSimdShImm));
-            SetA64("0x00111100>>>xxx000101xxxxxxxxxx", AInstEmit.Ssra_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0100111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", AInstEmit.Ssubl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Ssubw_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__Vms,       typeof(AOpCodeSimdMemMs));
-            SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms,       typeof(AOpCodeSimdMemMs));
-            SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", AInstEmit.St__Vss,       typeof(AOpCodeSimdMemSs));
-            SetA64("0x00110110xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vss,       typeof(AOpCodeSimdMemSs));
-            SetA64("xx10110xx0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Stp,           typeof(AOpCodeSimdMemPair));
-            SetA64("xx111100x00xxxxxxxxx00xxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x00xxxxxxxxx01xxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x00xxxxxxxxx11xxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeSimdMemImm));
-            SetA64("xx111100x01xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str,           typeof(AOpCodeSimdMemReg));
-            SetA64("01111110111xxxxx100001xxxxxxxxxx", AInstEmit.Sub_S,         typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V,         typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<1xxxxx011000xxxxxxxxxx", AInstEmit.Subhn_V,       typeof(AOpCodeSimdReg));
-            SetA64("01011110xx100000001110xxxxxxxxxx", AInstEmit.Suqadd_S,      typeof(AOpCodeSimd));
-            SetA64("0>001110<<100000001110xxxxxxxxxx", AInstEmit.Suqadd_V,      typeof(AOpCodeSimd));
-            SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V,         typeof(AOpCodeSimdTbl));
-            SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", AInstEmit.Trn1_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", AInstEmit.Trn2_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Uaba_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Uabal_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Uabd_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Uabdl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<100000011010xxxxxxxxxx", AInstEmit.Uadalp_V,      typeof(AOpCodeSimd));
-            SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", AInstEmit.Uaddl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<100000001010xxxxxxxxxx", AInstEmit.Uaddlp_V,      typeof(AOpCodeSimd));
-            SetA64("001011100x110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V,      typeof(AOpCodeSimd));
-            SetA64("01101110<<110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V,      typeof(AOpCodeSimd));
-            SetA64("0x101110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Uaddw_V,       typeof(AOpCodeSimdReg));
-            SetA64("x0011110xx100011000000xxxxxxxxxx", AInstEmit.Ucvtf_Gp,      typeof(AOpCodeSimdCvt));
-            SetA64("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_S,       typeof(AOpCodeSimd));
-            SetA64("0x1011100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V,       typeof(AOpCodeSimd));
-            SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Uhadd_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", AInstEmit.Uhsub_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Umax_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Umaxp_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Umin_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Umlal_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", AInstEmit.Umlsl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S,        typeof(AOpCodeSimdIns));
-            SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V,       typeof(AOpCodeSimdReg));
-            SetA64("01111110xx1xxxxx000011xxxxxxxxxx", AInstEmit.Uqadd_S,       typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", AInstEmit.Uqadd_V,       typeof(AOpCodeSimdReg));
-            SetA64("0111111100>>>xxx100111xxxxxxxxxx", AInstEmit.Uqrshrn_S,     typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx100111xxxxxxxxxx", AInstEmit.Uqrshrn_V,     typeof(AOpCodeSimdShImm));
-            SetA64("0111111100>>>xxx100101xxxxxxxxxx", AInstEmit.Uqshrn_S,      typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx100101xxxxxxxxxx", AInstEmit.Uqshrn_V,      typeof(AOpCodeSimdShImm));
-            SetA64("01111110xx1xxxxx001011xxxxxxxxxx", AInstEmit.Uqsub_S,       typeof(AOpCodeSimdReg));
-            SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", AInstEmit.Uqsub_V,       typeof(AOpCodeSimdReg));
-            SetA64("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S,       typeof(AOpCodeSimd));
-            SetA64("0x101110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_V,       typeof(AOpCodeSimd));
-            SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", AInstEmit.Urhadd_V,      typeof(AOpCodeSimdReg));
-            SetA64("0111111101xxxxxx001001xxxxxxxxxx", AInstEmit.Urshr_S,       typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx001001xxxxxxxxxx", AInstEmit.Urshr_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0110111101xxxxxx001001xxxxxxxxxx", AInstEmit.Urshr_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0111111101xxxxxx001101xxxxxxxxxx", AInstEmit.Ursra_S,       typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx001101xxxxxxxxxx", AInstEmit.Ursra_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0110111101xxxxxx001101xxxxxxxxxx", AInstEmit.Ursra_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V,       typeof(AOpCodeSimdShImm));
-            SetA64("0111111101xxxxxx000001xxxxxxxxxx", AInstEmit.Ushr_S,        typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0110111101xxxxxx000001xxxxxxxxxx", AInstEmit.Ushr_V,        typeof(AOpCodeSimdShImm));
-            SetA64("01111110xx100000001110xxxxxxxxxx", AInstEmit.Usqadd_S,      typeof(AOpCodeSimd));
-            SetA64("0>101110<<100000001110xxxxxxxxxx", AInstEmit.Usqadd_V,      typeof(AOpCodeSimd));
-            SetA64("0111111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_S,        typeof(AOpCodeSimdShImm));
-            SetA64("0x10111100>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0110111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_V,        typeof(AOpCodeSimdShImm));
-            SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", AInstEmit.Usubl_V,       typeof(AOpCodeSimdReg));
-            SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Usubw_V,       typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V,        typeof(AOpCodeSimdReg));
-            SetA64("0x001110<<100001001010xxxxxxxxxx", AInstEmit.Xtn_V,         typeof(AOpCodeSimd));
-            SetA64("0>001110<<0xxxxx001110xxxxxxxxxx", AInstEmit.Zip1_V,        typeof(AOpCodeSimdReg));
-            SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", AInstEmit.Zip2_V,        typeof(AOpCodeSimdReg));
-#endregion
-
-#region "Generate InstA64FastLookup Table (AArch64)"
-            var Tmp = new List<InstInfo>[FastLookupSize];
-            for (int i = 0; i < FastLookupSize; i++)
-            {
-                Tmp[i] = new List<InstInfo>();
-            }
-
-            foreach (var Inst in AllInstA64)
-            {
-                int Mask = ToFastLookupIndex(Inst.Mask);
-                int Value = ToFastLookupIndex(Inst.Value);
-
-                for (int i = 0; i < FastLookupSize; i++)
-                {
-                    if ((i & Mask) == Value)
-                    {
-                        Tmp[i].Add(Inst);
-                    }
-                }
-            }
-
-            for (int i = 0; i < FastLookupSize; i++)
-            {
-                InstA64FastLookup[i] = Tmp[i].ToArray();
-            }
-#endregion
-        }
-
-        private class InstInfo
-        {
-            public int Mask;
-            public int Value;
-
-            public AInst Inst;
-
-            public InstInfo(int Mask, int Value, AInst Inst)
-            {
-                this.Mask  = Mask;
-                this.Value = Value;
-                this.Inst  = Inst;
-            }
-        }
-
-        private static List<InstInfo> AllInstA32 = new List<InstInfo>();
-        private static List<InstInfo> AllInstA64 = new List<InstInfo>();
-
-        private static int FastLookupSize = 0x1000;
-        private static InstInfo[][] InstA64FastLookup = new InstInfo[FastLookupSize][];
-
-        private static void SetA32(string Encoding, AInstInterpreter Interpreter, Type Type)
-        {
-            Set(Encoding, new AInst(Interpreter, null, Type), AExecutionMode.AArch32);
-        }
-
-        private static void SetA64(string Encoding, AInstEmitter Emitter, Type Type)
-        {
-            Set(Encoding, new AInst(null, Emitter, Type), AExecutionMode.AArch64);
-        }
-
-        private static void Set(string Encoding, AInst Inst, AExecutionMode Mode)
-        {
-            int Bit   = Encoding.Length - 1;
-            int Value = 0;
-            int XMask = 0;
-            int XBits = 0;
-
-            int[] XPos = new int[Encoding.Length];
-
-            int Blacklisted = 0;
-
-            for (int Index = 0; Index < Encoding.Length; Index++, Bit--)
-            {
-                //Note: < and > are used on special encodings.
-                //The < means that we should never have ALL bits with the '<' set.
-                //So, when the encoding has <<, it means that 00, 01, and 10 are valid,
-                //but not 11. <<< is 000, 001, ..., 110 but NOT 111, and so on...
-                //For >, the invalid value is zero. So, for >> 01, 10 and 11 are valid,
-                //but 00 isn't.
-                char Chr = Encoding[Index];
-
-                if (Chr == '1')
-                {
-                    Value |= 1 << Bit;
-                }
-                else if (Chr == 'x')
-                {
-                    XMask |= 1 << Bit;
-                }
-                else if (Chr == '>')
-                {
-                    XPos[XBits++] = Bit;
-                }
-                else if (Chr == '<')
-                {
-                    XPos[XBits++] = Bit;
-
-                    Blacklisted |= 1 << Bit;
-                }
-                else if (Chr != '0')
-                {
-                    throw new ArgumentException(nameof(Encoding));
-                }
-            }
-
-            XMask = ~XMask;
-
-            if (XBits == 0)
-            {
-                InsertInst(XMask, Value, Inst, Mode);
-
-                return;
-            }
-
-            for (int Index = 0; Index < (1 << XBits); Index++)
-            {
-                int Mask = 0;
-
-                for (int X = 0; X < XBits; X++)
-                {
-                    Mask |= ((Index >> X) & 1) << XPos[X];
-                }
-
-                if (Mask != Blacklisted)
-                {
-                    InsertInst(XMask, Value | Mask, Inst, Mode);
-                }
-            }
-        }
-
-        private static void InsertInst(
-            int            XMask,
-            int            Value,
-            AInst          Inst,
-            AExecutionMode Mode)
-        {
-            InstInfo Info = new InstInfo(XMask, Value, Inst);
-
-            if (Mode == AExecutionMode.AArch64)
-            {
-                AllInstA64.Add(Info);
-            }
-            else
-            {
-                AllInstA32.Add(Info);
-            }
-        }
-
-        public static AInst GetInstA32(int OpCode)
-        {
-            return GetInstFromList(AllInstA32, OpCode);
-        }
-
-        public static AInst GetInstA64(int OpCode)
-        {
-            return GetInstFromList(InstA64FastLookup[ToFastLookupIndex(OpCode)], OpCode);
-        }
-
-        private static int ToFastLookupIndex(int Value)
-        {
-            return ((Value >> 10) & 0x00F) | ((Value >> 18) & 0xFF0);
-        }
-
-        private static AInst GetInstFromList(IEnumerable<InstInfo> InstList, int OpCode)
-        {
-            foreach (var Node in InstList)
-            {
-                if ((OpCode & Node.Mask) == Node.Value)
-                {
-                    return Node.Inst;
-                }
-            }
-
-            return AInst.Undefined;
-        }
-    }
-}

+ 0 - 18
ChocolArm64/AOptimizations.cs

@@ -1,18 +0,0 @@
-using System.Runtime.Intrinsics.X86;
-
-public static class AOptimizations
-{
-    internal static bool FastFP = true;
-
-    private static bool UseAllSseIfAvailable = true;
-
-    private static bool UseSseIfAvailable   = true;
-    private static bool UseSse2IfAvailable  = true;
-    private static bool UseSse41IfAvailable = true;
-    private static bool UseSse42IfAvailable = true;
-
-    internal static bool UseSse   = (UseAllSseIfAvailable && UseSseIfAvailable)   && Sse.IsSupported;
-    internal static bool UseSse2  = (UseAllSseIfAvailable && UseSse2IfAvailable)  && Sse2.IsSupported;
-    internal static bool UseSse41 = (UseAllSseIfAvailable && UseSse41IfAvailable) && Sse41.IsSupported;
-    internal static bool UseSse42 = (UseAllSseIfAvailable && UseSse42IfAvailable) && Sse42.IsSupported;
-}

+ 0 - 150
ChocolArm64/ATranslatedSub.cs

@@ -1,150 +0,0 @@
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace ChocolArm64
-{
-    class ATranslatedSub
-    {
-        private delegate long AA64Subroutine(AThreadState Register, AMemory Memory);
-
-        private const int MinCallCountForReJit = 250;
-
-        private AA64Subroutine ExecDelegate;
-
-        public static int StateArgIdx  { get; private set; }
-        public static int MemoryArgIdx { get; private set; }
-
-        public static Type[] FixedArgTypes { get; private set; }
-
-        public DynamicMethod Method { get; private set; }
-
-        public ReadOnlyCollection<ARegister> Params { get; private set; }
-
-        private HashSet<long> Callers;
-
-        private ATranslatedSubType Type;
-
-        private int CallCount;
-
-        private bool NeedsReJit;
-
-        public ATranslatedSub(DynamicMethod Method, List<ARegister> Params)
-        {
-            if (Method == null)
-            {
-                throw new ArgumentNullException(nameof(Method));
-            }
-
-            if (Params == null)
-            {
-                throw new ArgumentNullException(nameof(Params));
-            }
-
-            this.Method = Method;
-            this.Params = Params.AsReadOnly();
-
-            Callers = new HashSet<long>();
-
-            PrepareDelegate();
-        }
-
-        static ATranslatedSub()
-        {
-            MethodInfo MthdInfo = typeof(AA64Subroutine).GetMethod("Invoke");
-
-            ParameterInfo[] Params = MthdInfo.GetParameters();
-
-            FixedArgTypes = new Type[Params.Length];
-
-            for (int Index = 0; Index < Params.Length; Index++)
-            {
-                Type ParamType = Params[Index].ParameterType;
-
-                FixedArgTypes[Index] = ParamType;
-
-                if (ParamType == typeof(AThreadState))
-                {
-                    StateArgIdx = Index;
-                }
-                else if (ParamType == typeof(AMemory))
-                {
-                    MemoryArgIdx = Index;
-                }
-            }
-        }
-
-        private void PrepareDelegate()
-        {
-            string Name = $"{Method.Name}_Dispatch";
-
-            DynamicMethod Mthd = new DynamicMethod(Name, typeof(long), FixedArgTypes);
-
-            ILGenerator Generator = Mthd.GetILGenerator();
-
-            Generator.EmitLdargSeq(FixedArgTypes.Length);
-
-            foreach (ARegister Reg in Params)
-            {
-                Generator.EmitLdarg(StateArgIdx);
-
-                Generator.Emit(OpCodes.Ldfld, Reg.GetField());
-            }
-
-            Generator.Emit(OpCodes.Call, Method);
-            Generator.Emit(OpCodes.Ret);
-
-            ExecDelegate = (AA64Subroutine)Mthd.CreateDelegate(typeof(AA64Subroutine));
-        }
-
-        public bool ShouldReJit()
-        {
-            if (NeedsReJit && CallCount < MinCallCountForReJit)
-            {
-                CallCount++;
-
-                return false;
-            }
-
-            return NeedsReJit;
-        }
-
-        public long Execute(AThreadState ThreadState, AMemory Memory)
-        {
-            return ExecDelegate(ThreadState, Memory);
-        }
-
-        public void AddCaller(long Position)
-        {
-            lock (Callers)
-            {
-                Callers.Add(Position);
-            }
-        }
-
-        public long[] GetCallerPositions()
-        {
-            lock (Callers)
-            {
-                return Callers.ToArray();
-            }
-        }
-
-        public void SetType(ATranslatedSubType Type)
-        {
-            this.Type = Type;
-
-            if (Type == ATranslatedSubType.SubTier0)
-            {
-                NeedsReJit = true;
-            }
-        }
-
-        public void MarkForReJit() => NeedsReJit = true;
-    }
-}

+ 0 - 165
ChocolArm64/ATranslator.cs

@@ -1,165 +0,0 @@
-using ChocolArm64.Decoder;
-using ChocolArm64.Events;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using ChocolArm64.Translation;
-using System;
-using System.Reflection.Emit;
-
-namespace ChocolArm64
-{
-    public class ATranslator
-    {
-        private ATranslatorCache Cache;
-
-        public event EventHandler<ACpuTraceEventArgs> CpuTrace;
-
-        public bool EnableCpuTrace { get; set; }
-
-        public ATranslator()
-        {
-            Cache = new ATranslatorCache();
-        }
-
-        internal void ExecuteSubroutine(AThread Thread, long Position)
-        {
-            //TODO: Both the execute A32/A64 methods should be merged on the future,
-            //when both ISAs are implemented with the interpreter and JIT.
-            //As of now, A32 only has a interpreter and A64 a JIT.
-            AThreadState State  = Thread.ThreadState;
-            AMemory      Memory = Thread.Memory;
-
-            if (State.ExecutionMode == AExecutionMode.AArch32)
-            {
-                ExecuteSubroutineA32(State, Memory);
-            }
-            else
-            {
-                ExecuteSubroutineA64(State, Memory, Position);
-            }
-        }
-
-        private void ExecuteSubroutineA32(AThreadState State, AMemory Memory)
-        {
-            do
-            {
-                AOpCode OpCode = ADecoder.DecodeOpCode(State, Memory, State.R15);
-
-                OpCode.Interpreter(State, Memory, OpCode);
-            }
-            while (State.R15 != 0 && State.Running);
-        }
-
-        private void ExecuteSubroutineA64(AThreadState State, AMemory Memory, long Position)
-        {
-            do
-            {
-                if (EnableCpuTrace)
-                {
-                    CpuTrace?.Invoke(this, new ACpuTraceEventArgs(Position));
-                }
-
-                if (!Cache.TryGetSubroutine(Position, out ATranslatedSub Sub))
-                {
-                    Sub = TranslateTier0(State, Memory, Position);
-                }
-
-                if (Sub.ShouldReJit())
-                {
-                    TranslateTier1(State, Memory, Position);
-                }
-
-                Position = Sub.Execute(State, Memory);
-            }
-            while (Position != 0 && State.Running);
-        }
-
-        internal bool HasCachedSub(long Position)
-        {
-            return Cache.HasSubroutine(Position);
-        }
-
-        private ATranslatedSub TranslateTier0(AThreadState State, AMemory Memory, long Position)
-        {
-            ABlock Block = ADecoder.DecodeBasicBlock(State, Memory, Position);
-
-            ABlock[] Graph = new ABlock[] { Block };
-
-            string SubName = GetSubroutineName(Position);
-
-            AILEmitterCtx Context = new AILEmitterCtx(Cache, Graph, Block, SubName);
-
-            do
-            {
-                Context.EmitOpCode();
-            }
-            while (Context.AdvanceOpCode());
-
-            ATranslatedSub Subroutine = Context.GetSubroutine();
-
-            Subroutine.SetType(ATranslatedSubType.SubTier0);
-
-            Cache.AddOrUpdate(Position, Subroutine, Block.OpCodes.Count);
-
-            AOpCode LastOp = Block.GetLastOp();
-
-            return Subroutine;
-        }
-
-        private void TranslateTier1(AThreadState State, AMemory Memory, long Position)
-        {
-            (ABlock[] Graph, ABlock Root) = ADecoder.DecodeSubroutine(Cache, State, Memory, Position);
-
-            string SubName = GetSubroutineName(Position);
-
-            AILEmitterCtx Context = new AILEmitterCtx(Cache, Graph, Root, SubName);
-
-            if (Context.CurrBlock.Position != Position)
-            {
-                Context.Emit(OpCodes.Br, Context.GetLabel(Position));
-            }
-
-            do
-            {
-                Context.EmitOpCode();
-            }
-            while (Context.AdvanceOpCode());
-
-            //Mark all methods that calls this method for ReJiting,
-            //since we can now call it directly which is faster.
-            if (Cache.TryGetSubroutine(Position, out ATranslatedSub OldSub))
-            {
-                foreach (long CallerPos in OldSub.GetCallerPositions())
-                {
-                    if (Cache.TryGetSubroutine(Position, out ATranslatedSub CallerSub))
-                    {
-                        CallerSub.MarkForReJit();
-                    }
-                }
-            }
-
-            ATranslatedSub Subroutine = Context.GetSubroutine();
-
-            Subroutine.SetType(ATranslatedSubType.SubTier1);
-
-            Cache.AddOrUpdate(Position, Subroutine, GetGraphInstCount(Graph));
-        }
-
-        private string GetSubroutineName(long Position)
-        {
-            return $"Sub{Position:x16}";
-        }
-
-        private int GetGraphInstCount(ABlock[] Graph)
-        {
-            int Size = 0;
-
-            foreach (ABlock Block in Graph)
-            {
-                Size += Block.OpCodes.Count;
-            }
-
-            return Size;
-        }
-    }
-}

+ 0 - 165
ChocolArm64/ATranslatorCache.cs

@@ -1,165 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Threading;
-
-namespace ChocolArm64
-{
-    class ATranslatorCache
-    {
-        //Maximum size of the cache, in bytes, measured in ARM code size.
-        private const int MaxTotalSize = 4 * 1024 * 256;
-
-        //Minimum time required in milliseconds for a method to be eligible for deletion.
-        private const int MinTimeDelta = 2 * 60000;
-
-        //Minimum number of calls required to update the timestamp.
-        private const int MinCallCountForUpdate = 250;
-
-        private class CacheBucket
-        {
-            public ATranslatedSub Subroutine { get; private set; }
-
-            public LinkedListNode<long> Node { get; private set; }
-
-            public int CallCount { get; set; }
-
-            public int Size { get; private set; }
-
-            public long Timestamp { get; private set; }
-
-            public CacheBucket(ATranslatedSub Subroutine, LinkedListNode<long> Node, int Size)
-            {
-                this.Subroutine = Subroutine;
-                this.Size       = Size;
-
-                UpdateNode(Node);
-            }
-
-            public void UpdateNode(LinkedListNode<long> Node)
-            {
-                this.Node = Node;
-
-                Timestamp = GetTimestamp();
-            }
-        }
-
-        private ConcurrentDictionary<long, CacheBucket> Cache;
-
-        private LinkedList<long> SortedCache;
-
-        private int TotalSize;
-
-        public ATranslatorCache()
-        {
-            Cache = new ConcurrentDictionary<long, CacheBucket>();
-
-            SortedCache = new LinkedList<long>();
-        }
-
-        public void AddOrUpdate(long Position, ATranslatedSub Subroutine, int Size)
-        {
-            ClearCacheIfNeeded();
-
-            TotalSize += Size;
-
-            lock (SortedCache)
-            {
-                LinkedListNode<long> Node = SortedCache.AddLast(Position);
-
-                CacheBucket NewBucket = new CacheBucket(Subroutine, Node, Size);
-
-                Cache.AddOrUpdate(Position, NewBucket, (Key, Bucket) =>
-                {
-                    TotalSize -= Bucket.Size;
-
-                    SortedCache.Remove(Bucket.Node);
-
-                    return NewBucket;
-                });
-            }
-        }
-
-        public bool HasSubroutine(long Position)
-        {
-            return Cache.ContainsKey(Position);
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public bool TryGetSubroutine(long Position, out ATranslatedSub Subroutine)
-        {
-            if (Cache.TryGetValue(Position, out CacheBucket Bucket))
-            {
-                if (Bucket.CallCount++ > MinCallCountForUpdate)
-                {
-                    if (Monitor.TryEnter(SortedCache))
-                    {
-                        try
-                        {
-                            Bucket.CallCount = 0;
-
-                            SortedCache.Remove(Bucket.Node);
-
-                            Bucket.UpdateNode(SortedCache.AddLast(Position));
-                        }
-                        finally
-                        {
-                            Monitor.Exit(SortedCache);
-                        }
-                    }
-                }
-
-                Subroutine = Bucket.Subroutine;
-
-                return true;
-            }
-
-            Subroutine = default(ATranslatedSub);
-
-            return false;
-        }
-
-        private void ClearCacheIfNeeded()
-        {
-            long Timestamp = GetTimestamp();
-
-            while (TotalSize > MaxTotalSize)
-            {
-                lock (SortedCache)
-                {
-                    LinkedListNode<long> Node = SortedCache.First;
-
-                    if (Node == null)
-                    {
-                        break;
-                    }
-
-                    CacheBucket Bucket = Cache[Node.Value];
-
-                    long TimeDelta = Timestamp - Bucket.Timestamp;
-
-                    if (TimeDelta <= MinTimeDelta)
-                    {
-                        break;
-                    }
-
-                    if (Cache.TryRemove(Node.Value, out Bucket))
-                    {
-                        TotalSize -= Bucket.Size;
-
-                        SortedCache.Remove(Bucket.Node);
-                    }
-                }
-            }
-        }
-
-        private static long GetTimestamp()
-        {
-            long timestamp = Stopwatch.GetTimestamp();
-
-            return timestamp / (Stopwatch.Frequency / 1000);
-        }
-    }
-}

+ 49 - 0
ChocolArm64/BitUtils.cs

@@ -0,0 +1,49 @@
+namespace ChocolArm64
+{
+    static class BitUtils
+    {
+        public static int HighestBitSet32(int value)
+        {
+            for (int bit = 31; bit >= 0; bit--)
+            {
+                if (((value >> bit) & 1) != 0)
+                {
+                    return bit;
+                }
+            }
+
+            return -1;
+        }
+
+        private static readonly sbyte[] HbsNibbleTbl = { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+        public static int HighestBitSetNibble(int value) => HbsNibbleTbl[value & 0b1111];
+
+        public static long Replicate(long bits, int size)
+        {
+            long output = 0;
+
+            for (int bit = 0; bit < 64; bit += size)
+            {
+                output |= bits << bit;
+            }
+
+            return output;
+        }
+
+        public static long FillWithOnes(int bits)
+        {
+            return bits == 64 ? -1L : (1L << bits) - 1;
+        }
+
+        public static long RotateRight(long bits, int shift, int size)
+        {
+            return (long)RotateRight((ulong)bits, shift, size);
+        }
+
+        public static ulong RotateRight(ulong bits, int shift, int size)
+        {
+            return (bits >> shift) | (bits << (size - shift));
+        }
+    }
+}

+ 13 - 13
ChocolArm64/AThread.cs → ChocolArm64/CpuThread.cs

@@ -5,35 +5,35 @@ using System.Threading;
 
 namespace ChocolArm64
 {
-    public class AThread
+    public class CpuThread
     {
-        public AThreadState ThreadState { get; private set; }
-        public AMemory      Memory      { get; private set; }
+        public CpuThreadState ThreadState { get; private set; }
+        public MemoryManager  Memory      { get; private set; }
 
-        private ATranslator Translator;
+        private Translator _translator;
 
         public Thread Work;
 
         public event EventHandler WorkFinished;
 
-        private int IsExecuting;
+        private int _isExecuting;
 
-        public AThread(ATranslator Translator, AMemory Memory, long EntryPoint)
+        public CpuThread(Translator translator, MemoryManager memory, long entryPoint)
         {
-            this.Translator = Translator;
-            this.Memory     = Memory;
+            _translator = translator;
+            Memory      = memory;
 
-            ThreadState = new AThreadState();
+            ThreadState = new CpuThreadState();
 
-            ThreadState.ExecutionMode = AExecutionMode.AArch64;
+            ThreadState.ExecutionMode = ExecutionMode.AArch64;
 
             ThreadState.Running = true;
 
             Work = new Thread(delegate()
             {
-                Translator.ExecuteSubroutine(this, EntryPoint);
+                translator.ExecuteSubroutine(this, entryPoint);
 
-                Memory.RemoveMonitor(ThreadState.Core);
+                memory.RemoveMonitor(ThreadState.Core);
 
                 WorkFinished?.Invoke(this, EventArgs.Empty);
             });
@@ -41,7 +41,7 @@ namespace ChocolArm64
 
         public bool Execute()
         {
-            if (Interlocked.Exchange(ref IsExecuting, 1) == 1)
+            if (Interlocked.Exchange(ref _isExecuting, 1) == 1)
             {
                 return false;
             }

+ 0 - 35
ChocolArm64/Decoder/ABlock.cs

@@ -1,35 +0,0 @@
-using System.Collections.Generic;
-
-namespace ChocolArm64.Decoder
-{
-    class ABlock
-    {
-        public long Position    { get; set; }
-        public long EndPosition { get; set; }
-
-        public ABlock Next   { get; set; }
-        public ABlock Branch { get; set; }
-
-        public List<AOpCode> OpCodes { get; private set; }
-
-        public ABlock()
-        {
-            OpCodes = new List<AOpCode>();
-        }
-
-        public ABlock(long Position) : this()
-        {
-            this.Position = Position;
-        }
-
-        public AOpCode GetLastOp()
-        {
-            if (OpCodes.Count > 0)
-            {
-                return OpCodes[OpCodes.Count - 1];
-            }
-
-            return null;
-        }
-    }
-}

+ 0 - 22
ChocolArm64/Decoder/ACond.cs

@@ -1,22 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    enum ACond
-    {
-        Eq    = 0,
-        Ne    = 1,
-        Ge_Un = 2,
-        Lt_Un = 3,
-        Mi    = 4,
-        Pl    = 5,
-        Vs    = 6,
-        Vc    = 7,
-        Gt_Un = 8,
-        Le_Un = 9,
-        Ge    = 10,
-        Lt    = 11,
-        Gt    = 12,
-        Le    = 13,
-        Al    = 14,
-        Nv    = 15
-    }
-}

+ 0 - 239
ChocolArm64/Decoder/ADecoder.cs

@@ -1,239 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.Memory;
-using ChocolArm64.State;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Reflection.Emit;
-
-namespace ChocolArm64.Decoder
-{
-    static class ADecoder
-    {
-        private delegate object OpActivator(AInst Inst, long Position, int OpCode);
-
-        private static ConcurrentDictionary<Type, OpActivator> OpActivators;
-
-        static ADecoder()
-        {
-            OpActivators = new ConcurrentDictionary<Type, OpActivator>();
-        }
-
-        public static ABlock DecodeBasicBlock(AThreadState State, AMemory Memory, long Start)
-        {
-            ABlock Block = new ABlock(Start);
-
-            FillBlock(State, Memory, Block);
-
-            return Block;
-        }
-
-        public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(
-            ATranslatorCache Cache,
-            AThreadState     State,
-            AMemory          Memory,
-            long             Start)
-        {
-            Dictionary<long, ABlock> Visited    = new Dictionary<long, ABlock>();
-            Dictionary<long, ABlock> VisitedEnd = new Dictionary<long, ABlock>();
-
-            Queue<ABlock> Blocks = new Queue<ABlock>();
-
-            ABlock Enqueue(long Position)
-            {
-                if (!Visited.TryGetValue(Position, out ABlock Output))
-                {
-                    Output = new ABlock(Position);
-
-                    Blocks.Enqueue(Output);
-
-                    Visited.Add(Position, Output);
-                }
-
-                return Output;
-            }
-
-            ABlock Root = Enqueue(Start);
-
-            while (Blocks.Count > 0)
-            {
-                ABlock Current = Blocks.Dequeue();
-
-                FillBlock(State, Memory, Current);
-
-                //Set child blocks. "Branch" is the block the branch instruction
-                //points to (when taken), "Next" is the block at the next address,
-                //executed when the branch is not taken. For Unconditional Branches
-                //(except BL/BLR that are sub calls) or end of executable, Next is null.
-                if (Current.OpCodes.Count > 0)
-                {
-                    bool HasCachedSub = false;
-
-                    AOpCode LastOp = Current.GetLastOp();
-
-                    if (LastOp is AOpCodeBImm Op)
-                    {
-                        if (Op.Emitter == AInstEmit.Bl)
-                        {
-                            HasCachedSub = Cache.HasSubroutine(Op.Imm);
-                        }
-                        else
-                        {
-                            Current.Branch = Enqueue(Op.Imm);
-                        }
-                    }
-
-                    if (!((LastOp is AOpCodeBImmAl) ||
-                          (LastOp is AOpCodeBReg)) || HasCachedSub)
-                    {
-                        Current.Next = Enqueue(Current.EndPosition);
-                    }
-                }
-
-                //If we have on the graph two blocks with the same end position,
-                //then we need to split the bigger block and have two small blocks,
-                //the end position of the bigger "Current" block should then be == to
-                //the position of the "Smaller" block.
-                while (VisitedEnd.TryGetValue(Current.EndPosition, out ABlock Smaller))
-                {
-                    if (Current.Position > Smaller.Position)
-                    {
-                        ABlock Temp = Smaller;
-
-                        Smaller = Current;
-                        Current = Temp;
-                    }
-
-                    Current.EndPosition = Smaller.Position;
-                    Current.Next        = Smaller;
-                    Current.Branch      = null;
-
-                    Current.OpCodes.RemoveRange(
-                        Current.OpCodes.Count - Smaller.OpCodes.Count,
-                        Smaller.OpCodes.Count);
-
-                    VisitedEnd[Smaller.EndPosition] = Smaller;
-                }
-
-                VisitedEnd.Add(Current.EndPosition, Current);
-            }
-
-            //Make and sort Graph blocks array by position.
-            ABlock[] Graph = new ABlock[Visited.Count];
-
-            while (Visited.Count > 0)
-            {
-                ulong FirstPos = ulong.MaxValue;
-
-                foreach (ABlock Block in Visited.Values)
-                {
-                    if (FirstPos > (ulong)Block.Position)
-                        FirstPos = (ulong)Block.Position;
-                }
-
-                ABlock Current = Visited[(long)FirstPos];
-
-                do
-                {
-                    Graph[Graph.Length - Visited.Count] = Current;
-
-                    Visited.Remove(Current.Position);
-
-                    Current = Current.Next;
-                }
-                while (Current != null);
-            }
-
-            return (Graph, Root);
-        }
-
-        private static void FillBlock(AThreadState State, AMemory Memory, ABlock Block)
-        {
-            long Position = Block.Position;
-
-            AOpCode OpCode;
-
-            do
-            {
-                //TODO: This needs to be changed to support both AArch32 and AArch64,
-                //once JIT support is introduced on AArch32 aswell.
-                OpCode = DecodeOpCode(State, Memory, Position);
-
-                Block.OpCodes.Add(OpCode);
-
-                Position += 4;
-            }
-            while (!(IsBranch(OpCode) || IsException(OpCode)));
-
-            Block.EndPosition = Position;
-        }
-
-        private static bool IsBranch(AOpCode OpCode)
-        {
-            return OpCode is AOpCodeBImm ||
-                   OpCode is AOpCodeBReg;
-        }
-
-        private static bool IsException(AOpCode OpCode)
-        {
-            return OpCode.Emitter == AInstEmit.Brk ||
-                   OpCode.Emitter == AInstEmit.Svc ||
-                   OpCode.Emitter == AInstEmit.Und;
-        }
-
-        public static AOpCode DecodeOpCode(AThreadState State, AMemory Memory, long Position)
-        {
-            int OpCode = Memory.ReadInt32(Position);
-
-            AInst Inst;
-
-            if (State.ExecutionMode == AExecutionMode.AArch64)
-            {
-                Inst = AOpCodeTable.GetInstA64(OpCode);
-            }
-            else
-            {
-                //TODO: Thumb support.
-                Inst = AOpCodeTable.GetInstA32(OpCode);
-            }
-
-            AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);
-
-            if (Inst.Type != null)
-            {
-                DecodedOpCode = MakeOpCode(Inst.Type, Inst, Position, OpCode);
-            }
-
-            return DecodedOpCode;
-        }
-
-        private static AOpCode MakeOpCode(Type Type, AInst Inst, long Position, int OpCode)
-        {
-            if (Type == null)
-            {
-                throw new ArgumentNullException(nameof(Type));
-            }
-
-            OpActivator CreateInstance = OpActivators.GetOrAdd(Type, CacheOpActivator);
-
-            return (AOpCode)CreateInstance(Inst, Position, OpCode);
-        }
-
-        private static OpActivator CacheOpActivator(Type Type)
-        {
-            Type[] ArgTypes = new Type[] { typeof(AInst), typeof(long), typeof(int) };
-
-            DynamicMethod Mthd = new DynamicMethod($"Make{Type.Name}", Type, ArgTypes);
-
-            ILGenerator Generator = Mthd.GetILGenerator();
-
-            Generator.Emit(OpCodes.Ldarg_0);
-            Generator.Emit(OpCodes.Ldarg_1);
-            Generator.Emit(OpCodes.Ldarg_2);
-            Generator.Emit(OpCodes.Newobj, Type.GetConstructor(ArgTypes));
-            Generator.Emit(OpCodes.Ret);
-
-            return (OpActivator)Mthd.CreateDelegate(typeof(OpActivator));
-        }
-    }
-}

+ 0 - 107
ChocolArm64/Decoder/ADecoderHelper.cs

@@ -1,107 +0,0 @@
-using System;
-
-namespace ChocolArm64.Decoder
-{
-    static class ADecoderHelper
-    {
-        public struct BitMask
-        {
-            public long WMask;
-            public long TMask;
-            public int  Pos;
-            public int  Shift;
-            public bool IsUndefined;
-
-            public static BitMask Invalid => new BitMask { IsUndefined = true };
-        }
-
-        public static BitMask DecodeBitMask(int OpCode, bool Immediate)
-        {
-            int ImmS = (OpCode >> 10) & 0x3f;
-            int ImmR = (OpCode >> 16) & 0x3f;
-
-            int N  = (OpCode >> 22) & 1;
-            int SF = (OpCode >> 31) & 1;
-
-            int Length = ABitUtils.HighestBitSet32((~ImmS & 0x3f) | (N << 6));
-
-            if (Length < 1 || (SF == 0 && N != 0))
-            {
-                return BitMask.Invalid;
-            }
-
-            int Size = 1 << Length;
-
-            int Levels = Size - 1;
-
-            int S = ImmS & Levels;
-            int R = ImmR & Levels;
-
-            if (Immediate && S == Levels)
-            {
-                return BitMask.Invalid;
-            }
-
-            long WMask = ABitUtils.FillWithOnes(S + 1);
-            long TMask = ABitUtils.FillWithOnes(((S - R) & Levels) + 1);
-
-            if (R > 0)
-            {
-                WMask  = ABitUtils.RotateRight(WMask, R, Size);
-                WMask &= ABitUtils.FillWithOnes(Size);
-            }
-
-            return new BitMask()
-            {
-                WMask = ABitUtils.Replicate(WMask, Size),
-                TMask = ABitUtils.Replicate(TMask, Size),
-
-                Pos   = ImmS,
-                Shift = ImmR
-            };
-        }
-
-        public static long DecodeImm8Float(long Imm, int Size)
-        {
-            int E = 0, F = 0;
-
-            switch (Size)
-            {
-                case 0: E =  8; F = 23; break;
-                case 1: E = 11; F = 52; break;
-
-                default: throw new ArgumentOutOfRangeException(nameof(Size));
-            }
-
-            long Value = (Imm & 0x3f) << F - 4;
-
-            long EBit = (Imm >> 6) & 1;
-            long SBit = (Imm >> 7) & 1;
-
-            if (EBit != 0)
-            {
-                Value |= (1L << E - 3) - 1 << F + 2;
-            }
-
-            Value |= (EBit ^ 1) << F + E - 1;
-            Value |=  SBit      << F + E;
-
-            return Value;
-        }
-
-        public static long DecodeImm26_2(int OpCode)
-        {
-            return ((long)OpCode << 38) >> 36;
-        }
-
-        public static long DecodeImmS19_2(int OpCode)
-        {
-            return (((long)OpCode << 40) >> 43) & ~3;
-        }
-
-        public static long DecodeImmS14_2(int OpCode)
-        {
-            return (((long)OpCode << 45) >> 48) & ~3;
-        }
-    }
-}

+ 0 - 40
ChocolArm64/Decoder/AOpCode.cs

@@ -1,40 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-using System;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCode : IAOpCode
-    {
-        public long Position  { get; private set; }
-        public int  RawOpCode { get; private set; }
-
-        public AInstEmitter     Emitter      { get; protected set; }
-        public AInstInterpreter Interpreter  { get; protected set; }
-        public ARegisterSize    RegisterSize { get; protected set; }
-
-        public AOpCode(AInst Inst, long Position, int OpCode)
-        {
-            this.Position  = Position;
-            this.RawOpCode = OpCode;
-
-            RegisterSize = ARegisterSize.Int64;
-
-            Emitter     = Inst.Emitter;
-            Interpreter = Inst.Interpreter;
-        }
-
-        public int GetBitsCount()
-        {
-            switch (RegisterSize)
-            {
-                case ARegisterSize.Int32:   return 32;
-                case ARegisterSize.Int64:   return 64;
-                case ARegisterSize.SIMD64:  return 64;
-                case ARegisterSize.SIMD128: return 128;
-            }
-
-            throw new InvalidOperationException();
-        }
-    }
-}

+ 0 - 18
ChocolArm64/Decoder/AOpCodeAdr.cs

@@ -1,18 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeAdr : AOpCode
-    {
-        public int  Rd  { get; private set; }
-        public long Imm { get; private set; }
-
-         public AOpCodeAdr(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rd = OpCode & 0x1f;
-
-            Imm  = ADecoderHelper.DecodeImmS19_2(OpCode);
-            Imm |= ((long)OpCode >> 29) & 3;
-        }
-    }
-}

+ 0 - 24
ChocolArm64/Decoder/AOpCodeAlu.cs

@@ -1,24 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeAlu : AOpCode, IAOpCodeAlu
-    {
-        public int Rd { get; protected set; }
-        public int Rn { get; private   set; }
-
-        public ADataOp DataOp { get; private set; }
-
-        public AOpCodeAlu(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rd     =           (OpCode >>  0) & 0x1f;
-            Rn     =           (OpCode >>  5) & 0x1f;
-            DataOp = (ADataOp)((OpCode >> 24) & 0x3);
-
-            RegisterSize = (OpCode >> 31) != 0
-                ? ARegisterSize.Int64
-                : ARegisterSize.Int32;
-        }
-    }
-}

+ 0 - 39
ChocolArm64/Decoder/AOpCodeAluImm.cs

@@ -1,39 +0,0 @@
-using ChocolArm64.Instruction;
-using System;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeAluImm : AOpCodeAlu, IAOpCodeAluImm
-    {
-        public long Imm { get; private set; }
-
-        public AOpCodeAluImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            if (DataOp == ADataOp.Arithmetic)
-            {
-                Imm = (OpCode >> 10) & 0xfff;
-
-                int Shift = (OpCode >> 22) & 3;
-
-                Imm <<= Shift * 12;
-            }
-            else if (DataOp == ADataOp.Logical)
-            {
-                var BM = ADecoderHelper.DecodeBitMask(OpCode, true);
-
-                if (BM.IsUndefined)
-                {
-                    Emitter = AInstEmit.Und;
-
-                    return;
-                }
-
-                Imm = BM.WMask;
-            }
-            else
-            {
-                throw new ArgumentException(nameof(OpCode));
-            }
-        }
-    }
-}

+ 0 - 29
ChocolArm64/Decoder/AOpCodeAluRs.cs

@@ -1,29 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeAluRs : AOpCodeAlu, IAOpCodeAluRs
-    {
-        public int Shift { get; private set; }
-        public int Rm    { get; private set; }
-
-        public AShiftType ShiftType { get; private set; }
-
-        public AOpCodeAluRs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Shift = (OpCode >> 10) & 0x3f;
-
-            if (Shift >= GetBitsCount())
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            this.Shift = Shift;
-
-            Rm        =              (OpCode >> 16) & 0x1f;
-            ShiftType = (AShiftType)((OpCode >> 22) & 0x3);
-        }
-    }
-}

+ 0 - 19
ChocolArm64/Decoder/AOpCodeAluRx.cs

@@ -1,19 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeAluRx : AOpCodeAlu, IAOpCodeAluRx
-    {
-        public int Shift { get; private set; }
-        public int Rm    { get; private set; }
-
-        public AIntType IntType { get; private set; }
-
-        public AOpCodeAluRx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Shift   =            (OpCode >> 10) & 0x7;
-            IntType = (AIntType)((OpCode >> 13) & 0x7);
-            Rm      =            (OpCode >> 16) & 0x1f;
-        }
-    }
-}

+ 0 - 11
ChocolArm64/Decoder/AOpCodeBImm.cs

@@ -1,11 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBImm : AOpCode
-    {
-        public long Imm { get; protected set; }
-
-        public AOpCodeBImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
-    }
-}

+ 0 - 12
ChocolArm64/Decoder/AOpCodeBImmAl.cs

@@ -1,12 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBImmAl : AOpCodeBImm
-    {
-        public AOpCodeBImmAl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Imm = Position + ADecoderHelper.DecodeImm26_2(OpCode);
-        }
-    }
-}

+ 0 - 21
ChocolArm64/Decoder/AOpCodeBImmCmp.cs

@@ -1,21 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBImmCmp : AOpCodeBImm
-    {
-        public int Rt { get; private set; }
-
-        public AOpCodeBImmCmp(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt = OpCode & 0x1f;
-
-            Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
-
-            RegisterSize = (OpCode >> 31) != 0
-                ? ARegisterSize.Int64
-                : ARegisterSize.Int32;
-        }
-    }
-}

+ 0 - 25
ChocolArm64/Decoder/AOpCodeBImmCond.cs

@@ -1,25 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBImmCond : AOpCodeBImm, IAOpCodeCond
-    {
-        public ACond Cond { get; private set; }
-
-        public AOpCodeBImmCond(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int O0 = (OpCode >> 4) & 1;
-
-            if (O0 != 0)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Cond = (ACond)(OpCode & 0xf);
-
-            Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
-        }
-    }
-}

+ 0 - 20
ChocolArm64/Decoder/AOpCodeBImmTest.cs

@@ -1,20 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBImmTest : AOpCodeBImm
-    {
-        public int Rt  { get; private set; }
-        public int Pos { get; private set; }
-
-        public AOpCodeBImmTest(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt = OpCode & 0x1f;
-
-            Imm = Position + ADecoderHelper.DecodeImmS14_2(OpCode);
-
-            Pos  = (OpCode >> 19) & 0x1f;
-            Pos |= (OpCode >> 26) & 0x20;
-        }
-    }
-}

+ 0 - 24
ChocolArm64/Decoder/AOpCodeBReg.cs

@@ -1,24 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBReg : AOpCode
-    {
-        public int Rn { get; private set; }
-
-        public AOpCodeBReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Op4 = (OpCode >>  0) & 0x1f;
-            int Op2 = (OpCode >> 16) & 0x1f;
-
-            if (Op2 != 0b11111 || Op4 != 0b00000)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Rn = (OpCode >> 5) & 0x1f;
-        }
-    }
-}

+ 0 - 29
ChocolArm64/Decoder/AOpCodeBfm.cs

@@ -1,29 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeBfm : AOpCodeAlu
-    {
-        public long WMask { get; private set; }
-        public long TMask { get; private set; }
-        public int  Pos   { get; private set; }
-        public int  Shift { get; private set; }
-
-        public AOpCodeBfm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            var BM = ADecoderHelper.DecodeBitMask(OpCode, false);
-
-            if (BM.IsUndefined)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            WMask = BM.WMask;
-            TMask = BM.TMask;
-            Pos   = BM.Pos;
-            Shift = BM.Shift;
-        }
-    }
-}

+ 0 - 31
ChocolArm64/Decoder/AOpCodeCcmp.cs

@@ -1,31 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeCcmp : AOpCodeAlu, IAOpCodeCond
-    {
-        public    int NZCV { get; private set; }
-        protected int RmImm;
-
-        public ACond Cond { get; private set; }
-
-        public AOpCodeCcmp(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int O3 = (OpCode >> 4) & 1;
-
-            if (O3 != 0)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            NZCV  =         (OpCode >>  0) & 0xf;
-            Cond  = (ACond)((OpCode >> 12) & 0xf);
-            RmImm =         (OpCode >> 16) & 0x1f;
-
-            Rd = AThreadState.ZRIndex;
-        }
-    }
-}

+ 0 - 11
ChocolArm64/Decoder/AOpCodeCcmpImm.cs

@@ -1,11 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeCcmpImm : AOpCodeCcmp, IAOpCodeAluImm
-    {
-        public long Imm => RmImm;
-
-        public AOpCodeCcmpImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
-    }
-}

+ 0 - 15
ChocolArm64/Decoder/AOpCodeCcmpReg.cs

@@ -1,15 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeCcmpReg : AOpCodeCcmp, IAOpCodeAluRs
-    {
-        public int Rm => RmImm;
-
-        public int Shift => 0;
-
-        public AShiftType ShiftType => AShiftType.Lsl;
-
-        public AOpCodeCcmpReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
-    }
-}

+ 0 - 17
ChocolArm64/Decoder/AOpCodeCsel.cs

@@ -1,17 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeCsel : AOpCodeAlu, IAOpCodeCond
-    {
-        public int Rm { get; private set; }
-
-        public ACond Cond { get; private set; }
-
-        public AOpCodeCsel(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rm   =         (OpCode >> 16) & 0x1f;
-            Cond = (ACond)((OpCode >> 12) & 0xf);
-        }
-    }
-}

+ 0 - 14
ChocolArm64/Decoder/AOpCodeException.cs

@@ -1,14 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeException : AOpCode
-    {
-        public int Id { get; private set; }
-
-        public AOpCodeException(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Id = (OpCode >> 5) & 0xffff;
-        }
-    }
-}

+ 0 - 19
ChocolArm64/Decoder/AOpCodeMem.cs

@@ -1,19 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMem : AOpCode
-    {
-        public int  Rt       { get; protected set; }
-        public int  Rn       { get; protected set; }
-        public int  Size     { get; protected set; }
-        public bool Extend64 { get; protected set; }
-
-        public AOpCodeMem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt   = (OpCode >>  0) & 0x1f;
-            Rn   = (OpCode >>  5) & 0x1f;
-            Size = (OpCode >> 30) & 0x3;
-        }
-    }
-}

+ 0 - 16
ChocolArm64/Decoder/AOpCodeMemEx.cs

@@ -1,16 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMemEx : AOpCodeMem
-    {
-        public int Rt2 { get; private set; }
-        public int Rs  { get; private set; }
-
-        public AOpCodeMemEx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt2 = (OpCode >> 10) & 0x1f;
-            Rs  = (OpCode >> 16) & 0x1f;
-        }
-    }
-}

+ 0 - 25
ChocolArm64/Decoder/AOpCodeMemPair.cs

@@ -1,25 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMemPair : AOpCodeMemImm
-    {
-        public int Rt2 { get; private set; }
-
-        public AOpCodeMemPair(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt2      =  (OpCode >> 10) & 0x1f;
-            WBack    = ((OpCode >> 23) & 0x1) != 0;
-            PostIdx  = ((OpCode >> 23) & 0x3) == 1;
-            Extend64 = ((OpCode >> 30) & 0x3) == 1;
-            Size     = ((OpCode >> 31) & 0x1) | 2;
-
-            DecodeImm(OpCode);
-        }
-
-        protected void DecodeImm(int OpCode)
-        {
-            Imm = ((long)(OpCode >> 15) << 57) >> (57 - Size);
-        }
-    }
-}

+ 0 - 20
ChocolArm64/Decoder/AOpCodeMemReg.cs

@@ -1,20 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMemReg : AOpCodeMem
-    {
-        public bool Shift { get; private set; }
-        public int  Rm    { get; private set; }
-
-        public AIntType IntType { get; private set; }
-
-        public AOpCodeMemReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Shift    =           ((OpCode >> 12) & 0x1) != 0;
-            IntType  = (AIntType)((OpCode >> 13) & 0x7);
-            Rm       =            (OpCode >> 16) & 0x1f;
-            Extend64 =           ((OpCode >> 22) & 0x3) == 2;
-        }
-    }
-}

+ 0 - 36
ChocolArm64/Decoder/AOpCodeMov.cs

@@ -1,36 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMov : AOpCode
-    {
-        public int  Rd  { get; private set; }
-        public long Imm { get; private set; }
-        public int  Pos { get; private set; }
-
-        public AOpCodeMov(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int P1 = (OpCode >> 22) & 1;
-            int SF = (OpCode >> 31) & 1;
-
-            if (SF == 0 && P1 != 0)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Rd  = (OpCode >>  0) & 0x1f;
-            Imm = (OpCode >>  5) & 0xffff;
-            Pos = (OpCode >> 21) & 0x3;
-
-            Pos <<= 4;
-            Imm <<= Pos;
-
-            RegisterSize = (OpCode >> 31) != 0
-                ? ARegisterSize.Int64
-                : ARegisterSize.Int32;
-        }
-    }
-}

+ 0 - 16
ChocolArm64/Decoder/AOpCodeMul.cs

@@ -1,16 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeMul : AOpCodeAlu
-    {
-        public int Rm { get; private set; }
-        public int Ra { get; private set; }
-
-        public AOpCodeMul(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Ra = (OpCode >> 10) & 0x1f;
-            Rm = (OpCode >> 16) & 0x1f;
-        }
-    }
-}

+ 0 - 25
ChocolArm64/Decoder/AOpCodeSimd.cs

@@ -1,25 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimd : AOpCode, IAOpCodeSimd
-    {
-        public int Rd   { get; private   set; }
-        public int Rn   { get; private   set; }
-        public int Opc  { get; private   set; }
-        public int Size { get; protected set; }
-
-        public AOpCodeSimd(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rd   = (OpCode >>  0) & 0x1f;
-            Rn   = (OpCode >>  5) & 0x1f;
-            Opc  = (OpCode >> 15) & 0x3;
-            Size = (OpCode >> 22) & 0x3;
-
-            RegisterSize = ((OpCode >> 30) & 1) != 0
-                ? ARegisterSize.SIMD128
-                : ARegisterSize.SIMD64;
-        }
-    }
-}

+ 0 - 31
ChocolArm64/Decoder/AOpCodeSimdCvt.cs

@@ -1,31 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdCvt : AOpCodeSimd
-    {
-        public int FBits { get; private set; }
-
-        public AOpCodeSimdCvt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            //TODO:
-            //Und of Fixed Point variants.
-            int Scale = (OpCode >> 10) & 0x3f;
-            int SF    = (OpCode >> 31) & 0x1;
-
-            /*if (Type != SF && !(Type == 2 && SF == 1))
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }*/
-
-            FBits = 64 - Scale;
-
-            RegisterSize = SF != 0
-                ? ARegisterSize.Int64
-                : ARegisterSize.Int32;
-        }
-    }
-}

+ 0 - 14
ChocolArm64/Decoder/AOpCodeSimdExt.cs

@@ -1,14 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdExt : AOpCodeSimdReg
-    {
-        public int Imm4 { get; private set; }
-
-        public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Imm4 = (OpCode >> 11) & 0xf;
-        }
-    }
-}

+ 0 - 17
ChocolArm64/Decoder/AOpCodeSimdFcond.cs

@@ -1,17 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdFcond : AOpCodeSimdReg, IAOpCodeCond
-    {
-        public int NZCV { get; private set; }
-
-        public ACond Cond { get; private set; }
-
-        public AOpCodeSimdFcond(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            NZCV =         (OpCode >>  0) & 0xf;
-            Cond = (ACond)((OpCode >> 12) & 0xf);
-        }
-    }
-}

+ 0 - 33
ChocolArm64/Decoder/AOpCodeSimdFmov.cs

@@ -1,33 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdFmov : AOpCode, IAOpCodeSimd
-    {
-        public int  Rd   { get; private set; }
-        public long Imm  { get; private set; }
-        public int  Size { get; private set; }
-
-        public AOpCodeSimdFmov(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Imm5 = (OpCode >>  5) & 0x1f;
-            int Type = (OpCode >> 22) & 0x3;
-
-            if (Imm5 != 0b00000 || Type > 1)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Size = Type;
-
-            long Imm;
-
-            Rd  = (OpCode >>  0) & 0x1f;
-            Imm = (OpCode >> 13) & 0xff;
-
-            this.Imm = ADecoderHelper.DecodeImm8Float(Imm, Type);
-        }
-    }
-}

+ 0 - 101
ChocolArm64/Decoder/AOpCodeSimdImm.cs

@@ -1,101 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdImm : AOpCode, IAOpCodeSimd
-    {
-        public int  Rd   { get; private set; }
-        public long Imm  { get; private set; }
-        public int  Size { get; private set; }
-
-        public AOpCodeSimdImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rd = OpCode & 0x1f;
-
-            int CMode = (OpCode >> 12) & 0xf;
-            int Op    = (OpCode >> 29) & 0x1;
-
-            int ModeLow  = CMode &  1;
-            int ModeHigh = CMode >> 1;
-
-            long Imm;
-
-            Imm  = ((uint)OpCode >>  5) & 0x1f;
-            Imm |= ((uint)OpCode >> 11) & 0xe0;
-
-            if (ModeHigh == 0b111)
-            {
-                Size = ModeLow != 0 ? Op : 3;
-
-                switch (Op | (ModeLow << 1))
-                {
-                    case 0:
-                        //64-bits Immediate.
-                        //Transform abcd efgh into abcd efgh abcd efgh ...
-                        Imm = (long)((ulong)Imm * 0x0101010101010101);
-                        break;
-
-                    case 1:
-                        //64-bits Immediate.
-                        //Transform abcd efgh into aaaa aaaa bbbb bbbb ...
-                        Imm = (Imm & 0xf0) >> 4 | (Imm & 0x0f) << 4;
-                        Imm = (Imm & 0xcc) >> 2 | (Imm & 0x33) << 2;
-                        Imm = (Imm & 0xaa) >> 1 | (Imm & 0x55) << 1;
-
-                        Imm = (long)((ulong)Imm * 0x8040201008040201);
-                        Imm = (long)((ulong)Imm & 0x8080808080808080);
-
-                        Imm |= Imm >> 4;
-                        Imm |= Imm >> 2;
-                        Imm |= Imm >> 1;
-                        break;
-
-                    case 2:
-                    case 3:
-                        //Floating point Immediate.
-                        Imm = ADecoderHelper.DecodeImm8Float(Imm, Size);
-                        break;
-                }
-            }
-            else if ((ModeHigh & 0b110) == 0b100)
-            {
-                //16-bits shifted Immediate.
-                Size = 1; Imm <<= (ModeHigh & 1) << 3; 
-            }
-            else if ((ModeHigh & 0b100) == 0b000)
-            {
-                //32-bits shifted Immediate.
-                Size = 2; Imm <<= ModeHigh << 3; 
-            }
-            else if ((ModeHigh & 0b111) == 0b110)
-            {
-                //32-bits shifted Immediate (fill with ones).
-                Size = 2; Imm = ShlOnes(Imm, 8 << ModeLow);
-            }
-            else
-            {
-                //8 bits without shift.
-                Size = 0;
-            }
-
-            this.Imm = Imm;
-
-            RegisterSize = ((OpCode >> 30) & 1) != 0
-                ? ARegisterSize.SIMD128
-                : ARegisterSize.SIMD64;
-        }
-
-        private static long ShlOnes(long Value, int Shift)
-        {
-            if (Shift != 0)
-            {
-                return Value << Shift | (long)(ulong.MaxValue >> (64 - Shift));
-            }
-            else
-            {
-                return Value;
-            }
-        }
-    }
-}

+ 0 - 36
ChocolArm64/Decoder/AOpCodeSimdIns.cs

@@ -1,36 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdIns : AOpCodeSimd
-    {
-        public int SrcIndex { get; private set; }
-        public int DstIndex { get; private set; }
-
-        public AOpCodeSimdIns(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Imm4 = (OpCode >> 11) & 0xf;
-            int Imm5 = (OpCode >> 16) & 0x1f;
-
-            if (Imm5 == 0b10000)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Size = Imm5 & -Imm5;
-
-            switch (Size)
-            {
-                case 1: Size = 0; break;
-                case 2: Size = 1; break;
-                case 4: Size = 2; break;
-                case 8: Size = 3; break;
-            }
-
-            SrcIndex = Imm4 >>  Size;
-            DstIndex = Imm5 >> (Size + 1);
-        }
-    }
-}

+ 0 - 19
ChocolArm64/Decoder/AOpCodeSimdMemImm.cs

@@ -1,19 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdMemImm : AOpCodeMemImm, IAOpCodeSimd
-    {
-        public AOpCodeSimdMemImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Size |= (OpCode >> 21) & 4;
-
-            if (!WBack && !Unscaled && Size >= 4)
-            {
-                Imm <<= 4;
-            }
-
-            Extend64 = false;
-        }
-    }
-}

+ 0 - 31
ChocolArm64/Decoder/AOpCodeSimdMemLit.cs

@@ -1,31 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdMemLit : AOpCode, IAOpCodeSimd, IAOpCodeLit
-    {
-        public int  Rt   { get; private set; }
-        public long Imm  { get; private set; }
-        public int  Size { get; private set; }
-        public bool Signed   => false;
-        public bool Prefetch => false;
-
-        public AOpCodeSimdMemLit(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Opc = (OpCode >> 30) & 3;
-
-            if (Opc == 3)
-            {
-                Emitter = AInstEmit.Und;
-
-                return;
-            }
-
-            Rt = OpCode & 0x1f;
-
-            Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
-
-            Size = Opc + 2;
-        }
-    }
-}

+ 0 - 16
ChocolArm64/Decoder/AOpCodeSimdMemPair.cs

@@ -1,16 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdMemPair : AOpCodeMemPair, IAOpCodeSimd
-    {
-        public AOpCodeSimdMemPair(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Size = ((OpCode >> 30) & 3) + 2;
-
-            Extend64 = false;
-
-            DecodeImm(OpCode);
-        }
-    }
-}

+ 0 - 14
ChocolArm64/Decoder/AOpCodeSimdMemReg.cs

@@ -1,14 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdMemReg : AOpCodeMemReg, IAOpCodeSimd
-    {
-        public AOpCodeSimdMemReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Size |= (OpCode >> 21) & 4;
-
-            Extend64 = false;
-        }
-    }
-}

+ 0 - 98
ChocolArm64/Decoder/AOpCodeSimdMemSs.cs

@@ -1,98 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdMemSs : AOpCodeMemReg, IAOpCodeSimd
-    {
-        public int  SElems    { get; private set; }
-        public int  Index     { get; private set; }
-        public bool Replicate { get; private set; }
-        public bool WBack     { get; private set; }
-
-        public AOpCodeSimdMemSs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            int Size   = (OpCode >> 10) & 3;
-            int S      = (OpCode >> 12) & 1;
-            int SElems = (OpCode >> 12) & 2;
-            int Scale  = (OpCode >> 14) & 3;
-            int L      = (OpCode >> 22) & 1;
-            int Q      = (OpCode >> 30) & 1;
-
-            SElems |= (OpCode >> 21) & 1;
-
-            SElems++;
-
-            int Index = (Q << 3) | (S << 2) | Size;
-
-            switch (Scale)
-            {
-                case 1:
-                {
-                    if ((Size & 1) != 0)
-                    {
-                        Inst = AInst.Undefined;
-
-                        return;
-                    }
-
-                    Index >>= 1;
-
-                    break;
-                }
-
-                case 2:
-                {
-                    if ((Size & 2) != 0 ||
-                       ((Size & 1) != 0 && S != 0))
-                    {
-                        Inst = AInst.Undefined;
-
-                        return;
-                    }
-
-                    if ((Size & 1) != 0)
-                    {
-                        Index >>= 3;
-
-                        Scale = 3;
-                    }
-                    else
-                    {
-                        Index >>= 2;
-                    }
-
-                    break;
-                }
-
-                case 3:
-                {
-                    if (L == 0 || S != 0)
-                    {
-                        Inst = AInst.Undefined;
-
-                        return;
-                    }
-
-                    Scale = Size;
-
-                    Replicate = true;
-
-                    break;
-                }
-            }
-
-            this.Index  = Index;
-            this.SElems = SElems;
-            this.Size   = Scale;
-
-            Extend64 = false;
-
-            WBack = ((OpCode >> 23) & 1) != 0;
-
-            RegisterSize = Q != 0
-                ? ARegisterSize.SIMD128
-                : ARegisterSize.SIMD64;
-        }
-    }
-}

+ 0 - 18
ChocolArm64/Decoder/AOpCodeSimdReg.cs

@@ -1,18 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdReg : AOpCodeSimd
-    {
-        public bool Bit3 { get; private   set; }
-        public int  Ra   { get; private   set; }
-        public int  Rm   { get; protected set; }
-
-        public AOpCodeSimdReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Bit3 = ((OpCode >>  3) & 0x1) != 0;
-            Ra   =  (OpCode >> 10) & 0x1f;
-            Rm   =  (OpCode >> 16) & 0x1f;
-        }
-    }
-}

+ 0 - 31
ChocolArm64/Decoder/AOpCodeSimdRegElem.cs

@@ -1,31 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdRegElem : AOpCodeSimdReg
-    {
-        public int Index { get; private set; }
-
-        public AOpCodeSimdRegElem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            switch (Size)
-            {
-                case 1:
-                    Index = (OpCode >> 20) & 3 |
-                            (OpCode >>  9) & 4;
-
-                    Rm &= 0xf;
-
-                    break;
-
-                case 2:
-                    Index = (OpCode >> 21) & 1 |
-                            (OpCode >> 10) & 2;
-
-                    break;
-
-                default: Emitter = AInstEmit.Und; return;
-            }
-        }
-    }
-}

+ 0 - 33
ChocolArm64/Decoder/AOpCodeSimdRegElemF.cs

@@ -1,33 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdRegElemF : AOpCodeSimdReg
-    {
-        public int Index { get; private set; }
-
-        public AOpCodeSimdRegElemF(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            switch ((OpCode >> 21) & 3) // sz:L
-            {
-                case 0: // H:0
-                    Index = (OpCode >> 10) & 2; // 0, 2
-
-                    break;
-
-                case 1: // H:1
-                    Index = (OpCode >> 10) & 2;
-                    Index++; // 1, 3
-
-                    break;
-
-                case 2: // H
-                    Index = (OpCode >> 11) & 1; // 0, 1
-
-                    break;
-
-                default: Emitter = AInstEmit.Und; return;
-            }
-        }
-    }
-}

+ 0 - 16
ChocolArm64/Decoder/AOpCodeSimdShImm.cs

@@ -1,16 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdShImm : AOpCodeSimd
-    {
-        public int Imm { get; private set; }
-
-        public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Imm = (OpCode >> 16) & 0x7f;
-
-            Size = ABitUtils.HighestBitSetNibble(Imm >> 3);
-        }
-    }
-}

+ 0 - 12
ChocolArm64/Decoder/AOpCodeSimdTbl.cs

@@ -1,12 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSimdTbl : AOpCodeSimdReg
-    {
-        public AOpCodeSimdTbl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Size = ((OpCode >> 13) & 3) + 1;
-        }
-    }
-}

+ 0 - 24
ChocolArm64/Decoder/AOpCodeSystem.cs

@@ -1,24 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder
-{
-    class AOpCodeSystem : AOpCode
-    {
-        public int Rt  { get; private set; }
-        public int Op2 { get; private set; }
-        public int CRm { get; private set; }
-        public int CRn { get; private set; }
-        public int Op1 { get; private set; }
-        public int Op0 { get; private set; }
-
-        public AOpCodeSystem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Rt  =  (OpCode >>  0) & 0x1f;
-            Op2 =  (OpCode >>  5) & 0x7;
-            CRm =  (OpCode >>  8) & 0xf;
-            CRn =  (OpCode >> 12) & 0xf;
-            Op1 =  (OpCode >> 16) & 0x7;
-            Op0 = ((OpCode >> 19) & 0x1) | 2;
-        }
-    }
-}

+ 0 - 13
ChocolArm64/Decoder/IAOpCode.cs

@@ -1,13 +0,0 @@
-using ChocolArm64.Instruction;
-using ChocolArm64.State;
-
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCode
-    {
-        long Position { get; }
-
-        AInstEmitter  Emitter      { get; }
-        ARegisterSize RegisterSize { get; }
-    }
-}

+ 0 - 10
ChocolArm64/Decoder/IAOpCodeAlu.cs

@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeAlu : IAOpCode
-    {
-        int Rd { get; }
-        int Rn { get; }
-
-        ADataOp DataOp { get; }
-    }
-}

+ 0 - 7
ChocolArm64/Decoder/IAOpCodeAluImm.cs

@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeAluImm : IAOpCodeAlu
-    {
-        long Imm { get; }
-    }
-}

+ 0 - 10
ChocolArm64/Decoder/IAOpCodeAluRs.cs

@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeAluRs : IAOpCodeAlu
-    {
-        int Shift { get; }
-        int Rm    { get; }
-
-        AShiftType ShiftType { get; }
-    }
-}

+ 0 - 10
ChocolArm64/Decoder/IAOpCodeAluRx.cs

@@ -1,10 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeAluRx : IAOpCodeAlu
-    {
-        int Shift { get; }
-        int Rm    { get; }
-
-        AIntType IntType { get; }
-    }
-}

+ 0 - 7
ChocolArm64/Decoder/IAOpCodeCond.cs

@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeCond : IAOpCode
-    {
-        ACond Cond { get; }
-    }
-}

+ 0 - 7
ChocolArm64/Decoder/IAOpCodeSimd.cs

@@ -1,7 +0,0 @@
-namespace ChocolArm64.Decoder
-{
-    interface IAOpCodeSimd : IAOpCode
-    {
-        int Size { get; }
-    }
-}

+ 0 - 15
ChocolArm64/Decoder32/A32OpCode.cs

@@ -1,15 +0,0 @@
-using ChocolArm64.Decoder;
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder32
-{
-    class A32OpCode : AOpCode
-    {
-        public ACond Cond { get; private set; }
-
-        public A32OpCode(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Cond = (ACond)((uint)OpCode >> 28);
-        }
-    }
-}

+ 0 - 16
ChocolArm64/Decoder32/A32OpCodeBImmAl.cs

@@ -1,16 +0,0 @@
-using ChocolArm64.Instruction;
-
-namespace ChocolArm64.Decoder32
-{
-    class A32OpCodeBImmAl : A32OpCode
-    {
-        public int Imm;
-        public int H;
-
-        public A32OpCodeBImmAl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
-        {
-            Imm = (OpCode <<  8) >> 6;
-            H   = (OpCode >> 23) &  2;
-        }
-    }
-}

+ 35 - 0
ChocolArm64/Decoders/Block.cs

@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+
+namespace ChocolArm64.Decoders
+{
+    class Block
+    {
+        public long Position    { get; set; }
+        public long EndPosition { get; set; }
+
+        public Block Next   { get; set; }
+        public Block Branch { get; set; }
+
+        public List<OpCode64> OpCodes { get; private set; }
+
+        public Block()
+        {
+            OpCodes = new List<OpCode64>();
+        }
+
+        public Block(long position) : this()
+        {
+            Position = position;
+        }
+
+        public OpCode64 GetLastOp()
+        {
+            if (OpCodes.Count > 0)
+            {
+                return OpCodes[OpCodes.Count - 1];
+            }
+
+            return null;
+        }
+    }
+}

+ 22 - 0
ChocolArm64/Decoders/Cond.cs

@@ -0,0 +1,22 @@
+namespace ChocolArm64.Decoders
+{
+    enum Cond
+    {
+        Eq   = 0,
+        Ne   = 1,
+        GeUn = 2,
+        LtUn = 3,
+        Mi   = 4,
+        Pl   = 5,
+        Vs   = 6,
+        Vc   = 7,
+        GtUn = 8,
+        LeUn = 9,
+        Ge   = 10,
+        Lt   = 11,
+        Gt   = 12,
+        Le   = 13,
+        Al   = 14,
+        Nv   = 15
+    }
+}

+ 2 - 2
ChocolArm64/Decoder/ADataOp.cs → ChocolArm64/Decoders/DataOp.cs

@@ -1,6 +1,6 @@
-namespace ChocolArm64.Decoder
+namespace ChocolArm64.Decoders
 {
-    enum ADataOp
+    enum DataOp
     {
         Adr        = 0,
         Arithmetic = 1,

+ 239 - 0
ChocolArm64/Decoders/Decoder.cs

@@ -0,0 +1,239 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.Memory;
+using ChocolArm64.State;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Reflection.Emit;
+
+namespace ChocolArm64.Decoders
+{
+    static class Decoder
+    {
+        private delegate object OpActivator(Inst inst, long position, int opCode);
+
+        private static ConcurrentDictionary<Type, OpActivator> _opActivators;
+
+        static Decoder()
+        {
+            _opActivators = new ConcurrentDictionary<Type, OpActivator>();
+        }
+
+        public static Block DecodeBasicBlock(CpuThreadState state, MemoryManager memory, long start)
+        {
+            Block block = new Block(start);
+
+            FillBlock(state, memory, block);
+
+            return block;
+        }
+
+        public static (Block[] Graph, Block Root) DecodeSubroutine(
+            TranslatorCache  cache,
+            CpuThreadState   state,
+            MemoryManager    memory,
+            long             start)
+        {
+            Dictionary<long, Block> visited    = new Dictionary<long, Block>();
+            Dictionary<long, Block> visitedEnd = new Dictionary<long, Block>();
+
+            Queue<Block> blocks = new Queue<Block>();
+
+            Block Enqueue(long position)
+            {
+                if (!visited.TryGetValue(position, out Block output))
+                {
+                    output = new Block(position);
+
+                    blocks.Enqueue(output);
+
+                    visited.Add(position, output);
+                }
+
+                return output;
+            }
+
+            Block root = Enqueue(start);
+
+            while (blocks.Count > 0)
+            {
+                Block current = blocks.Dequeue();
+
+                FillBlock(state, memory, current);
+
+                //Set child blocks. "Branch" is the block the branch instruction
+                //points to (when taken), "Next" is the block at the next address,
+                //executed when the branch is not taken. For Unconditional Branches
+                //(except BL/BLR that are sub calls) or end of executable, Next is null.
+                if (current.OpCodes.Count > 0)
+                {
+                    bool hasCachedSub = false;
+
+                    OpCode64 lastOp = current.GetLastOp();
+
+                    if (lastOp is OpCodeBImm64 op)
+                    {
+                        if (op.Emitter == InstEmit.Bl)
+                        {
+                            hasCachedSub = cache.HasSubroutine(op.Imm);
+                        }
+                        else
+                        {
+                            current.Branch = Enqueue(op.Imm);
+                        }
+                    }
+
+                    if (!((lastOp is OpCodeBImmAl64) ||
+                          (lastOp is OpCodeBReg64)) || hasCachedSub)
+                    {
+                        current.Next = Enqueue(current.EndPosition);
+                    }
+                }
+
+                //If we have on the graph two blocks with the same end position,
+                //then we need to split the bigger block and have two small blocks,
+                //the end position of the bigger "Current" block should then be == to
+                //the position of the "Smaller" block.
+                while (visitedEnd.TryGetValue(current.EndPosition, out Block smaller))
+                {
+                    if (current.Position > smaller.Position)
+                    {
+                        Block temp = smaller;
+
+                        smaller = current;
+                        current = temp;
+                    }
+
+                    current.EndPosition = smaller.Position;
+                    current.Next        = smaller;
+                    current.Branch      = null;
+
+                    current.OpCodes.RemoveRange(
+                        current.OpCodes.Count - smaller.OpCodes.Count,
+                        smaller.OpCodes.Count);
+
+                    visitedEnd[smaller.EndPosition] = smaller;
+                }
+
+                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);
+        }
+
+        private static void FillBlock(CpuThreadState state, MemoryManager memory, Block block)
+        {
+            long position = block.Position;
+
+            OpCode64 opCode;
+
+            do
+            {
+                //TODO: This needs to be changed to support both AArch32 and AArch64,
+                //once JIT support is introduced on AArch32 aswell.
+                opCode = DecodeOpCode(state, memory, position);
+
+                block.OpCodes.Add(opCode);
+
+                position += 4;
+            }
+            while (!(IsBranch(opCode) || IsException(opCode)));
+
+            block.EndPosition = position;
+        }
+
+        private static bool IsBranch(OpCode64 opCode)
+        {
+            return opCode is OpCodeBImm64 ||
+                   opCode is OpCodeBReg64;
+        }
+
+        private static bool IsException(OpCode64 opCode)
+        {
+            return opCode.Emitter == InstEmit.Brk ||
+                   opCode.Emitter == InstEmit.Svc ||
+                   opCode.Emitter == InstEmit.Und;
+        }
+
+        public static OpCode64 DecodeOpCode(CpuThreadState state, MemoryManager memory, long position)
+        {
+            int opCode = memory.ReadInt32(position);
+
+            Inst inst;
+
+            if (state.ExecutionMode == ExecutionMode.AArch64)
+            {
+                inst = OpCodeTable.GetInstA64(opCode);
+            }
+            else
+            {
+                //TODO: Thumb support.
+                inst = OpCodeTable.GetInstA32(opCode);
+            }
+
+            OpCode64 decodedOpCode = new OpCode64(Inst.Undefined, position, opCode);
+
+            if (inst.Type != null)
+            {
+                decodedOpCode = MakeOpCode(inst.Type, inst, position, opCode);
+            }
+
+            return decodedOpCode;
+        }
+
+        private static OpCode64 MakeOpCode(Type type, Inst inst, long position, int opCode)
+        {
+            if (type == null)
+            {
+                throw new ArgumentNullException(nameof(type));
+            }
+
+            OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
+
+            return (OpCode64)createInstance(inst, position, opCode);
+        }
+
+        private static OpActivator CacheOpActivator(Type type)
+        {
+            Type[] argTypes = new Type[] { typeof(Inst), typeof(long), typeof(int) };
+
+            DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes);
+
+            ILGenerator generator = mthd.GetILGenerator();
+
+            generator.Emit(OpCodes.Ldarg_0);
+            generator.Emit(OpCodes.Ldarg_1);
+            generator.Emit(OpCodes.Ldarg_2);
+            generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes));
+            generator.Emit(OpCodes.Ret);
+
+            return (OpActivator)mthd.CreateDelegate(typeof(OpActivator));
+        }
+    }
+}

+ 107 - 0
ChocolArm64/Decoders/DecoderHelper.cs

@@ -0,0 +1,107 @@
+using System;
+
+namespace ChocolArm64.Decoders
+{
+    static class DecoderHelper
+    {
+        public struct BitMask
+        {
+            public long WMask;
+            public long TMask;
+            public int  Pos;
+            public int  Shift;
+            public bool IsUndefined;
+
+            public static BitMask Invalid => new BitMask { IsUndefined = true };
+        }
+
+        public static BitMask DecodeBitMask(int opCode, bool immediate)
+        {
+            int immS = (opCode >> 10) & 0x3f;
+            int immR = (opCode >> 16) & 0x3f;
+
+            int n  = (opCode >> 22) & 1;
+            int sf = (opCode >> 31) & 1;
+
+            int length = BitUtils.HighestBitSet32((~immS & 0x3f) | (n << 6));
+
+            if (length < 1 || (sf == 0 && n != 0))
+            {
+                return BitMask.Invalid;
+            }
+
+            int size = 1 << length;
+
+            int levels = size - 1;
+
+            int s = immS & levels;
+            int r = immR & levels;
+
+            if (immediate && s == levels)
+            {
+                return BitMask.Invalid;
+            }
+
+            long wMask = BitUtils.FillWithOnes(s + 1);
+            long tMask = BitUtils.FillWithOnes(((s - r) & levels) + 1);
+
+            if (r > 0)
+            {
+                wMask  = BitUtils.RotateRight(wMask, r, size);
+                wMask &= BitUtils.FillWithOnes(size);
+            }
+
+            return new BitMask()
+            {
+                WMask = BitUtils.Replicate(wMask, size),
+                TMask = BitUtils.Replicate(tMask, size),
+
+                Pos   = immS,
+                Shift = immR
+            };
+        }
+
+        public static long DecodeImm8Float(long imm, int size)
+        {
+            int e = 0, f = 0;
+
+            switch (size)
+            {
+                case 0: e =  8; f = 23; break;
+                case 1: e = 11; f = 52; break;
+
+                default: throw new ArgumentOutOfRangeException(nameof(size));
+            }
+
+            long value = (imm & 0x3f) << f - 4;
+
+            long eBit = (imm >> 6) & 1;
+            long sBit = (imm >> 7) & 1;
+
+            if (eBit != 0)
+            {
+                value |= (1L << e - 3) - 1 << f + 2;
+            }
+
+            value |= (eBit ^ 1) << f + e - 1;
+            value |=  sBit      << f + e;
+
+            return value;
+        }
+
+        public static long DecodeImm26_2(int opCode)
+        {
+            return ((long)opCode << 38) >> 36;
+        }
+
+        public static long DecodeImmS19_2(int opCode)
+        {
+            return (((long)opCode << 40) >> 43) & ~3;
+        }
+
+        public static long DecodeImmS14_2(int opCode)
+        {
+            return (((long)opCode << 45) >> 48) & ~3;
+        }
+    }
+}

+ 13 - 0
ChocolArm64/Decoders/IOpCode64.cs

@@ -0,0 +1,13 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.State;
+
+namespace ChocolArm64.Decoders
+{
+    interface IOpCode64
+    {
+        long Position { get; }
+
+        InstEmitter  Emitter      { get; }
+        RegisterSize RegisterSize { get; }
+    }
+}

+ 10 - 0
ChocolArm64/Decoders/IOpCodeAlu64.cs

@@ -0,0 +1,10 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeAlu64 : IOpCode64
+    {
+        int Rd { get; }
+        int Rn { get; }
+
+        DataOp DataOp { get; }
+    }
+}

+ 7 - 0
ChocolArm64/Decoders/IOpCodeAluImm64.cs

@@ -0,0 +1,7 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeAluImm64 : IOpCodeAlu64
+    {
+        long Imm { get; }
+    }
+}

+ 10 - 0
ChocolArm64/Decoders/IOpCodeAluRs64.cs

@@ -0,0 +1,10 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeAluRs64 : IOpCodeAlu64
+    {
+        int Shift { get; }
+        int Rm    { get; }
+
+        ShiftType ShiftType { get; }
+    }
+}

+ 10 - 0
ChocolArm64/Decoders/IOpCodeAluRx64.cs

@@ -0,0 +1,10 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeAluRx64 : IOpCodeAlu64
+    {
+        int Shift { get; }
+        int Rm    { get; }
+
+        IntType IntType { get; }
+    }
+}

+ 7 - 0
ChocolArm64/Decoders/IOpCodeCond64.cs

@@ -0,0 +1,7 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeCond64 : IOpCode64
+    {
+        Cond Cond { get; }
+    }
+}

+ 2 - 2
ChocolArm64/Decoder/IAOpCodeLit.cs → ChocolArm64/Decoders/IOpCodeLit64.cs

@@ -1,6 +1,6 @@
-namespace ChocolArm64.Decoder
+namespace ChocolArm64.Decoders
 {
-    interface IAOpCodeLit : IAOpCode
+    interface IOpCodeLit64 : IOpCode64
     {
         int  Rt       { get; }
         long Imm      { get; }

+ 7 - 0
ChocolArm64/Decoders/IOpCodeSimd64.cs

@@ -0,0 +1,7 @@
+namespace ChocolArm64.Decoders
+{
+    interface IOpCodeSimd64 : IOpCode64
+    {
+        int Size { get; }
+    }
+}

+ 2 - 2
ChocolArm64/Decoder/AIntType.cs → ChocolArm64/Decoders/IntType.cs

@@ -1,6 +1,6 @@
-namespace ChocolArm64.Decoder
+namespace ChocolArm64.Decoders
 {
-    enum AIntType
+    enum IntType
     {
         UInt8  = 0,
         UInt16 = 1,

+ 40 - 0
ChocolArm64/Decoders/OpCode64.cs

@@ -0,0 +1,40 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.State;
+using System;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCode64 : IOpCode64
+    {
+        public long Position  { get; private set; }
+        public int  RawOpCode { get; private set; }
+
+        public InstEmitter     Emitter      { get; protected set; }
+        public InstInterpreter Interpreter  { get; protected set; }
+        public RegisterSize    RegisterSize { get; protected set; }
+
+        public OpCode64(Inst inst, long position, int opCode)
+        {
+            Position  = position;
+            RawOpCode = opCode;
+
+            RegisterSize = RegisterSize.Int64;
+
+            Emitter     = inst.Emitter;
+            Interpreter = inst.Interpreter;
+        }
+
+        public int GetBitsCount()
+        {
+            switch (RegisterSize)
+            {
+                case RegisterSize.Int32:   return 32;
+                case RegisterSize.Int64:   return 64;
+                case RegisterSize.Simd64:  return 64;
+                case RegisterSize.Simd128: return 128;
+            }
+
+            throw new InvalidOperationException();
+        }
+    }
+}

+ 18 - 0
ChocolArm64/Decoders/OpCodeAdr64.cs

@@ -0,0 +1,18 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeAdr64 : OpCode64
+    {
+        public int  Rd  { get; private set; }
+        public long Imm { get; private set; }
+
+         public OpCodeAdr64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rd = opCode & 0x1f;
+
+            Imm  = DecoderHelper.DecodeImmS19_2(opCode);
+            Imm |= ((long)opCode >> 29) & 3;
+        }
+    }
+}

+ 24 - 0
ChocolArm64/Decoders/OpCodeAlu64.cs

@@ -0,0 +1,24 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.State;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeAlu64 : OpCode64, IOpCodeAlu64
+    {
+        public int Rd { get; protected set; }
+        public int Rn { get; private   set; }
+
+        public DataOp DataOp { get; private set; }
+
+        public OpCodeAlu64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rd     =           (opCode >>  0) & 0x1f;
+            Rn     =           (opCode >>  5) & 0x1f;
+            DataOp = (DataOp)((opCode >> 24) & 0x3);
+
+            RegisterSize = (opCode >> 31) != 0
+                ? State.RegisterSize.Int64
+                : State.RegisterSize.Int32;
+        }
+    }
+}

+ 39 - 0
ChocolArm64/Decoders/OpCodeAluImm64.cs

@@ -0,0 +1,39 @@
+using ChocolArm64.Instructions;
+using System;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeAluImm64 : OpCodeAlu64, IOpCodeAluImm64
+    {
+        public long Imm { get; private set; }
+
+        public OpCodeAluImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            if (DataOp == DataOp.Arithmetic)
+            {
+                Imm = (opCode >> 10) & 0xfff;
+
+                int shift = (opCode >> 22) & 3;
+
+                Imm <<= shift * 12;
+            }
+            else if (DataOp == DataOp.Logical)
+            {
+                var bm = DecoderHelper.DecodeBitMask(opCode, true);
+
+                if (bm.IsUndefined)
+                {
+                    Emitter = InstEmit.Und;
+
+                    return;
+                }
+
+                Imm = bm.WMask;
+            }
+            else
+            {
+                throw new ArgumentException(nameof(opCode));
+            }
+        }
+    }
+}

+ 29 - 0
ChocolArm64/Decoders/OpCodeAluRs64.cs

@@ -0,0 +1,29 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeAluRs64 : OpCodeAlu64, IOpCodeAluRs64
+    {
+        public int Shift { get; private set; }
+        public int Rm    { get; private set; }
+
+        public ShiftType ShiftType { get; private set; }
+
+        public OpCodeAluRs64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            int shift = (opCode >> 10) & 0x3f;
+
+            if (shift >= GetBitsCount())
+            {
+                Emitter = InstEmit.Und;
+
+                return;
+            }
+
+            Shift = shift;
+
+            Rm        =              (opCode >> 16) & 0x1f;
+            ShiftType = (ShiftType)((opCode >> 22) & 0x3);
+        }
+    }
+}

+ 19 - 0
ChocolArm64/Decoders/OpCodeAluRx64.cs

@@ -0,0 +1,19 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeAluRx64 : OpCodeAlu64, IOpCodeAluRx64
+    {
+        public int Shift { get; private set; }
+        public int Rm    { get; private set; }
+
+        public IntType IntType { get; private set; }
+
+        public OpCodeAluRx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Shift   =            (opCode >> 10) & 0x7;
+            IntType = (IntType)((opCode >> 13) & 0x7);
+            Rm      =            (opCode >> 16) & 0x1f;
+        }
+    }
+}

+ 11 - 0
ChocolArm64/Decoders/OpCodeBImm64.cs

@@ -0,0 +1,11 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBImm64 : OpCode64
+    {
+        public long Imm { get; protected set; }
+
+        public OpCodeBImm64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
+    }
+}

+ 12 - 0
ChocolArm64/Decoders/OpCodeBImmAl64.cs

@@ -0,0 +1,12 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBImmAl64 : OpCodeBImm64
+    {
+        public OpCodeBImmAl64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Imm = position + DecoderHelper.DecodeImm26_2(opCode);
+        }
+    }
+}

+ 21 - 0
ChocolArm64/Decoders/OpCodeBImmCmp64.cs

@@ -0,0 +1,21 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.State;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBImmCmp64 : OpCodeBImm64
+    {
+        public int Rt { get; private set; }
+
+        public OpCodeBImmCmp64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rt = opCode & 0x1f;
+
+            Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
+
+            RegisterSize = (opCode >> 31) != 0
+                ? State.RegisterSize.Int64
+                : State.RegisterSize.Int32;
+        }
+    }
+}

+ 25 - 0
ChocolArm64/Decoders/OpCodeBImmCond64.cs

@@ -0,0 +1,25 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBImmCond64 : OpCodeBImm64, IOpCodeCond64
+    {
+        public Cond Cond { get; private set; }
+
+        public OpCodeBImmCond64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            int o0 = (opCode >> 4) & 1;
+
+            if (o0 != 0)
+            {
+                Emitter = InstEmit.Und;
+
+                return;
+            }
+
+            Cond = (Cond)(opCode & 0xf);
+
+            Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
+        }
+    }
+}

+ 20 - 0
ChocolArm64/Decoders/OpCodeBImmTest64.cs

@@ -0,0 +1,20 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBImmTest64 : OpCodeBImm64
+    {
+        public int Rt  { get; private set; }
+        public int Pos { get; private set; }
+
+        public OpCodeBImmTest64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rt = opCode & 0x1f;
+
+            Imm = position + DecoderHelper.DecodeImmS14_2(opCode);
+
+            Pos  = (opCode >> 19) & 0x1f;
+            Pos |= (opCode >> 26) & 0x20;
+        }
+    }
+}

+ 24 - 0
ChocolArm64/Decoders/OpCodeBReg64.cs

@@ -0,0 +1,24 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBReg64 : OpCode64
+    {
+        public int Rn { get; private set; }
+
+        public OpCodeBReg64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            int op4 = (opCode >>  0) & 0x1f;
+            int op2 = (opCode >> 16) & 0x1f;
+
+            if (op2 != 0b11111 || op4 != 0b00000)
+            {
+                Emitter = InstEmit.Und;
+
+                return;
+            }
+
+            Rn = (opCode >> 5) & 0x1f;
+        }
+    }
+}

+ 29 - 0
ChocolArm64/Decoders/OpCodeBfm64.cs

@@ -0,0 +1,29 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeBfm64 : OpCodeAlu64
+    {
+        public long WMask { get; private set; }
+        public long TMask { get; private set; }
+        public int  Pos   { get; private set; }
+        public int  Shift { get; private set; }
+
+        public OpCodeBfm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            var bm = DecoderHelper.DecodeBitMask(opCode, false);
+
+            if (bm.IsUndefined)
+            {
+                Emitter = InstEmit.Und;
+
+                return;
+            }
+
+            WMask = bm.WMask;
+            TMask = bm.TMask;
+            Pos   = bm.Pos;
+            Shift = bm.Shift;
+        }
+    }
+}

+ 31 - 0
ChocolArm64/Decoders/OpCodeCcmp64.cs

@@ -0,0 +1,31 @@
+using ChocolArm64.Instructions;
+using ChocolArm64.State;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeCcmp64 : OpCodeAlu64, IOpCodeCond64
+    {
+        public    int Nzcv { get; private set; }
+        protected int RmImm;
+
+        public Cond Cond { get; private set; }
+
+        public OpCodeCcmp64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            int o3 = (opCode >> 4) & 1;
+
+            if (o3 != 0)
+            {
+                Emitter = InstEmit.Und;
+
+                return;
+            }
+
+            Nzcv  =         (opCode >>  0) & 0xf;
+            Cond  = (Cond)((opCode >> 12) & 0xf);
+            RmImm =         (opCode >> 16) & 0x1f;
+
+            Rd = CpuThreadState.ZrIndex;
+        }
+    }
+}

+ 11 - 0
ChocolArm64/Decoders/OpCodeCcmpImm64.cs

@@ -0,0 +1,11 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeCcmpImm64 : OpCodeCcmp64, IOpCodeAluImm64
+    {
+        public long Imm => RmImm;
+
+        public OpCodeCcmpImm64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
+    }
+}

+ 15 - 0
ChocolArm64/Decoders/OpCodeCcmpReg64.cs

@@ -0,0 +1,15 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeCcmpReg64 : OpCodeCcmp64, IOpCodeAluRs64
+    {
+        public int Rm => RmImm;
+
+        public int Shift => 0;
+
+        public ShiftType ShiftType => ShiftType.Lsl;
+
+        public OpCodeCcmpReg64(Inst inst, long position, int opCode) : base(inst, position, opCode) { }
+    }
+}

+ 17 - 0
ChocolArm64/Decoders/OpCodeCsel64.cs

@@ -0,0 +1,17 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeCsel64 : OpCodeAlu64, IOpCodeCond64
+    {
+        public int Rm { get; private set; }
+
+        public Cond Cond { get; private set; }
+
+        public OpCodeCsel64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rm   =         (opCode >> 16) & 0x1f;
+            Cond = (Cond)((opCode >> 12) & 0xf);
+        }
+    }
+}

+ 14 - 0
ChocolArm64/Decoders/OpCodeException64.cs

@@ -0,0 +1,14 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeException64 : OpCode64
+    {
+        public int Id { get; private set; }
+
+        public OpCodeException64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Id = (opCode >> 5) & 0xffff;
+        }
+    }
+}

+ 19 - 0
ChocolArm64/Decoders/OpCodeMem64.cs

@@ -0,0 +1,19 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeMem64 : OpCode64
+    {
+        public int  Rt       { get; protected set; }
+        public int  Rn       { get; protected set; }
+        public int  Size     { get; protected set; }
+        public bool Extend64 { get; protected set; }
+
+        public OpCodeMem64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rt   = (opCode >>  0) & 0x1f;
+            Rn   = (opCode >>  5) & 0x1f;
+            Size = (opCode >> 30) & 0x3;
+        }
+    }
+}

+ 16 - 0
ChocolArm64/Decoders/OpCodeMemEx64.cs

@@ -0,0 +1,16 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeMemEx64 : OpCodeMem64
+    {
+        public int Rt2 { get; private set; }
+        public int Rs  { get; private set; }
+
+        public OpCodeMemEx64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rt2 = (opCode >> 10) & 0x1f;
+            Rs  = (opCode >> 16) & 0x1f;
+        }
+    }
+}

+ 12 - 12
ChocolArm64/Decoder/AOpCodeMemImm.cs → ChocolArm64/Decoders/OpCodeMemImm64.cs

@@ -1,8 +1,8 @@
-using ChocolArm64.Instruction;
+using ChocolArm64.Instructions;
 
-namespace ChocolArm64.Decoder
+namespace ChocolArm64.Decoders
 {
-    class AOpCodeMemImm : AOpCodeMem
+    class OpCodeMemImm64 : OpCodeMem64
     {
         public    long Imm      { get; protected set; }
         public    bool WBack    { get; protected set; }
@@ -18,18 +18,18 @@ namespace ChocolArm64.Decoder
             Unsigned
         }
 
-        public AOpCodeMemImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
+        public OpCodeMemImm64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Extend64 = ((OpCode >> 22) & 3) == 2;
-            WBack    = ((OpCode >> 24) & 1) == 0;
+            Extend64 = ((opCode >> 22) & 3) == 2;
+            WBack    = ((opCode >> 24) & 1) == 0;
 
             //The type is not valid for the Unsigned Immediate 12-bits encoding,
             //because the bits 11:10 are used for the larger Immediate offset.
-            MemOp Type = WBack ? (MemOp)((OpCode >> 10) & 3) : MemOp.Unsigned;
+            MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
 
-            PostIdx  = Type == MemOp.PostIndexed;
-            Unscaled = Type == MemOp.Unscaled ||
-                       Type == MemOp.Unprivileged;
+            PostIdx  = type == MemOp.PostIndexed;
+            Unscaled = type == MemOp.Unscaled ||
+                       type == MemOp.Unprivileged;
 
             //Unscaled and Unprivileged doesn't write back,
             //but they do use the 9-bits Signed Immediate.
@@ -41,12 +41,12 @@ namespace ChocolArm64.Decoder
             if (WBack || Unscaled)
             {
                 //9-bits Signed Immediate.
-                Imm = (OpCode << 43) >> 55;
+                Imm = (opCode << 43) >> 55;
             }
             else
             {
                 //12-bits Unsigned Immediate.
-                Imm = ((OpCode >> 10) & 0xfff) << Size;
+                Imm = ((opCode >> 10) & 0xfff) << Size;
             }
         }
     }

+ 7 - 7
ChocolArm64/Decoder/AOpCodeMemLit.cs → ChocolArm64/Decoders/OpCodeMemLit64.cs

@@ -1,8 +1,8 @@
-using ChocolArm64.Instruction;
+using ChocolArm64.Instructions;
 
-namespace ChocolArm64.Decoder
+namespace ChocolArm64.Decoders
 {
-    class AOpCodeMemLit : AOpCode, IAOpCodeLit
+    class OpCodeMemLit64 : OpCode64, IOpCodeLit64
     {
         public int  Rt       { get; private set; }
         public long Imm      { get; private set; }
@@ -10,13 +10,13 @@ namespace ChocolArm64.Decoder
         public bool Signed   { get; private set; }
         public bool Prefetch { get; private set; }
 
-        public AOpCodeMemLit(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
+        public OpCodeMemLit64(Inst inst, long position, int opCode) : base(inst, position, opCode)
         {
-            Rt = OpCode & 0x1f;
+            Rt = opCode & 0x1f;
 
-            Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
+            Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
 
-            switch ((OpCode >> 30) & 3)
+            switch ((opCode >> 30) & 3)
             {
                 case 0: Size = 2; Signed = false; Prefetch = false; break;
                 case 1: Size = 3; Signed = false; Prefetch = false; break;

+ 25 - 0
ChocolArm64/Decoders/OpCodeMemPair64.cs

@@ -0,0 +1,25 @@
+using ChocolArm64.Instructions;
+
+namespace ChocolArm64.Decoders
+{
+    class OpCodeMemPair64 : OpCodeMemImm64
+    {
+        public int Rt2 { get; private set; }
+
+        public OpCodeMemPair64(Inst inst, long position, int opCode) : base(inst, position, opCode)
+        {
+            Rt2      =  (opCode >> 10) & 0x1f;
+            WBack    = ((opCode >> 23) & 0x1) != 0;
+            PostIdx  = ((opCode >> 23) & 0x3) == 1;
+            Extend64 = ((opCode >> 30) & 0x3) == 1;
+            Size     = ((opCode >> 31) & 0x1) | 2;
+
+            DecodeImm(opCode);
+        }
+
+        protected void DecodeImm(int opCode)
+        {
+            Imm = ((long)(opCode >> 15) << 57) >> (57 - Size);
+        }
+    }
+}

Деякі файли не було показано, через те що забагато файлів було змінено