diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-06-30 17:40:41 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-06-30 12:40:41 -0300 |
| commit | 53934e88727b3d86ccb5ac08a489b28c8f7fc991 (patch) | |
| tree | 39a3a5bb819b4999db6368125f345013b00ef88f /ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | |
| parent | edfd4bc860e05698946605c740fdb5857d64e917 (diff) | |
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
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index efd3cc6e..e61979b0 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/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 Uabd_V(AILEmitterCtx Context) + public static void Uaba_V(AILEmitterCtx Context) { - EmitVectorBinaryOpZx(Context, () => EmitAbd(Context)); + EmitVectorTernaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); } - public static void Uabdl_V(AILEmitterCtx Context) + public static void Uabal_V(AILEmitterCtx Context) { - EmitVectorWidenRnRmBinaryOpZx(Context, () => EmitAbd(Context)); + EmitVectorWidenRnRmTernaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + + Context.Emit(OpCodes.Add); + }); } - private static void EmitAbd(AILEmitterCtx Context) + public static void Uabd_V(AILEmitterCtx Context) { - Context.Emit(OpCodes.Sub); - - Type[] Types = new Type[] { typeof(long) }; + EmitVectorBinaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); + } - Context.EmitCall(typeof(Math).GetMethod(nameof(Math.Abs), Types)); + public static void Uabdl_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmBinaryOpZx(Context, () => + { + Context.Emit(OpCodes.Sub); + EmitAbs(Context); + }); } public static void Uaddl_V(AILEmitterCtx Context) |
