浏览代码

Fix FRSQRTS and FCM* (scalar) instructions

gdkchan 8 年之前
父节点
当前提交
df3cbadceb
共有 2 个文件被更改,包括 51 次插入18 次删除
  1. 30 7
      ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
  2. 21 11
      ChocolArm64/Instruction/AInstEmitSimdCmp.cs

+ 30 - 7
ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs

@@ -512,22 +512,34 @@ namespace ChocolArm64.Instruction
 
 
         public static void Frsqrts_S(AILEmitterCtx Context)
         public static void Frsqrts_S(AILEmitterCtx Context)
         {
         {
-            EmitScalarBinaryOpF(Context, () => EmitFrsqrts(Context));
+            EmitFrsqrts(Context, 0, Scalar: true);
         }
         }
 
 
         public static void Frsqrts_V(AILEmitterCtx Context)
         public static void Frsqrts_V(AILEmitterCtx Context)
         {
         {
-            EmitVectorBinaryOpF(Context, () => EmitFrsqrts(Context));
+            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+            int SizeF = Op.Size & 1;
+
+            int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+            for (int Index = 0; Index < Bytes >> SizeF + 2; Index++)
+            {
+                EmitFrsqrts(Context, Index, Scalar: false);
+            }
+
+            if (Op.RegisterSize == ARegisterSize.SIMD64)
+            {
+                EmitVectorZeroUpper(Context, Op.Rd);
+            }
         }
         }
 
 
-        private static void EmitFrsqrts(AILEmitterCtx Context)
+        private static void EmitFrsqrts(AILEmitterCtx Context, int Index, bool Scalar)
         {
         {
-            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
+            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
 
 
             int SizeF = Op.Size & 1;
             int SizeF = Op.Size & 1;
 
 
-            Context.Emit(OpCodes.Mul);
-
             if (SizeF == 0)
             if (SizeF == 0)
             {
             {
                 Context.EmitLdc_R4(3);
                 Context.EmitLdc_R4(3);
@@ -537,7 +549,11 @@ namespace ChocolArm64.Instruction
                 Context.EmitLdc_R8(3);
                 Context.EmitLdc_R8(3);
             }
             }
 
 
-            Context.Emit(OpCodes.Add);
+            EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+            EmitVectorExtractF(Context, Op.Rm, Index, SizeF);
+
+            Context.Emit(OpCodes.Mul);
+            Context.Emit(OpCodes.Sub);
 
 
             if (SizeF == 0)
             if (SizeF == 0)
             {
             {
@@ -549,6 +565,13 @@ namespace ChocolArm64.Instruction
             }
             }
 
 
             Context.Emit(OpCodes.Mul);
             Context.Emit(OpCodes.Mul);
+
+            if (Scalar)
+            {
+                EmitVectorZeroAll(Context, Op.Rd);
+            }
+
+            EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
         }
         }
 
 
         public static void Fsqrt_S(AILEmitterCtx Context)
         public static void Fsqrt_S(AILEmitterCtx Context)

+ 21 - 11
ChocolArm64/Instruction/AInstEmitSimdCmp.cs

@@ -313,13 +313,7 @@ namespace ChocolArm64.Instruction
 
 
         private static void EmitScalarFcmp(AILEmitterCtx Context, OpCode ILOp)
         private static void EmitScalarFcmp(AILEmitterCtx Context, OpCode ILOp)
         {
         {
-            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
-
-            int SizeF = Op.Size & 1;
-
-            EmitFcmp(Context, ILOp, 0);
-
-            EmitScalarSetF(Context, Op.Rd, SizeF);
+            EmitFcmp(Context, ILOp, 0, Scalar: true);
         }
         }
 
 
         private static void EmitVectorFcmp(AILEmitterCtx Context, OpCode ILOp)
         private static void EmitVectorFcmp(AILEmitterCtx Context, OpCode ILOp)
@@ -332,7 +326,7 @@ namespace ChocolArm64.Instruction
 
 
             for (int Index = 0; Index < Bytes >> SizeF + 2; Index++)
             for (int Index = 0; Index < Bytes >> SizeF + 2; Index++)
             {
             {
-                EmitFcmp(Context, ILOp, Index);
+                EmitFcmp(Context, ILOp, Index, Scalar: false);
             }
             }
 
 
             if (Op.RegisterSize == ARegisterSize.SIMD64)
             if (Op.RegisterSize == ARegisterSize.SIMD64)
@@ -341,7 +335,7 @@ namespace ChocolArm64.Instruction
             }
             }
         }
         }
 
 
-        private static void EmitFcmp(AILEmitterCtx Context, OpCode ILOp, int Index)
+        private static void EmitFcmp(AILEmitterCtx Context, OpCode ILOp, int Index, bool Scalar)
         {
         {
             AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
             AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
 
 
@@ -369,13 +363,29 @@ namespace ChocolArm64.Instruction
 
 
             Context.Emit(ILOp, LblTrue);
             Context.Emit(ILOp, LblTrue);
 
 
-            EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, 0);
+            if (Scalar)
+            {
+                EmitVectorZeroAll(Context, Op.Rd);
+            }
+            else
+            {
+                EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, 0);
+            }
 
 
             Context.Emit(OpCodes.Br_S, LblEnd);
             Context.Emit(OpCodes.Br_S, LblEnd);
 
 
             Context.MarkLabel(LblTrue);
             Context.MarkLabel(LblTrue);
 
 
-            EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, (long)SzMask);
+            if (Scalar)
+            {
+                EmitVectorInsert(Context, Op.Rd, Index, 3, (long)SzMask);
+
+                EmitVectorZeroUpper(Context, Op.Rd);
+            }
+            else
+            {
+                EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, (long)SzMask);
+            }
 
 
             Context.MarkLabel(LblEnd);
             Context.MarkLabel(LblEnd);
         }
         }