diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index bf030314ec..c2db77434b 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -255,6 +255,7 @@ namespace ChocolArm64 SetA64("x00111100x110000000000xxxxxxxxxx", AInstEmit.Fcvtms_Gp, typeof(AOpCodeSimdCvt)); SetA64("x00111100x110001000000xxxxxxxxxx", AInstEmit.Fcvtmu_Gp, typeof(AOpCodeSimdCvt)); SetA64("0x0011100x100001011010xxxxxxxxxx", AInstEmit.Fcvtn_V, typeof(AOpCodeSimd)); + SetA64("0x0011100x100001101010xxxxxxxxxx", AInstEmit.Fcvtns_V, typeof(AOpCodeSimd)); SetA64("x00111100x101000000000xxxxxxxxxx", AInstEmit.Fcvtps_Gp, typeof(AOpCodeSimdCvt)); SetA64("x00111100x101001000000xxxxxxxxxx", AInstEmit.Fcvtpu_Gp, typeof(AOpCodeSimdCvt)); SetA64("x00111100x111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_Gp, typeof(AOpCodeSimdCvt)); diff --git a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs index 7b355494dc..ae6475d757 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdCvt.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdCvt.cs @@ -105,6 +105,39 @@ namespace ChocolArm64.Instruction EmitVectorZeroUpper(Context, Op.Rd); } } + + public static void Fcvtns_V(AILEmitterCtx Context) + { + AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; + + int SizeF = Op.Size & 1; + + int Elems = 4 >> SizeF; + + for (int Index = 0; Index < Elems; Index++) + { + EmitVectorExtractF(Context, Op.Rd, Index, SizeF); + + EmitRoundMathCall(Context, MidpointRounding.ToEven); + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + Context.Emit(OpCodes.Conv_I4); + } + else if (Op.RegisterSize == ARegisterSize.SIMD128) + { + Context.Emit(OpCodes.Conv_I8); + } + + EmitVectorInsertF(Context, Op.Rd, Index, 0); + + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } public static void Fcvtps_Gp(AILEmitterCtx Context) { @@ -569,4 +602,4 @@ namespace ChocolArm64.Instruction } } } -} \ No newline at end of file +}