Просмотр исходного кода

AOpCodeTable: Speed up instruction decoding (#284)

Merry 7 лет назад
Родитель
Сommit
bdb6cbb435
1 измененных файлов с 49 добавлено и 22 удалено
  1. 49 22
      ChocolArm64/AOpCodeTable.cs

+ 49 - 22
ChocolArm64/AOpCodeTable.cs

@@ -4,6 +4,7 @@ using ChocolArm64.Instruction;
 using ChocolArm64.Instruction32;
 using ChocolArm64.State;
 using System;
+using System.Collections.Generic;
 
 namespace ChocolArm64
 {
@@ -438,18 +439,43 @@ namespace ChocolArm64
             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 TreeNode
+        private class InstInfo
         {
             public int Mask;
             public int Value;
 
-            public TreeNode Next;
-
             public AInst Inst;
 
-            public TreeNode(int Mask, int Value, AInst Inst)
+            public InstInfo(int Mask, int Value, AInst Inst)
             {
                 this.Mask  = Mask;
                 this.Value = Value;
@@ -457,8 +483,11 @@ namespace ChocolArm64
             }
         }
 
-        private static TreeNode InstHeadA32;
-        private static TreeNode InstHeadA64;
+        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)
         {
@@ -519,7 +548,7 @@ namespace ChocolArm64
 
             if (XBits == 0)
             {
-                InsertTop(XMask, Value, Inst, Mode);
+                InsertInst(XMask, Value, Inst, Mode);
 
                 return;
             }
@@ -535,55 +564,53 @@ namespace ChocolArm64
 
                 if (Mask != Blacklisted)
                 {
-                    InsertTop(XMask, Value | Mask, Inst, Mode);
+                    InsertInst(XMask, Value | Mask, Inst, Mode);
                 }
             }
         }
 
-        private static void InsertTop(
+        private static void InsertInst(
             int            XMask,
             int            Value,
             AInst          Inst,
             AExecutionMode Mode)
         {
-            TreeNode Node = new TreeNode(XMask, Value, Inst);
+            InstInfo Info = new InstInfo(XMask, Value, Inst);
 
             if (Mode == AExecutionMode.AArch64)
             {
-                Node.Next = InstHeadA64;
-
-                InstHeadA64 = Node;
+                AllInstA64.Add(Info);
             }
             else
             {
-                Node.Next = InstHeadA32;
-
-                InstHeadA32 = Node;
+                AllInstA32.Add(Info);
             }
         }
 
         public static AInst GetInstA32(int OpCode)
         {
-            return GetInst(InstHeadA32, OpCode);
+            return GetInstFromList(AllInstA32, OpCode);
         }
 
         public static AInst GetInstA64(int OpCode)
         {
-            return GetInst(InstHeadA64, OpCode);
+            return GetInstFromList(InstA64FastLookup[ToFastLookupIndex(OpCode)], OpCode);
         }
 
-        private static AInst GetInst(TreeNode Head, int OpCode)
+        private static int ToFastLookupIndex(int Value)
         {
-            TreeNode Node = Head;
+            return ((Value >> 10) & 0x00F) | ((Value >> 18) & 0xFF0);
+        }
 
-            do
+        private static AInst GetInstFromList(IEnumerable<InstInfo> InstList, int OpCode)
+        {
+            foreach (var Node in InstList)
             {
                 if ((OpCode & Node.Mask) == Node.Value)
                 {
                     return Node.Inst;
                 }
             }
-            while ((Node = Node.Next) != null);
 
             return AInst.Undefined;
         }