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

Add Cls Instruction. (#67)

* Update AInstEmitAlu.cs

* Update ASoftFallback.cs

* Update AOpCodeTable.cs
LDj3SNuD 8 лет назад
Родитель
Сommit
873a7cd112

+ 4 - 3
ChocolArm64/AOpCodeTable.cs

@@ -8,7 +8,7 @@ namespace ChocolArm64
     {
         static AOpCodeTable()
         {
- #region "OpCode Table"
+#region "OpCode Table"
             //Integer
             Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc,           typeof(AOpCodeAluRs));
             Set("x0111010000xxxxx000000xxxxxxxxxx", AInstEmit.Adcs,          typeof(AOpCodeAluRs));
@@ -41,6 +41,7 @@ namespace ChocolArm64
             Set("x1111010010xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ccmp,          typeof(AOpCodeCcmpImm));
             Set("x1111010010xxxxxxxxx00xxxxxxxxxx", AInstEmit.Ccmp,          typeof(AOpCodeCcmpReg));
             Set("11010101000000110011xxxx01011111", AInstEmit.Clrex,         typeof(AOpCodeSystem));
+            Set("x101101011000000000101xxxxxxxxxx", AInstEmit.Cls,           typeof(AOpCodeAlu));
             Set("x101101011000000000100xxxxxxxxxx", AInstEmit.Clz,           typeof(AOpCodeAlu));
             Set("x0011010110xxxxx010000xxxxxxxxxx", AInstEmit.Crc32b,        typeof(AOpCodeAluRs));
             Set("x0011010110xxxxx010001xxxxxxxxxx", AInstEmit.Crc32h,        typeof(AOpCodeAluRs));
@@ -68,7 +69,7 @@ namespace ChocolArm64
             Set("xx111000010xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemImm));
             Set("xx11100101xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemImm));
             Set("xx111000011xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr,           typeof(AOpCodeMemReg));
-            Set("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit,        typeof(AOpCodeMemLit));            
+            Set("xx011000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit,        typeof(AOpCodeMemLit));
             Set("0x1110001x0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
             Set("0x1110011xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
             Set("10111000100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldrs,          typeof(AOpCodeMemImm));
@@ -442,4 +443,4 @@ namespace ChocolArm64
             return AInst.Undefined;
         }
     }
-}
+}

+ 19 - 1
ChocolArm64/Instruction/AInstEmitAlu.cs

@@ -100,6 +100,24 @@ namespace ChocolArm64.Instruction
             EmitDataStore(Context, SetFlags);
         }
 
+        public static void Cls(AILEmitterCtx Context)
+        {
+            AOpCodeAlu Op = (AOpCodeAlu)Context.CurrOp;
+
+            Context.EmitLdintzr(Op.Rn);
+
+            if (Op.RegisterSize == ARegisterSize.Int32)
+            {
+                ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingSigns32));
+            }
+            else
+            {
+                ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingSigns64));
+            }
+
+            Context.EmitStintzr(Op.Rd);
+        }
+
         public static void Clz(AILEmitterCtx Context)
         {
             AOpCodeAlu Op = (AOpCodeAlu)Context.CurrOp;
@@ -383,4 +401,4 @@ namespace ChocolArm64.Instruction
             Context.EmitStflg((int)APState.CBit);
         }
     }
-}
+}

+ 9 - 1
ChocolArm64/Instruction/ASoftFallback.cs

@@ -20,6 +20,14 @@ namespace ChocolArm64.Instruction
             Context.EmitCall(typeof(ASoftFallback), MthdName);
         }
 
+        public static uint  CountLeadingSigns32(uint Value)  => (uint)CountLeadingSigns(Value, 32);
+        public static ulong CountLeadingSigns64(ulong Value) => (ulong)CountLeadingSigns(Value, 64);
+
+        private static ulong CountLeadingSigns(ulong Value, int Size)
+        {
+            return CountLeadingZeros((Value >> 1) ^ Value, Size - 1);
+        }
+
         public static uint  CountLeadingZeros32(uint Value)  => (uint)CountLeadingZeros(Value, 32);
         public static ulong CountLeadingZeros64(ulong Value) => (ulong)CountLeadingZeros(Value, 64);
 
@@ -398,4 +406,4 @@ namespace ChocolArm64.Instruction
             throw new ArgumentOutOfRangeException(nameof(Size));
         }
     }
-}
+}