aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-07-03 03:31:48 -0300
committerGitHub <noreply@github.com>2018-07-03 03:31:48 -0300
commit741773910d61a75bd5466265e5dd825d55a98e7c (patch)
tree6d2a917f4dd4e069177397e65dffe973511067af
parentc228cf320d476303da679066c67c3a8c9c6aa3e1 (diff)
Add SMAXP, SMINP, UMAX, UMAXP, UMIN and UMINP cpu instructions (#200)
-rw-r--r--ChocolArm64/AOpCodeTable.cs6
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs81
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdHelper.cs44
-rw-r--r--ChocolArm64/Translation/ILGeneratorEx.cs6
4 files changed, 106 insertions, 31 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 7cef4398..fb4763ef 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -367,7 +367,9 @@ namespace ChocolArm64
SetA64("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V, typeof(AOpCodeSimdShImm));
SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Sli_V, typeof(AOpCodeSimdShImm));
SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Smaxp_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Sminp_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg));
SetA64("01011110<<100001010010xxxxxxxxxx", AInstEmit.Sqxtn_S, typeof(AOpCodeSimd));
@@ -407,6 +409,10 @@ namespace ChocolArm64
SetA64("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_S, typeof(AOpCodeSimd));
SetA64("0x1011100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimd));
SetA64("0x101110<<1xxxxx000001xxxxxxxxxx", AInstEmit.Uhadd_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Umax_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", AInstEmit.Umaxp_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Umin_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", AInstEmit.Uminp_V, typeof(AOpCodeSimdReg));
SetA64("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
SetA64("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
SetA64("01111110<<100001010010xxxxxxxxxx", AInstEmit.Uqxtn_S, typeof(AOpCodeSimd));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index 06844526..b96b71be 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -58,32 +58,7 @@ namespace ChocolArm64.Instruction
public static void Addp_V(AILEmitterCtx Context)
{
- AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
-
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
-
- int Elems = Bytes >> Op.Size;
- int Half = Elems >> 1;
-
- for (int Index = 0; Index < Elems; Index++)
- {
- int Elem = (Index & (Half - 1)) << 1;
-
- EmitVectorExtractZx(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 0, Op.Size);
- EmitVectorExtractZx(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 1, Op.Size);
-
- Context.Emit(OpCodes.Add);
-
- EmitVectorInsertTmp(Context, Index, Op.Size);
- }
-
- Context.EmitLdvectmp();
- Context.EmitStvec(Op.Rd);
-
- if (Op.RegisterSize == ARegisterSize.SIMD64)
- {
- EmitVectorZeroUpper(Context, Op.Rd);
- }
+ EmitVectorPairwiseOpZx(Context, () => Context.Emit(OpCodes.Add));
}
public static void Addv_V(AILEmitterCtx Context)
@@ -1163,6 +1138,15 @@ namespace ChocolArm64.Instruction
EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
}
+ public static void Smaxp_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(long), typeof(long) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Max), Types);
+
+ EmitVectorPairwiseOpSx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
public static void Smin_V(AILEmitterCtx Context)
{
Type[] Types = new Type[] { typeof(long), typeof(long) };
@@ -1172,6 +1156,15 @@ namespace ChocolArm64.Instruction
EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
}
+ public static void Sminp_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(long), typeof(long) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Min), Types);
+
+ EmitVectorPairwiseOpSx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
public static void Smlal_V(AILEmitterCtx Context)
{
EmitVectorWidenRnRmTernaryOpSx(Context, () =>
@@ -1308,6 +1301,42 @@ namespace ChocolArm64.Instruction
});
}
+ public static void Umin_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Min), Types);
+
+ EmitVectorBinaryOpZx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
+ public static void Uminp_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Min), Types);
+
+ EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
+ public static void Umax_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Max), Types);
+
+ EmitVectorBinaryOpZx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
+ public static void Umaxp_V(AILEmitterCtx Context)
+ {
+ Type[] Types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Max), Types);
+
+ EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
+ }
+
public static void Umull_V(AILEmitterCtx Context)
{
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
index 83f6ca25..0f6ea42c 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
@@ -132,12 +132,12 @@ namespace ChocolArm64.Instruction
if (SizeF == 0)
{
- Type = typeof(Sse);
+ Type = typeof(Sse);
BaseType = typeof(Vector128<float>);
}
else /* if (SizeF == 1) */
{
- Type = typeof(Sse2);
+ Type = typeof(Sse2);
BaseType = typeof(Vector128<double>);
}
@@ -709,6 +709,46 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
+ public static void EmitVectorPairwiseOpSx(AILEmitterCtx Context, Action Emit)
+ {
+ EmitVectorPairwiseOp(Context, Emit, true);
+ }
+
+ public static void EmitVectorPairwiseOpZx(AILEmitterCtx Context, Action Emit)
+ {
+ EmitVectorPairwiseOp(Context, Emit, false);
+ }
+
+ private static void EmitVectorPairwiseOp(AILEmitterCtx Context, Action Emit, bool Signed)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ int Elems = Bytes >> Op.Size;
+ int Half = Elems >> 1;
+
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ int Elem = (Index & (Half - 1)) << 1;
+
+ EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 0, Op.Size, Signed);
+ EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 1, Op.Size, Signed);
+
+ Emit();
+
+ EmitVectorInsertTmp(Context, Index, Op.Size);
+ }
+
+ Context.EmitLdvectmp();
+ Context.EmitStvec(Op.Rd);
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
public static void EmitScalarSet(AILEmitterCtx Context, int Reg, int Size)
{
EmitVectorZeroAll(Context, Reg);
diff --git a/ChocolArm64/Translation/ILGeneratorEx.cs b/ChocolArm64/Translation/ILGeneratorEx.cs
index 52eb4746..40c6efa4 100644
--- a/ChocolArm64/Translation/ILGeneratorEx.cs
+++ b/ChocolArm64/Translation/ILGeneratorEx.cs
@@ -63,7 +63,7 @@ namespace ChocolArm64
else
{
throw new ArgumentOutOfRangeException(nameof(Index));
- }
+ }
}
public static void EmitLdloc(this ILGenerator Generator, int Index)
@@ -89,7 +89,7 @@ namespace ChocolArm64
throw new ArgumentOutOfRangeException(nameof(Index));
}
break;
- }
+ }
}
public static void EmitStloc(this ILGenerator Generator, int Index)
@@ -123,7 +123,7 @@ namespace ChocolArm64
for (int Index = 0; Index < Count; Index++)
{
Generator.EmitLdarg(Index);
- }
+ }
}
}
}