aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instructions/InstEmitSimdHelper.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-12-26 18:11:36 +0100
committergdkchan <gab.dark.100@gmail.com>2018-12-26 15:11:36 -0200
commit0f5b6dfbe8d4bcc4df3f670e366a967d8ea103db (patch)
tree89fe781d39e9e02534fd455a26008db8a3a14341 /ChocolArm64/Instructions/InstEmitSimdHelper.cs
parentd8f2497f155046402cd15c65eca0326faf3aefd6 (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.cs110
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
{