aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions/InstEmitSimdCvt.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-11-18 03:41:16 +0100
committergdkchan <gab.dark.100@gmail.com>2018-11-18 00:41:16 -0200
commite603b7afbcdff0fc732304872f5a65d410c601f9 (patch)
treed1949402bc6c6edd5a3d6e2ea40d9033a3d2f654 /ChocolArm64/Instructions/InstEmitSimdCvt.cs
parentb7613dd4b8a535d028ae180ee3a4b574abe4e3e0 (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.cs164
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;