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

Add scalar variants of FCVTZS/FCVTZU, fix a issue on Ryushader

gdkchan 8 лет назад
Родитель
Сommit
7ac5f40532
3 измененных файлов с 57 добавлено и 1 удалено
  1. 2 0
      ChocolArm64/AOpCodeTable.cs
  2. 54 0
      ChocolArm64/Instruction/AInstEmitSimdCvt.cs
  3. 1 1
      Ryushader/Program.cs

+ 2 - 0
ChocolArm64/AOpCodeTable.cs

@@ -231,10 +231,12 @@ namespace ChocolArm64
             Set("x00111100x101001000000xxxxxxxxxx", AInstEmit.Fcvtpu_Gp,     typeof(AOpCodeSimdCvt));
             Set("x00111100x111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp,     typeof(AOpCodeSimdCvt));
             Set("x00111100x011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Gp_Fix, typeof(AOpCodeSimdCvt));
+            Set("010111101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_S,      typeof(AOpCodeSimd));
             Set("0>0011101<100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V,      typeof(AOpCodeSimd));
             Set("0x0011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzs_V,      typeof(AOpCodeSimdShImm));
             Set("x00111100x111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_Gp,     typeof(AOpCodeSimdCvt));
             Set("x00111100x011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Gp_Fix, typeof(AOpCodeSimdCvt));
+            Set("011111101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_S,      typeof(AOpCodeSimd));
             Set("0>1011101<100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V,      typeof(AOpCodeSimd));
             Set("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V,      typeof(AOpCodeSimdShImm));
             Set("000111100x1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S,        typeof(AOpCodeSimdReg));

+ 54 - 0
ChocolArm64/Instruction/AInstEmitSimdCvt.cs

@@ -126,6 +126,11 @@ namespace ChocolArm64.Instruction
             EmitFcvtzs_Gp_Fix(Context);
         }
 
+        public static void Fcvtzs_S(AILEmitterCtx Context)
+        {
+            EmitScalarFcvtzs(Context);
+        }
+
         public static void Fcvtzs_V(AILEmitterCtx Context)
         {
             EmitVectorFcvtzs(Context);
@@ -141,6 +146,11 @@ namespace ChocolArm64.Instruction
             EmitFcvtzu_Gp_Fix(Context);
         }
 
+        public static void Fcvtzu_S(AILEmitterCtx Context)
+        {
+            EmitScalarFcvtzu(Context);
+        }
+
         public static void Fcvtzu_V(AILEmitterCtx Context)
         {
             EmitVectorFcvtzu(Context);
@@ -353,6 +363,50 @@ namespace ChocolArm64.Instruction
             }
         }
 
+        private static void EmitScalarFcvtzs(AILEmitterCtx Context)
+        {
+            EmitScalarFcvtz(Context, true);
+        }
+
+        private static void EmitScalarFcvtzu(AILEmitterCtx Context)
+        {
+            EmitScalarFcvtz(Context, false);
+        }
+
+        private static void EmitScalarFcvtz(AILEmitterCtx Context, bool Signed)
+        {
+            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+            int SizeF = Op.Size & 1;
+            int SizeI = SizeF + 2;
+
+            int FBits = GetFBits(Context);
+
+            EmitVectorExtractF(Context, Op.Rn, 0, SizeF);
+
+            EmitF2iFBitsMul(Context, SizeF, FBits);
+
+            if (SizeF == 0)
+            {
+                AVectorHelper.EmitCall(Context, Signed
+                    ? nameof(AVectorHelper.SatF32ToS32)
+                    : nameof(AVectorHelper.SatF32ToU32));
+            }
+            else /* if (SizeF == 1) */
+            {
+                AVectorHelper.EmitCall(Context, Signed
+                    ? nameof(AVectorHelper.SatF64ToS64)
+                    : nameof(AVectorHelper.SatF64ToU64));
+            }
+
+            if (SizeF == 0)
+            {
+                Context.Emit(OpCodes.Conv_U8);
+            }
+
+            EmitScalarSet(Context, Op.Rd, SizeI);
+        }
+
         private static void EmitVectorFcvtzs(AILEmitterCtx Context)
         {
             EmitVectorFcvtz(Context, true);

+ 1 - 1
Ryushader/Program.cs

@@ -28,7 +28,7 @@ namespace Ryushader
 
                 int[] Code = new int[Data.Length / 4];
 
-                for (int Offset = 0; Offset < Data.Length; Offset += 4)
+                for (int Offset = 0; Offset + 4 <= Data.Length; Offset += 4)
                 {
                     int Value = BitConverter.ToInt32(Data, Offset);