diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-10-14 04:35:16 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-10-13 23:35:16 -0300 |
| commit | 894459fcd7797b1e38f2448797d83856d11b6e23 (patch) | |
| tree | 87a67e3b80cba4b05a29d243db63d130e1b362c2 /ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | |
| parent | ac1a379265d0c02a8bd4a146c205f21e2d00f3ab (diff) | |
Add Fmls_Se, Fmulx_Se/Ve, Smov_S Inst.; Opt. Clz/Clz_V, Cnt_V, Shl_V, S/Ushr_V, S/Usra_V Inst.; Add 11 Tests. Some fixes. (#449)
* Update AOpCodeTable.cs
* Update AInstEmitSimdMove.cs
* Update AInstEmitSimdArithmetic.cs
* Update AInstEmitSimdShift.cs
* Update ASoftFallback.cs
* Update ASoftFloat.cs
* Update AOpCodeSimdRegElemF.cs
* Update CpuTestSimdIns.cs
* Update CpuTestSimdRegElem.cs
* Create CpuTestSimdRegElemF.cs
* Update CpuTestSimd.cs
* Update CpuTestSimdReg.cs
* Superseded Fmul_Se Test. Nit.
* Address PR feedback.
* Address PR feedback.
* Update AInstEmitSimdArithmetic.cs
* Update ASoftFallback.cs
* Update AInstEmitAlu.cs
* Update AInstEmitSimdShift.cs
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index d11a0b84..7ba08f5e 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -83,19 +83,31 @@ namespace ChocolArm64.Instruction public static void Cls_V(AILEmitterCtx Context) { - MethodInfo MthdInfo = typeof(ASoftFallback).GetMethod(nameof(ASoftFallback.CountLeadingSigns)); + AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; - EmitCountLeadingBits(Context, () => Context.EmitCall(MthdInfo)); - } + int Bytes = Op.GetBitsCount() >> 3; + int Elems = Bytes >> Op.Size; - public static void Clz_V(AILEmitterCtx Context) - { - MethodInfo MthdInfo = typeof(ASoftFallback).GetMethod(nameof(ASoftFallback.CountLeadingZeros)); + int ESize = 8 << Op.Size; - EmitCountLeadingBits(Context, () => Context.EmitCall(MthdInfo)); + for (int Index = 0; Index < Elems; Index++) + { + EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); + + Context.EmitLdc_I4(ESize); + + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingSigns)); + + EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } } - private static void EmitCountLeadingBits(AILEmitterCtx Context, Action Emit) + public static void Clz_V(AILEmitterCtx Context) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; @@ -108,9 +120,20 @@ namespace ChocolArm64.Instruction { EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); - Context.EmitLdc_I4(ESize); + if (Lzcnt.IsSupported && ESize == 32) + { + Context.Emit(OpCodes.Conv_U4); - Emit(); + Context.EmitCall(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { typeof(uint) })); + + Context.Emit(OpCodes.Conv_U8); + } + else + { + Context.EmitLdc_I4(ESize); + + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingZeros)); + } EmitVectorInsert(Context, Op.Rd, Index, Op.Size); } @@ -131,11 +154,14 @@ namespace ChocolArm64.Instruction { EmitVectorExtractZx(Context, Op.Rn, Index, 0); - Context.Emit(OpCodes.Conv_U4); - - ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountSetBits8)); - - Context.Emit(OpCodes.Conv_U8); + if (Popcnt.IsSupported) + { + Context.EmitCall(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { typeof(ulong) })); + } + else + { + ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountSetBits8)); + } EmitVectorInsert(Context, Op.Rd, Index, 0); } @@ -440,6 +466,15 @@ namespace ChocolArm64.Instruction }); } + public static void Fmls_Se(AILEmitterCtx Context) + { + EmitScalarTernaryOpByElemF(Context, () => + { + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Sub); + }); + } + public static void Fmls_V(AILEmitterCtx Context) { EmitVectorTernaryOpF(Context, () => @@ -554,6 +589,14 @@ namespace ChocolArm64.Instruction }); } + public static void Fmulx_Se(AILEmitterCtx Context) + { + EmitScalarBinaryOpByElemF(Context, () => + { + EmitSoftFloatCall(Context, nameof(ASoftFloat_32.FPMulX)); + }); + } + public static void Fmulx_V(AILEmitterCtx Context) { EmitVectorBinaryOpF(Context, () => @@ -562,6 +605,14 @@ namespace ChocolArm64.Instruction }); } + public static void Fmulx_Ve(AILEmitterCtx Context) + { + EmitVectorBinaryOpByElemF(Context, () => + { + EmitSoftFloatCall(Context, nameof(ASoftFloat_32.FPMulX)); + }); + } + public static void Fneg_S(AILEmitterCtx Context) { EmitScalarUnaryOpF(Context, () => Context.Emit(OpCodes.Neg)); |
