diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-11-18 03:41:16 +0100 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-11-18 00:41:16 -0200 |
| commit | e603b7afbcdff0fc732304872f5a65d410c601f9 (patch) | |
| tree | d1949402bc6c6edd5a3d6e2ea40d9033a3d2f654 /ChocolArm64/Instructions/InstEmitSimdCvt.cs | |
| parent | b7613dd4b8a535d028ae180ee3a4b574abe4e3e0 (diff) | |
Add Sse Opt. for S/Umax_V, S/Umin_V, S/Uaddw_V, S/Usubw_V, Fabs_S/V, Fneg_S/V Inst.; for Fcvtl_V, Fcvtn_V Inst.; and for Fcmp_S Inst.. Add/Improve other Sse Opt.. Add Tests. (#496)
* Update CpuTest.cs
* Update CpuTestSimd.cs
* Update CpuTestSimdReg.cs
* Update InstEmitSimdCmp.cs
* Update SoftFloat.cs
* Update InstEmitAluHelper.cs
* Update InstEmitSimdArithmetic.cs
* Update InstEmitSimdHelper.cs
* Update VectorHelper.cs
* Update InstEmitSimdCvt.cs
* Update InstEmitSimdArithmetic.cs
* Update CpuTestSimd.cs
* Update InstEmitSimdArithmetic.cs
* Update OpCodeTable.cs
* Update InstEmitSimdArithmetic.cs
* Update InstEmitSimdCmp.cs
* Update InstEmitSimdCvt.cs
* Update CpuTestSimd.cs
* Update CpuTestSimdReg.cs
* Create CpuTestSimdFcond.cs
* Update OpCodeTable.cs
* Update InstEmitSimdMove.cs
* Update CpuTestSimdIns.cs
* Create CpuTestSimdExt.cs
* Nit.
* Update PackageReference.
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitSimdCvt.cs')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitSimdCvt.cs | 164 |
1 files changed, 112 insertions, 52 deletions
diff --git a/ChocolArm64/Instructions/InstEmitSimdCvt.cs b/ChocolArm64/Instructions/InstEmitSimdCvt.cs index 45f2bef2..fe8722af 100644 --- a/ChocolArm64/Instructions/InstEmitSimdCvt.cs +++ b/ChocolArm64/Instructions/InstEmitSimdCvt.cs @@ -76,33 +76,54 @@ namespace ChocolArm64.Instructions int sizeF = op.Size & 1; - int elems = 4 >> sizeF; + if (Optimizations.UseSse2 && sizeF == 1) + { + Type[] typesMov = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; + Type[] typesCvt = new Type[] { typeof(Vector128<float>) }; - int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; + string nameMov = op.RegisterSize == RegisterSize.Simd128 + ? nameof(Sse.MoveHighToLow) + : nameof(Sse.MoveLowToHigh); - for (int index = 0; index < elems; index++) + context.EmitLdvec(op.Rn); + context.Emit(OpCodes.Dup); + + context.EmitCall(typeof(Sse).GetMethod(nameMov, typesMov)); + + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Double), typesCvt)); + + EmitStvecWithCastFromDouble(context, op.Rd); + } + else { - if (sizeF == 0) - { - EmitVectorExtractZx(context, op.Rn, part + index, 1); - context.Emit(OpCodes.Conv_U2); + int elems = 4 >> sizeF; - context.EmitLdarg(TranslatedSub.StateArgIdx); + int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; - context.EmitCall(typeof(SoftFloat16_32), nameof(SoftFloat16_32.FPConvert)); - } - else /* if (sizeF == 1) */ + for (int index = 0; index < elems; index++) { - EmitVectorExtractF(context, op.Rn, part + index, 0); + if (sizeF == 0) + { + EmitVectorExtractZx(context, op.Rn, part + index, 1); + context.Emit(OpCodes.Conv_U2); + + context.EmitLdarg(TranslatedSub.StateArgIdx); + + context.EmitCall(typeof(SoftFloat16_32), nameof(SoftFloat16_32.FPConvert)); + } + else /* if (sizeF == 1) */ + { + EmitVectorExtractF(context, op.Rn, part + index, 0); - context.Emit(OpCodes.Conv_R8); + context.Emit(OpCodes.Conv_R8); + } + + EmitVectorInsertTmpF(context, index, sizeF); } - EmitVectorInsertTmpF(context, index, sizeF); + context.EmitLdvectmp(); + context.EmitStvec(op.Rd); } - - context.EmitLdvectmp(); - context.EmitStvec(op.Rd); } public static void Fcvtms_Gp(ILEmitterCtx context) @@ -121,43 +142,70 @@ namespace ChocolArm64.Instructions int sizeF = op.Size & 1; - int elems = 4 >> sizeF; + if (Optimizations.UseSse2 && sizeF == 1) + { + Type[] typesMov = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; + Type[] typesCvt = new Type[] { typeof(Vector128<double>) }; - int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; + string nameMov = op.RegisterSize == RegisterSize.Simd128 + ? nameof(Sse.MoveLowToHigh) + : nameof(Sse.MoveHighToLow); - if (part != 0) - { context.EmitLdvec(op.Rd); - context.EmitStvectmp(); - } + VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero)); - for (int index = 0; index < elems; index++) - { - EmitVectorExtractF(context, op.Rn, index, sizeF); + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh), typesMov)); - if (sizeF == 0) - { - context.EmitLdarg(TranslatedSub.StateArgIdx); + EmitLdvecWithCastToDouble(context, op.Rn); + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt)); + context.Emit(OpCodes.Dup); - context.EmitCall(typeof(SoftFloat32_16), nameof(SoftFloat32_16.FPConvert)); + context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh), typesMov)); - context.Emit(OpCodes.Conv_U8); - EmitVectorInsertTmp(context, part + index, 1); + context.EmitCall(typeof(Sse).GetMethod(nameMov, typesMov)); + + context.EmitStvec(op.Rd); + } + else + { + int elems = 4 >> sizeF; + + int part = op.RegisterSize == RegisterSize.Simd128 ? elems : 0; + + if (part != 0) + { + context.EmitLdvec(op.Rd); + context.EmitStvectmp(); } - else /* if (sizeF == 1) */ + + for (int index = 0; index < elems; index++) { - context.Emit(OpCodes.Conv_R4); + EmitVectorExtractF(context, op.Rn, index, sizeF); + + if (sizeF == 0) + { + context.EmitLdarg(TranslatedSub.StateArgIdx); + + context.EmitCall(typeof(SoftFloat32_16), nameof(SoftFloat32_16.FPConvert)); + + context.Emit(OpCodes.Conv_U8); + EmitVectorInsertTmp(context, part + index, 1); + } + else /* if (sizeF == 1) */ + { + context.Emit(OpCodes.Conv_R4); - EmitVectorInsertTmpF(context, part + index, 0); + EmitVectorInsertTmpF(context, part + index, 0); + } } - } - context.EmitLdvectmp(); - context.EmitStvec(op.Rd); + context.EmitLdvectmp(); + context.EmitStvec(op.Rd); - if (part == 0) - { - EmitVectorZeroUpper(context, op.Rd); + if (part == 0) + { + EmitVectorZeroUpper(context, op.Rd); + } } } @@ -260,7 +308,29 @@ namespace ChocolArm64.Instructions public static void Scvtf_V(ILEmitterCtx context) { - EmitVectorCvtf(context, signed: true); + OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; + + int sizeF = op.Size & 1; + + if (Optimizations.UseSse2 && sizeF == 0) + { + Type[] typesCvt = new Type[] { typeof(Vector128<int>) }; + + EmitLdvecWithSignedCast(context, op.Rn, 2); + + context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt)); + + context.EmitStvec(op.Rd); + + if (op.RegisterSize == RegisterSize.Simd64) + { + EmitVectorZeroUpper(context, op.Rd); + } + } + else + { + EmitVectorCvtf(context, signed: true); + } } public static void Ucvtf_Gp(ILEmitterCtx context) @@ -441,16 +511,6 @@ namespace ChocolArm64.Instructions context.EmitStintzr(op.Rd); } - private static void EmitVectorScvtf(ILEmitterCtx context) - { - EmitVectorCvtf(context, true); - } - - private static void EmitVectorUcvtf(ILEmitterCtx context) - { - EmitVectorCvtf(context, false); - } - private static void EmitVectorCvtf(ILEmitterCtx context, bool signed) { OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; |
