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 | |
| 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')
| -rw-r--r-- | ChocolArm64/AOpCodeTable.cs | 6 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 113 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdHelper.cs | 5 |
3 files changed, 99 insertions, 25 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index 1f60be1c..09a6ca4a 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/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/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) diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs index bca45649..83f6ca25 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs +++ b/ChocolArm64/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); |
