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

Add Faddp (vector) instruction

gdkchan 8 лет назад
Родитель
Сommit
45c078d782
2 измененных файлов с 33 добавлено и 0 удалено
  1. 1 0
      ChocolArm64/AOpCodeTable.cs
  2. 32 0
      ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs

+ 1 - 0
ChocolArm64/AOpCodeTable.cs

@@ -165,6 +165,7 @@ namespace ChocolArm64
             Set("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S,        typeof(AOpCodeSimd));
             Set("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S,        typeof(AOpCodeSimdReg));
             Set("0>0011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V,        typeof(AOpCodeSimdReg));
+            Set("0>1011100<1xxxxx110101xxxxxxxxxx", AInstEmit.Faddp_V,       typeof(AOpCodeSimdReg));
             Set("000111100x1xxxxxxxxx01xxxxx0xxxx", AInstEmit.Fccmp_S,       typeof(AOpCodeSimdFcond));
             Set("000111100x1xxxxxxxxx01xxxxx1xxxx", AInstEmit.Fccmpe_S,      typeof(AOpCodeSimdFcond));
             Set("000111100x1xxxxx001000xxxxx0x000", AInstEmit.Fcmp_S,        typeof(AOpCodeSimdReg));

+ 32 - 0
ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs

@@ -129,6 +129,38 @@ namespace ChocolArm64.Instruction
             EmitVectorBinaryOpF(Context, () => Context.Emit(OpCodes.Add));
         }
 
+        public static void Faddp_V(AILEmitterCtx Context)
+        {
+            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+            int SizeF = Op.Size & 1;
+
+            int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+            int Elems = Bytes >> SizeF + 2;
+            int Half  = Elems >> 1;
+
+            for (int Index = 0; Index < Elems; Index++)
+            {
+                int Elem = (Index & (Half - 1)) << 1;
+
+                EmitVectorExtractF(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 0, SizeF);
+                EmitVectorExtractF(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 1, SizeF);
+
+                Context.Emit(OpCodes.Add);
+
+                EmitVectorInsertTmpF(Context, Index, SizeF);
+            }
+
+            Context.EmitLdvectmp();
+            Context.EmitStvec(Op.Rd);
+
+            if (Op.RegisterSize == ARegisterSize.SIMD64)
+            {
+                EmitVectorZeroUpper(Context, Op.Rd);
+            }
+        }
+
         public static void Fdiv_S(AILEmitterCtx Context)
         {
             EmitScalarBinaryOpF(Context, () => Context.Emit(OpCodes.Div));