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

Add SMLAL (vector), fix EXT instruction

gdkchan 8 лет назад
Родитель
Сommit
be0e4007dc

+ 1 - 0
ChocolArm64/AOpCodeTable.cs

@@ -243,6 +243,7 @@ namespace ChocolArm64
             Set("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V,        typeof(AOpCodeSimdShImm));
             Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V,        typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V,        typeof(AOpCodeSimdReg));
+            Set("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V,       typeof(AOpCodeSimdReg));
             Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V,       typeof(AOpCodeSimdReg));
             Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V,        typeof(AOpCodeSimdReg));
             Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V,       typeof(AOpCodeSimdShImm));

+ 1 - 1
ChocolArm64/Decoder/AOpCodeSimdExt.cs

@@ -8,7 +8,7 @@ namespace ChocolArm64.Decoder
 
         public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
         {
-            int Imm4 = (OpCode >> 11) & 0xf;
+            Imm4 = (OpCode >> 11) & 0xf;
         }
     }
 }

+ 9 - 0
ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs

@@ -374,6 +374,15 @@ namespace ChocolArm64.Instruction
             EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
         }
 
+        public static void Smlal_V(AILEmitterCtx Context)
+        {
+            EmitVectorWidenRnRmTernaryOpSx(Context, () =>
+            {
+                Context.Emit(OpCodes.Mul);
+                Context.Emit(OpCodes.Add);
+            });
+        }
+
         public static void Smull_V(AILEmitterCtx Context)
         {
             EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul));

+ 18 - 3
ChocolArm64/Instruction/AInstEmitSimdHelper.cs

@@ -459,15 +459,25 @@ namespace ChocolArm64.Instruction
 
         public static void EmitVectorWidenRnRmBinaryOpSx(AILEmitterCtx Context, Action Emit)
         {
-            EmitVectorWidenRnRmBinaryOp(Context, Emit, true);
+            EmitVectorWidenRnRmOp(Context, Emit, false, true);
         }
 
         public static void EmitVectorWidenRnRmBinaryOpZx(AILEmitterCtx Context, Action Emit)
         {
-            EmitVectorWidenRnRmBinaryOp(Context, Emit, false);
+            EmitVectorWidenRnRmOp(Context, Emit, false, false);
         }
 
-        public static void EmitVectorWidenRnRmBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed)
+        public static void EmitVectorWidenRnRmTernaryOpSx(AILEmitterCtx Context, Action Emit)
+        {
+            EmitVectorWidenRnRmOp(Context, Emit, true, true);
+        }
+
+        public static void EmitVectorWidenRnRmTernaryOpZx(AILEmitterCtx Context, Action Emit)
+        {
+            EmitVectorWidenRnRmOp(Context, Emit, true, false);
+        }
+
+        public static void EmitVectorWidenRnRmOp(AILEmitterCtx Context, Action Emit, bool Ternary, bool Signed)
         {
             AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
@@ -477,6 +487,11 @@ namespace ChocolArm64.Instruction
 
             for (int Index = 0; Index < Elems; Index++)
             {
+                if (Ternary)
+                {
+                    EmitVectorExtract(Context, Op.Rd, Index, Op.Size + 1, Signed);
+                }
+
                 EmitVectorExtract(Context, Op.Rn, Part + Index, Op.Size, Signed);
                 EmitVectorExtract(Context, Op.Rm, Part + Index, Op.Size, Signed);
 

+ 8 - 5
ChocolArm64/Instruction/AInstEmitSimdMove.cs

@@ -63,15 +63,18 @@ namespace ChocolArm64.Instruction
 
             int Bytes = Context.CurrOp.GetBitsCount() >> 3;
 
+            int Position = Op.Imm4;
+
             for (int Index = 0; Index < Bytes; Index++)
             {
-                int Position = Op.Imm4 + Index;
-
-                int Reg = Position < Bytes ? Op.Rn : Op.Rm;
+                int Reg = Op.Imm4 + Index < Bytes ? Op.Rn : Op.Rm;
 
-                Position &= Bytes - 1;
+                if (Position == Bytes)
+                {
+                    Position = 0;
+                }
 
-                EmitVectorExtractZx(Context, Reg, Position, 0);
+                EmitVectorExtractZx(Context, Reg, Position++, 0);
 
                 EmitVectorInsert(Context, Op.Rd, Index, 0);
             }