aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64
diff options
context:
space:
mode:
Diffstat (limited to 'ChocolArm64')
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdArithmetic.cs52
-rw-r--r--ChocolArm64/Instructions/InstEmitSimdHelper.cs29
-rw-r--r--ChocolArm64/OpCodeTable.cs8
3 files changed, 74 insertions, 15 deletions
diff --git a/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs b/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
index 0e610bbb..8cf5c2c5 100644
--- a/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instructions/InstEmitSimdArithmetic.cs
@@ -68,21 +68,7 @@ namespace ChocolArm64.Instructions
public static void Addv_V(ILEmitterCtx context)
{
- OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
-
- int bytes = op.GetBitsCount() >> 3;
- int elems = bytes >> op.Size;
-
- EmitVectorExtractZx(context, op.Rn, 0, op.Size);
-
- for (int index = 1; index < elems; index++)
- {
- EmitVectorExtractZx(context, op.Rn, index, op.Size);
-
- context.Emit(OpCodes.Add);
- }
-
- EmitScalarSet(context, op.Rd, op.Size);
+ EmitVectorAcrossVectorOpZx(context, () => context.Emit(OpCodes.Add));
}
public static void Cls_V(ILEmitterCtx context)
@@ -2388,6 +2374,15 @@ namespace ChocolArm64.Instructions
EmitVectorPairwiseOpSx(context, () => context.EmitCall(mthdInfo));
}
+ public static void Smaxv_V(ILEmitterCtx context)
+ {
+ Type[] types = new Type[] { typeof(long), typeof(long) };
+
+ MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
+
+ EmitVectorAcrossVectorOpSx(context, () => context.EmitCall(mthdInfo));
+ }
+
public static void Smin_V(ILEmitterCtx context)
{
if (Optimizations.UseSse41)
@@ -2429,6 +2424,15 @@ namespace ChocolArm64.Instructions
EmitVectorPairwiseOpSx(context, () => context.EmitCall(mthdInfo));
}
+ public static void Sminv_V(ILEmitterCtx context)
+ {
+ Type[] types = new Type[] { typeof(long), typeof(long) };
+
+ MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
+
+ EmitVectorAcrossVectorOpSx(context, () => context.EmitCall(mthdInfo));
+ }
+
public static void Smlal_V(ILEmitterCtx context)
{
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
@@ -3208,6 +3212,15 @@ namespace ChocolArm64.Instructions
EmitVectorPairwiseOpZx(context, () => context.EmitCall(mthdInfo));
}
+ public static void Umaxv_V(ILEmitterCtx context)
+ {
+ Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Max), types);
+
+ EmitVectorAcrossVectorOpZx(context, () => context.EmitCall(mthdInfo));
+ }
+
public static void Umin_V(ILEmitterCtx context)
{
if (Optimizations.UseSse41)
@@ -3249,6 +3262,15 @@ namespace ChocolArm64.Instructions
EmitVectorPairwiseOpZx(context, () => context.EmitCall(mthdInfo));
}
+ public static void Uminv_V(ILEmitterCtx context)
+ {
+ Type[] types = new Type[] { typeof(ulong), typeof(ulong) };
+
+ MethodInfo mthdInfo = typeof(Math).GetMethod(nameof(Math.Min), types);
+
+ EmitVectorAcrossVectorOpZx(context, () => context.EmitCall(mthdInfo));
+ }
+
public static void Umlal_V(ILEmitterCtx context)
{
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
diff --git a/ChocolArm64/Instructions/InstEmitSimdHelper.cs b/ChocolArm64/Instructions/InstEmitSimdHelper.cs
index 2bcda35f..f343dba8 100644
--- a/ChocolArm64/Instructions/InstEmitSimdHelper.cs
+++ b/ChocolArm64/Instructions/InstEmitSimdHelper.cs
@@ -821,6 +821,35 @@ namespace ChocolArm64.Instructions
}
}
+ public static void EmitVectorAcrossVectorOpSx(ILEmitterCtx context, Action emit)
+ {
+ EmitVectorAcrossVectorOp(context, emit, true);
+ }
+
+ public static void EmitVectorAcrossVectorOpZx(ILEmitterCtx context, Action emit)
+ {
+ EmitVectorAcrossVectorOp(context, emit, false);
+ }
+
+ public static void EmitVectorAcrossVectorOp(ILEmitterCtx context, Action emit, bool signed)
+ {
+ OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
+
+ int bytes = op.GetBitsCount() >> 3;
+ int elems = bytes >> op.Size;
+
+ EmitVectorExtract(context, op.Rn, 0, op.Size, signed);
+
+ for (int index = 1; index < elems; index++)
+ {
+ EmitVectorExtract(context, op.Rn, index, op.Size, signed);
+
+ emit();
+ }
+
+ EmitScalarSet(context, op.Rd, op.Size);
+ }
+
public static void EmitVectorPairwiseOpF(ILEmitterCtx context, Action emit)
{
OpCodeSimdReg64 op = (OpCodeSimdReg64)context.CurrOp;
diff --git a/ChocolArm64/OpCodeTable.cs b/ChocolArm64/OpCodeTable.cs
index fb8b19cd..a1bbd4bc 100644
--- a/ChocolArm64/OpCodeTable.cs
+++ b/ChocolArm64/OpCodeTable.cs
@@ -461,8 +461,12 @@ namespace ChocolArm64
SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstEmit.Sli_V, typeof(OpCodeSimdShImm64));
SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstEmit.Smax_V, typeof(OpCodeSimdReg64));
SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstEmit.Smaxp_V, typeof(OpCodeSimdReg64));
+ SetA64("000011100x110000101010xxxxxxxxxx", InstEmit.Smaxv_V, typeof(OpCodeSimd64));
+ SetA64("01001110<<110000101010xxxxxxxxxx", InstEmit.Smaxv_V, typeof(OpCodeSimd64));
SetA64("0x001110<<1xxxxx011011xxxxxxxxxx", InstEmit.Smin_V, typeof(OpCodeSimdReg64));
SetA64("0x001110<<1xxxxx101011xxxxxxxxxx", InstEmit.Sminp_V, typeof(OpCodeSimdReg64));
+ SetA64("000011100x110001101010xxxxxxxxxx", InstEmit.Sminv_V, typeof(OpCodeSimd64));
+ SetA64("01001110<<110001101010xxxxxxxxxx", InstEmit.Sminv_V, typeof(OpCodeSimd64));
SetA64("0x001110<<1xxxxx100000xxxxxxxxxx", InstEmit.Smlal_V, typeof(OpCodeSimdReg64));
SetA64("0x001111xxxxxxxx0010x0xxxxxxxxxx", InstEmit.Smlal_Ve, typeof(OpCodeSimdRegElem64));
SetA64("0x001110<<1xxxxx101000xxxxxxxxxx", InstEmit.Smlsl_V, typeof(OpCodeSimdReg64));
@@ -556,8 +560,12 @@ namespace ChocolArm64
SetA64("0x101110<<1xxxxx001001xxxxxxxxxx", InstEmit.Uhsub_V, typeof(OpCodeSimdReg64));
SetA64("0x101110<<1xxxxx011001xxxxxxxxxx", InstEmit.Umax_V, typeof(OpCodeSimdReg64));
SetA64("0x101110<<1xxxxx101001xxxxxxxxxx", InstEmit.Umaxp_V, typeof(OpCodeSimdReg64));
+ SetA64("001011100x110000101010xxxxxxxxxx", InstEmit.Umaxv_V, typeof(OpCodeSimd64));
+ SetA64("01101110<<110000101010xxxxxxxxxx", InstEmit.Umaxv_V, typeof(OpCodeSimd64));
SetA64("0x101110<<1xxxxx011011xxxxxxxxxx", InstEmit.Umin_V, typeof(OpCodeSimdReg64));
SetA64("0x101110<<1xxxxx101011xxxxxxxxxx", InstEmit.Uminp_V, typeof(OpCodeSimdReg64));
+ SetA64("001011100x110001101010xxxxxxxxxx", InstEmit.Uminv_V, typeof(OpCodeSimd64));
+ SetA64("01101110<<110001101010xxxxxxxxxx", InstEmit.Uminv_V, typeof(OpCodeSimd64));
SetA64("0x101110<<1xxxxx100000xxxxxxxxxx", InstEmit.Umlal_V, typeof(OpCodeSimdReg64));
SetA64("0x101111xxxxxxxx0010x0xxxxxxxxxx", InstEmit.Umlal_Ve, typeof(OpCodeSimdRegElem64));
SetA64("0x101110<<1xxxxx101000xxxxxxxxxx", InstEmit.Umlsl_V, typeof(OpCodeSimdReg64));