From 0f5b6dfbe8d4bcc4df3f670e366a967d8ea103db Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Wed, 26 Dec 2018 18:11:36 +0100 Subject: Fix Frecpe_S/V and Frsqrte_S/V (full FP emu.). Add Sse Opt. & SoftFloat Impl. for Fcmeq/ge/gt/le/lt_S/V (Reg & Zero), Faddp_S/V, Fmaxp_V, Fminp_V Inst.; add Sse Opt. for Shll_V, S/Ushll_V Inst.; improve Sse Opt. for Xtn_V Inst.. Add Tests. (#543) * Update Optimizations.cs * Update InstEmitSimdShift.cs * Update InstEmitSimdHelper.cs * Update InstEmitSimdArithmetic.cs * Update InstEmitSimdMove.cs * Update SoftFloat.cs * Update InstEmitSimdCmp.cs * Update CpuTestSimdShImm.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Nit. * Update SoftFloat.cs * Update InstEmitSimdArithmetic.cs * Update InstEmitSimdHelper.cs * Update CpuTestSimd.cs * Explicit some implicit casts. * Simplify some powers; nits. * Update OpCodeTable.cs * Update InstEmitSimdArithmetic.cs * Update CpuTestSimdReg.cs * Update InstEmitSimdArithmetic.cs --- ChocolArm64/Instructions/InstEmitSimdHelper.cs | 110 ++++++++++++++++++++----- 1 file changed, 90 insertions(+), 20 deletions(-) (limited to 'ChocolArm64/Instructions/InstEmitSimdHelper.cs') diff --git a/ChocolArm64/Instructions/InstEmitSimdHelper.cs b/ChocolArm64/Instructions/InstEmitSimdHelper.cs index 7b597be3..cea481a6 100644 --- a/ChocolArm64/Instructions/InstEmitSimdHelper.cs +++ b/ChocolArm64/Instructions/InstEmitSimdHelper.cs @@ -322,26 +322,6 @@ namespace ChocolArm64.Instructions context.EmitCall(mthdInfo); } - public static void EmitUnarySoftFloatCall(ILEmitterCtx context, string name) - { - IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp; - - int sizeF = op.Size & 1; - - MethodInfo mthdInfo; - - if (sizeF == 0) - { - mthdInfo = typeof(SoftFloat).GetMethod(name, new Type[] { typeof(float) }); - } - else /* if (sizeF == 1) */ - { - mthdInfo = typeof(SoftFloat).GetMethod(name, new Type[] { typeof(double) }); - } - - context.EmitCall(mthdInfo); - } - public static void EmitSoftFloatCall(ILEmitterCtx context, string name) { IOpCodeSimd64 op = (IOpCodeSimd64)context.CurrOp; @@ -909,6 +889,96 @@ namespace ChocolArm64.Instructions } } + public static void EmitVectorPairwiseSseOrSse2OpF(ILEmitterCtx context, string name) + { + OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp; + + int sizeF = op.Size & 1; + + if (sizeF == 0) + { + if (op.RegisterSize == RegisterSize.Simd64) + { + Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) }; + + context.EmitLdvec(op.Rn); + context.EmitLdvec(op.Rm); + + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.UnpackLow), types)); + + context.Emit(OpCodes.Dup); + context.EmitStvectmp(); + + VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero)); + + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh), types)); + + VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero)); + + context.EmitLdvectmp(); + + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveHighToLow), types)); + + context.EmitCall(typeof(Sse).GetMethod(name, types)); + + context.EmitStvec(op.Rd); + } + else /* if (op.RegisterSize == RegisterSize.Simd128) */ + { + Type[] typesSfl = new Type[] { typeof(Vector128), typeof(Vector128), typeof(byte) }; + Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) }; + + context.EmitLdvec(op.Rn); + + context.Emit(OpCodes.Dup); + context.EmitStvectmp(); + + context.EmitLdvec(op.Rm); + + context.Emit(OpCodes.Dup); + context.EmitStvectmp2(); + + context.EmitLdc_I4(2 << 6 | 0 << 4 | 2 << 2 | 0 << 0); + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl)); + + context.EmitLdvectmp(); + context.EmitLdvectmp2(); + + context.EmitLdc_I4(3 << 6 | 1 << 4 | 3 << 2 | 1 << 0); + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl)); + + context.EmitCall(typeof(Sse).GetMethod(name, types)); + + context.EmitStvec(op.Rd); + } + } + else /* if (sizeF == 1) */ + { + Type[] types = new Type[] { typeof(Vector128), typeof(Vector128) }; + + EmitLdvecWithCastToDouble(context, op.Rn); + + context.Emit(OpCodes.Dup); + context.EmitStvectmp(); + + EmitLdvecWithCastToDouble(context, op.Rm); + + context.Emit(OpCodes.Dup); + context.EmitStvectmp2(); + + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), types)); + + context.EmitLdvectmp(); + context.EmitLdvectmp2(); + + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), types)); + + context.EmitCall(typeof(Sse2).GetMethod(name, types)); + + EmitStvecWithCastFromDouble(context, op.Rd); + } + } + [Flags] public enum SaturatingFlags { -- cgit v1.2.3