aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction
diff options
context:
space:
mode:
Diffstat (limited to 'ChocolArm64/Instruction')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs33
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdCvt.cs70
2 files changed, 102 insertions, 1 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 1e4002a0..a291a7e5 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -1032,6 +1032,11 @@ namespace ChocolArm64.Instruction
EmitAddLongPairwise(Context, Signed: true, Accumulate: true);
}
+ public static void Saddl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add));
+ }
+
public static void Saddlp_V(AILEmitterCtx Context)
{
EmitAddLongPairwise(Context, Signed: true, Accumulate: false);
@@ -1217,6 +1222,11 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Ssubl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
+ }
+
public static void Ssubw_V(AILEmitterCtx Context)
{
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
@@ -1391,6 +1401,24 @@ namespace ChocolArm64.Instruction
EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
}
+ public static void Umlal_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmTernaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Add);
+ });
+ }
+
+ public static void Umlsl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmTernaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Sub);
+ });
+ }
+
public static void Umull_V(AILEmitterCtx Context)
{
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
@@ -1450,6 +1478,11 @@ namespace ChocolArm64.Instruction
EmitVectorSaturatingBinaryOpZx(Context, SaturatingFlags.Accumulate);
}
+ public static void Usubl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
+ }
+
public static void Usubw_V(AILEmitterCtx Context)
{
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
index 7b355494..231de0af 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs
@@ -106,6 +106,26 @@ namespace ChocolArm64.Instruction
}
}
+ public static void Fcvtns_S(AILEmitterCtx Context)
+ {
+ EmitFcvtn(Context, Signed: true, Scalar: true);
+ }
+
+ public static void Fcvtns_V(AILEmitterCtx Context)
+ {
+ EmitFcvtn(Context, Signed: true, Scalar: false);
+ }
+
+ public static void Fcvtnu_S(AILEmitterCtx Context)
+ {
+ EmitFcvtn(Context, Signed: false, Scalar: true);
+ }
+
+ public static void Fcvtnu_V(AILEmitterCtx Context)
+ {
+ EmitFcvtn(Context, Signed: false, Scalar: false);
+ }
+
public static void Fcvtps_Gp(AILEmitterCtx Context)
{
EmitFcvt_s_Gp(Context, () => EmitUnaryMathCall(Context, nameof(Math.Ceiling)));
@@ -250,6 +270,54 @@ namespace ChocolArm64.Instruction
}
}
+ private static void EmitFcvtn(AILEmitterCtx Context, bool Signed, bool Scalar)
+ {
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+ int SizeF = Op.Size & 1;
+ int SizeI = SizeF + 2;
+
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = !Scalar ? Bytes >> SizeI : 1;
+
+ if (Scalar && (SizeF == 0))
+ {
+ EmitVectorZeroLowerTmp(Context);
+ }
+
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+
+ EmitRoundMathCall(Context, MidpointRounding.ToEven);
+
+ if (SizeF == 0)
+ {
+ AVectorHelper.EmitCall(Context, Signed
+ ? nameof(AVectorHelper.SatF32ToS32)
+ : nameof(AVectorHelper.SatF32ToU32));
+
+ Context.Emit(OpCodes.Conv_U8);
+ }
+ else /* if (SizeF == 1) */
+ {
+ AVectorHelper.EmitCall(Context, Signed
+ ? nameof(AVectorHelper.SatF64ToS64)
+ : nameof(AVectorHelper.SatF64ToU64));
+ }
+
+ EmitVectorInsertTmp(Context, Index, SizeI);
+ }
+
+ Context.EmitLdvectmp();
+ Context.EmitStvec(Op.Rd);
+
+ if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
private static void EmitFcvt_s_Gp(AILEmitterCtx Context, Action Emit)
{
EmitFcvt___Gp(Context, Emit, true);
@@ -569,4 +637,4 @@ namespace ChocolArm64.Instruction
}
}
}
-} \ No newline at end of file
+}