Update InstEmitSimdArithmetic.cs
This commit is contained in:
parent
e7f76a9e66
commit
0cbb2f81ac
1 changed files with 218 additions and 26 deletions
|
@ -366,7 +366,7 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fmadd_S(ILEmitterCtx context)
|
public static void Fmadd_S(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
@ -533,23 +533,119 @@ namespace ChocolArm64.Instructions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fmla_V(ILEmitterCtx context)
|
public static void Fmla_V(ILEmitterCtx context) // Fused.
|
||||||
|
{
|
||||||
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int sizeF = op.Size & 1;
|
||||||
|
|
||||||
|
if (sizeF == 0)
|
||||||
|
{
|
||||||
|
Type[] typesMulAdd = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rd);
|
||||||
|
context.EmitLdvec(op.Rn);
|
||||||
|
context.EmitLdvec(op.Rm);
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
|
||||||
|
|
||||||
|
context.EmitStvec(op.Rd);
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (sizeF == 1) */
|
||||||
|
{
|
||||||
|
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rd);
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rn);
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rm);
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
|
||||||
|
|
||||||
|
EmitStvecWithCastFromDouble(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
EmitVectorTernaryOpF(context, () =>
|
EmitVectorTernaryOpF(context, () =>
|
||||||
{
|
{
|
||||||
context.Emit(OpCodes.Mul);
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd));
|
||||||
context.Emit(OpCodes.Add);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fmla_Ve(ILEmitterCtx context)
|
public static void Fmla_Ve(ILEmitterCtx context) // Fused.
|
||||||
|
{
|
||||||
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
|
{
|
||||||
|
OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
|
||||||
|
|
||||||
|
int sizeF = op.Size & 1;
|
||||||
|
|
||||||
|
if (sizeF == 0)
|
||||||
|
{
|
||||||
|
Type[] typesSfl = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>), typeof(byte) };
|
||||||
|
Type[] typesMulAdd = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rd);
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rn);
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rm);
|
||||||
|
context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
|
||||||
|
|
||||||
|
context.EmitStvec(op.Rd);
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (sizeF == 1) */
|
||||||
|
{
|
||||||
|
Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) };
|
||||||
|
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rd);
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rn);
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rm);
|
||||||
|
context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
context.EmitLdc_I4(op.Index | op.Index << 1);
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
|
||||||
|
|
||||||
|
EmitStvecWithCastFromDouble(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
EmitVectorTernaryOpByElemF(context, () =>
|
EmitVectorTernaryOpByElemF(context, () =>
|
||||||
{
|
{
|
||||||
context.Emit(OpCodes.Mul);
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd));
|
||||||
context.Emit(OpCodes.Add);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fmls_Se(ILEmitterCtx context)
|
public static void Fmls_Se(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
|
@ -560,25 +656,121 @@ namespace ChocolArm64.Instructions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fmls_V(ILEmitterCtx context)
|
public static void Fmls_V(ILEmitterCtx context) // Fused.
|
||||||
|
{
|
||||||
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
|
{
|
||||||
|
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
|
||||||
|
|
||||||
|
int sizeF = op.Size & 1;
|
||||||
|
|
||||||
|
if (sizeF == 0)
|
||||||
|
{
|
||||||
|
Type[] typesMulSub = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rd);
|
||||||
|
context.EmitLdvec(op.Rn);
|
||||||
|
context.EmitLdvec(op.Rm);
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
|
||||||
|
|
||||||
|
context.EmitStvec(op.Rd);
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (sizeF == 1) */
|
||||||
|
{
|
||||||
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rd);
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rn);
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rm);
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
|
||||||
|
|
||||||
|
EmitStvecWithCastFromDouble(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
EmitVectorTernaryOpF(context, () =>
|
EmitVectorTernaryOpF(context, () =>
|
||||||
{
|
{
|
||||||
context.Emit(OpCodes.Mul);
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub));
|
||||||
context.Emit(OpCodes.Sub);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fmls_Ve(ILEmitterCtx context)
|
public static void Fmls_Ve(ILEmitterCtx context) // Fused.
|
||||||
|
{
|
||||||
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
|
{
|
||||||
|
OpCodeSimdRegElemF64 op = (OpCodeSimdRegElemF64)context.CurrOp;
|
||||||
|
|
||||||
|
int sizeF = op.Size & 1;
|
||||||
|
|
||||||
|
if (sizeF == 0)
|
||||||
|
{
|
||||||
|
Type[] typesSfl = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>), typeof(byte) };
|
||||||
|
Type[] typesMulSub = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rd);
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rn);
|
||||||
|
|
||||||
|
context.EmitLdvec(op.Rm);
|
||||||
|
context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
|
||||||
|
|
||||||
|
context.EmitStvec(op.Rd);
|
||||||
|
|
||||||
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* if (sizeF == 1) */
|
||||||
|
{
|
||||||
|
Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) };
|
||||||
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rd);
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rn);
|
||||||
|
|
||||||
|
EmitLdvecWithCastToDouble(context, op.Rm);
|
||||||
|
context.Emit(OpCodes.Dup);
|
||||||
|
|
||||||
|
context.EmitLdc_I4(op.Index | op.Index << 1);
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
|
||||||
|
|
||||||
|
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
|
||||||
|
|
||||||
|
EmitStvecWithCastFromDouble(context, op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
EmitVectorTernaryOpByElemF(context, () =>
|
EmitVectorTernaryOpByElemF(context, () =>
|
||||||
{
|
{
|
||||||
context.Emit(OpCodes.Mul);
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub));
|
||||||
context.Emit(OpCodes.Sub);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fmsub_S(ILEmitterCtx context)
|
public static void Fmsub_S(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
@ -907,7 +1099,7 @@ namespace ChocolArm64.Instructions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frecps_S(ILEmitterCtx context)
|
public static void Frecps_S(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
@ -961,7 +1153,7 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frecps_V(ILEmitterCtx context)
|
public static void Frecps_V(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
@ -1204,7 +1396,7 @@ namespace ChocolArm64.Instructions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frsqrts_S(ILEmitterCtx context)
|
public static void Frsqrts_S(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
@ -1266,7 +1458,7 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frsqrts_V(ILEmitterCtx context)
|
public static void Frsqrts_V(ILEmitterCtx context) // Fused.
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue