diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-12-26 18:11:36 +0100 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-12-26 15:11:36 -0200 |
| commit | 0f5b6dfbe8d4bcc4df3f670e366a967d8ea103db (patch) | |
| tree | 89fe781d39e9e02534fd455a26008db8a3a14341 /ChocolArm64/Instructions/InstEmitSimdHelper.cs | |
| parent | d8f2497f155046402cd15c65eca0326faf3aefd6 (diff) | |
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
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitSimdHelper.cs')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitSimdHelper.cs | 110 |
1 files changed, 90 insertions, 20 deletions
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<float>), typeof(Vector128<float>) }; + + 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<float>), typeof(Vector128<float>), typeof(byte) }; + Type[] types = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; + + 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<double>), typeof(Vector128<double>) }; + + 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 { |
