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
This commit is contained in:
LDj3SNuD 2018-12-26 18:11:36 +01:00 committed by gdkchan
parent d8f2497f15
commit 0f5b6dfbe8
11 changed files with 1808 additions and 441 deletions

View file

@ -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
{