From ac5c1e51077326a34fa5ebd8caebe63b4560aa05 Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Sat, 30 Jun 2018 17:40:41 +0200 Subject: [PATCH] Add Saba_V, Sabal_V, Sabd_V, Sabdl_V, Uaba_V, Uabal_V; Update Uabd_V, Uabdl_V. Add 16 tests. (#204) * Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdHelper.cs * Update Instructions.cs * Update CpuTest.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs --- AOpCodeTable.cs | 6 ++ Instruction/AInstEmitSimdArithmetic.cs | 117 +++++++++++++++++++------ Instruction/AInstEmitSimdHelper.cs | 5 ++ 3 files changed, 101 insertions(+), 27 deletions(-) diff --git a/AOpCodeTable.cs b/AOpCodeTable.cs index 1f60be1..09a6ca4 100644 --- a/AOpCodeTable.cs +++ b/AOpCodeTable.cs @@ -352,6 +352,10 @@ namespace ChocolArm64 SetA64("0x1011100x100000000010xxxxxxxxxx", AInstEmit.Rev32_V, typeof(AOpCodeSimd)); SetA64("0x001110<<100000000010xxxxxxxxxx", AInstEmit.Rev64_V, typeof(AOpCodeSimd)); SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", AInstEmit.Rsubhn_V, typeof(AOpCodeSimdReg)); + SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Saba_V, typeof(AOpCodeSimdReg)); + SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Sabal_V, typeof(AOpCodeSimdReg)); + SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Sabd_V, typeof(AOpCodeSimdReg)); + SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Sabdl_V, typeof(AOpCodeSimdReg)); SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg)); SetA64("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt)); SetA64("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd)); @@ -390,6 +394,8 @@ namespace ChocolArm64 SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl)); SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", AInstEmit.Trn1_V, typeof(AOpCodeSimdReg)); SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", AInstEmit.Trn2_V, typeof(AOpCodeSimdReg)); + SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Uaba_V, typeof(AOpCodeSimdReg)); + SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Uabal_V, typeof(AOpCodeSimdReg)); SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Uabd_V, typeof(AOpCodeSimdReg)); SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Uabdl_V, typeof(AOpCodeSimdReg)); SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", AInstEmit.Uaddl_V, typeof(AOpCodeSimdReg)); diff --git a/Instruction/AInstEmitSimdArithmetic.cs b/Instruction/AInstEmitSimdArithmetic.cs index efd3cc6..e61979b 100644 --- a/Instruction/AInstEmitSimdArithmetic.cs +++ b/Instruction/AInstEmitSimdArithmetic.cs @@ -22,19 +22,6 @@ namespace ChocolArm64.Instruction EmitVectorUnaryOpSx(Context, () => EmitAbs(Context)); } - private static void EmitAbs(AILEmitterCtx Context) - { - AILLabel LblTrue = new AILLabel(); - - Context.Emit(OpCodes.Dup); - Context.Emit(OpCodes.Ldc_I4_0); - Context.Emit(OpCodes.Bge_S, LblTrue); - - Context.Emit(OpCodes.Neg); - - Context.MarkLabel(LblTrue); - } - public static void Add_S(AILEmitterCtx Context) { EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Add)); @@ -179,6 +166,19 @@ namespace ChocolArm64.Instruction } } + private static void EmitAbs(AILEmitterCtx Context) + { + AILLabel LblTrue = new AILLabel(); + + Context.Emit(OpCodes.Dup); + Context.Emit(OpCodes.Ldc_I4_0); + Context.Emit(OpCodes.Bge_S, LblTrue); + + Context.Emit(OpCodes.Neg); + + Context.MarkLabel(LblTrue); + } + private static void EmitHighNarrow(AILEmitterCtx Context, Action Emit, bool Round) { AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; @@ -188,6 +188,8 @@ namespace ChocolArm64.Instruction int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; + long RoundConst = 1L << (ESize - 1); + for (int Index = 0; Index < Elems; Index++) { EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1); @@ -197,7 +199,7 @@ namespace ChocolArm64.Instruction if (Round) { - Context.EmitLdc_I8(1L << (ESize - 1)); + Context.EmitLdc_I8(RoundConst); Context.Emit(OpCodes.Add); } @@ -220,11 +222,11 @@ namespace ChocolArm64.Instruction int Elems = (!Scalar ? 8 >> Op.Size : 1); int ESize = 8 << Op.Size; + int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0); + int TMaxValue = (SignedDst ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L)); int TMinValue = (SignedDst ? -((1 << (ESize - 1))) : 0); - int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0); - Context.EmitLdc_I8(0L); Context.EmitSttmp(); @@ -1107,6 +1109,46 @@ namespace ChocolArm64.Instruction EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: true); } + public static void Saba_V(AILEmitterCtx Context) + { + EmitVectorTernaryOpSx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); + } + + public static void Sabal_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmTernaryOpSx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); + } + + public static void Sabd_V(AILEmitterCtx Context) + { + EmitVectorBinaryOpSx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); + } + + public static void Sabdl_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmBinaryOpSx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); + } + public static void Saddw_V(AILEmitterCtx Context) { EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add)); @@ -1186,23 +1228,44 @@ namespace ChocolArm64.Instruction EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: false); } + public static void Uaba_V(AILEmitterCtx Context) + { + EmitVectorTernaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); + } + + public static void Uabal_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmTernaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); + } + public static void Uabd_V(AILEmitterCtx Context) { - EmitVectorBinaryOpZx(Context, () => EmitAbd(Context)); + EmitVectorBinaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); } public static void Uabdl_V(AILEmitterCtx Context) { - EmitVectorWidenRnRmBinaryOpZx(Context, () => EmitAbd(Context)); - } - - private static void EmitAbd(AILEmitterCtx Context) - { - Context.Emit(OpCodes.Sub); - - Type[] Types = new Type[] { typeof(long) }; - - Context.EmitCall(typeof(Math).GetMethod(nameof(Math.Abs), Types)); + EmitVectorWidenRnRmBinaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); } public static void Uaddl_V(AILEmitterCtx Context) diff --git a/Instruction/AInstEmitSimdHelper.cs b/Instruction/AInstEmitSimdHelper.cs index bca4564..83f6ca2 100644 --- a/Instruction/AInstEmitSimdHelper.cs +++ b/Instruction/AInstEmitSimdHelper.cs @@ -483,6 +483,11 @@ namespace ChocolArm64.Instruction EmitVectorOp(Context, Emit, OperFlags.RnRm, true); } + public static void EmitVectorTernaryOpSx(AILEmitterCtx Context, Action Emit) + { + EmitVectorOp(Context, Emit, OperFlags.RdRnRm, true); + } + public static void EmitVectorUnaryOpZx(AILEmitterCtx Context, Action Emit) { EmitVectorOp(Context, Emit, OperFlags.Rn, false);