aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-10-14 04:35:16 +0200
committergdkchan <gab.dark.100@gmail.com>2018-10-13 23:35:16 -0300
commit894459fcd7797b1e38f2448797d83856d11b6e23 (patch)
tree87a67e3b80cba4b05a29d243db63d130e1b362c2 /ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
parentac1a379265d0c02a8bd4a146c205f21e2d00f3ab (diff)
Add Fmls_Se, Fmulx_Se/Ve, Smov_S Inst.; Opt. Clz/Clz_V, Cnt_V, Shl_V, S/Ushr_V, S/Usra_V Inst.; Add 11 Tests. Some fixes. (#449)
* Update AOpCodeTable.cs * Update AInstEmitSimdMove.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdShift.cs * Update ASoftFallback.cs * Update ASoftFloat.cs * Update AOpCodeSimdRegElemF.cs * Update CpuTestSimdIns.cs * Update CpuTestSimdRegElem.cs * Create CpuTestSimdRegElemF.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Superseded Fmul_Se Test. Nit. * Address PR feedback. * Address PR feedback. * Update AInstEmitSimdArithmetic.cs * Update ASoftFallback.cs * Update AInstEmitAlu.cs * Update AInstEmitSimdShift.cs
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs')
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs81
1 files changed, 66 insertions, 15 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index d11a0b84..7ba08f5e 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -83,19 +83,31 @@ namespace ChocolArm64.Instruction
public static void Cls_V(AILEmitterCtx Context)
{
- MethodInfo MthdInfo = typeof(ASoftFallback).GetMethod(nameof(ASoftFallback.CountLeadingSigns));
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
- EmitCountLeadingBits(Context, () => Context.EmitCall(MthdInfo));
- }
+ int Bytes = Op.GetBitsCount() >> 3;
+ int Elems = Bytes >> Op.Size;
- public static void Clz_V(AILEmitterCtx Context)
- {
- MethodInfo MthdInfo = typeof(ASoftFallback).GetMethod(nameof(ASoftFallback.CountLeadingZeros));
+ int ESize = 8 << Op.Size;
- EmitCountLeadingBits(Context, () => Context.EmitCall(MthdInfo));
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
+
+ Context.EmitLdc_I4(ESize);
+
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingSigns));
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
}
- private static void EmitCountLeadingBits(AILEmitterCtx Context, Action Emit)
+ public static void Clz_V(AILEmitterCtx Context)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@@ -108,9 +120,20 @@ namespace ChocolArm64.Instruction
{
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
- Context.EmitLdc_I4(ESize);
+ if (Lzcnt.IsSupported && ESize == 32)
+ {
+ Context.Emit(OpCodes.Conv_U4);
- Emit();
+ Context.EmitCall(typeof(Lzcnt).GetMethod(nameof(Lzcnt.LeadingZeroCount), new Type[] { typeof(uint) }));
+
+ Context.Emit(OpCodes.Conv_U8);
+ }
+ else
+ {
+ Context.EmitLdc_I4(ESize);
+
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountLeadingZeros));
+ }
EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
}
@@ -131,11 +154,14 @@ namespace ChocolArm64.Instruction
{
EmitVectorExtractZx(Context, Op.Rn, Index, 0);
- Context.Emit(OpCodes.Conv_U4);
-
- ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountSetBits8));
-
- Context.Emit(OpCodes.Conv_U8);
+ if (Popcnt.IsSupported)
+ {
+ Context.EmitCall(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { typeof(ulong) }));
+ }
+ else
+ {
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountSetBits8));
+ }
EmitVectorInsert(Context, Op.Rd, Index, 0);
}
@@ -440,6 +466,15 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Fmls_Se(AILEmitterCtx Context)
+ {
+ EmitScalarTernaryOpByElemF(Context, () =>
+ {
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Sub);
+ });
+ }
+
public static void Fmls_V(AILEmitterCtx Context)
{
EmitVectorTernaryOpF(Context, () =>
@@ -554,6 +589,14 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Fmulx_Se(AILEmitterCtx Context)
+ {
+ EmitScalarBinaryOpByElemF(Context, () =>
+ {
+ EmitSoftFloatCall(Context, nameof(ASoftFloat_32.FPMulX));
+ });
+ }
+
public static void Fmulx_V(AILEmitterCtx Context)
{
EmitVectorBinaryOpF(Context, () =>
@@ -562,6 +605,14 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Fmulx_Ve(AILEmitterCtx Context)
+ {
+ EmitVectorBinaryOpByElemF(Context, () =>
+ {
+ EmitSoftFloatCall(Context, nameof(ASoftFloat_32.FPMulX));
+ });
+ }
+
public static void Fneg_S(AILEmitterCtx Context)
{
EmitScalarUnaryOpF(Context, () => Context.Emit(OpCodes.Neg));