aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-06-30 17:40:41 +0200
committergdkchan <gab.dark.100@gmail.com>2018-06-30 12:40:41 -0300
commit53934e88727b3d86ccb5ac08a489b28c8f7fc991 (patch)
tree39a3a5bb819b4999db6368125f345013b00ef88f /ChocolArm64
parentedfd4bc860e05698946605c740fdb5857d64e917 (diff)
Add Saba_V, Sabal_V, Sabd_V, Sabdl_V, Uaba_V, Uabal_V; Update Uabd_V, Uabdl_V. Add 16 tests. (#204)
* Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdHelper.cs * Update Instructions.cs * Update CpuTest.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs
Diffstat (limited to 'ChocolArm64')
-rw-r--r--ChocolArm64/AOpCodeTable.cs6
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs113
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdHelper.cs5
3 files changed, 99 insertions, 25 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 1f60be1c..09a6ca4a 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -352,6 +352,10 @@ namespace ChocolArm64
SetA64("0x1011100x100000000010xxxxxxxxxx", AInstEmit.Rev32_V, typeof(AOpCodeSimd));
SetA64("0x001110<<100000000010xxxxxxxxxx", AInstEmit.Rev64_V, typeof(AOpCodeSimd));
SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", AInstEmit.Rsubhn_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Saba_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Sabal_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Sabd_V, typeof(AOpCodeSimdReg));
+ SetA64("0x001110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Sabdl_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg));
SetA64("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
SetA64("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
@@ -390,6 +394,8 @@ namespace ChocolArm64
SetA64("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl));
SetA64("0>001110<<0xxxxx001010xxxxxxxxxx", AInstEmit.Trn1_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<0xxxxx011010xxxxxxxxxx", AInstEmit.Trn2_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx011111xxxxxxxxxx", AInstEmit.Uaba_V, typeof(AOpCodeSimdReg));
+ SetA64("0x101110<<1xxxxx010100xxxxxxxxxx", AInstEmit.Uabal_V, typeof(AOpCodeSimdReg));
SetA64("0x101110<<1xxxxx011101xxxxxxxxxx", AInstEmit.Uabd_V, typeof(AOpCodeSimdReg));
SetA64("0x101110<<1xxxxx011100xxxxxxxxxx", AInstEmit.Uabdl_V, typeof(AOpCodeSimdReg));
SetA64("0x101110<<1xxxxx000000xxxxxxxxxx", AInstEmit.Uaddl_V, typeof(AOpCodeSimdReg));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
index efd3cc6e..e61979b0 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs
@@ -22,19 +22,6 @@ namespace ChocolArm64.Instruction
EmitVectorUnaryOpSx(Context, () => EmitAbs(Context));
}
- private static void EmitAbs(AILEmitterCtx Context)
- {
- AILLabel LblTrue = new AILLabel();
-
- Context.Emit(OpCodes.Dup);
- Context.Emit(OpCodes.Ldc_I4_0);
- Context.Emit(OpCodes.Bge_S, LblTrue);
-
- Context.Emit(OpCodes.Neg);
-
- Context.MarkLabel(LblTrue);
- }
-
public static void Add_S(AILEmitterCtx Context)
{
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
@@ -179,6 +166,19 @@ namespace ChocolArm64.Instruction
}
}
+ private static void EmitAbs(AILEmitterCtx Context)
+ {
+ AILLabel LblTrue = new AILLabel();
+
+ Context.Emit(OpCodes.Dup);
+ Context.Emit(OpCodes.Ldc_I4_0);
+ Context.Emit(OpCodes.Bge_S, LblTrue);
+
+ Context.Emit(OpCodes.Neg);
+
+ Context.MarkLabel(LblTrue);
+ }
+
private static void EmitHighNarrow(AILEmitterCtx Context, Action Emit, bool Round)
{
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
@@ -188,6 +188,8 @@ namespace ChocolArm64.Instruction
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
+ long RoundConst = 1L << (ESize - 1);
+
for (int Index = 0; Index < Elems; Index++)
{
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1);
@@ -197,7 +199,7 @@ namespace ChocolArm64.Instruction
if (Round)
{
- Context.EmitLdc_I8(1L << (ESize - 1));
+ Context.EmitLdc_I8(RoundConst);
Context.Emit(OpCodes.Add);
}
@@ -220,11 +222,11 @@ namespace ChocolArm64.Instruction
int Elems = (!Scalar ? 8 >> Op.Size : 1);
int ESize = 8 << Op.Size;
+ int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);
+
int TMaxValue = (SignedDst ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L));
int TMinValue = (SignedDst ? -((1 << (ESize - 1))) : 0);
- int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);
-
Context.EmitLdc_I8(0L);
Context.EmitSttmp();
@@ -1107,6 +1109,46 @@ namespace ChocolArm64.Instruction
EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: true);
}
+ public static void Saba_V(AILEmitterCtx Context)
+ {
+ EmitVectorTernaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+
+ Context.Emit(OpCodes.Add);
+ });
+ }
+
+ public static void Sabal_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmTernaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+
+ Context.Emit(OpCodes.Add);
+ });
+ }
+
+ public static void Sabd_V(AILEmitterCtx Context)
+ {
+ EmitVectorBinaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+ });
+ }
+
+ public static void Sabdl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpSx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+ });
+ }
+
public static void Saddw_V(AILEmitterCtx Context)
{
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add));
@@ -1186,23 +1228,44 @@ namespace ChocolArm64.Instruction
EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: false);
}
- public static void Uabd_V(AILEmitterCtx Context)
+ public static void Uaba_V(AILEmitterCtx Context)
{
- EmitVectorBinaryOpZx(Context, () => EmitAbd(Context));
+ EmitVectorTernaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+
+ Context.Emit(OpCodes.Add);
+ });
}
- public static void Uabdl_V(AILEmitterCtx Context)
+ public static void Uabal_V(AILEmitterCtx Context)
{
- EmitVectorWidenRnRmBinaryOpZx(Context, () => EmitAbd(Context));
+ EmitVectorWidenRnRmTernaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+
+ Context.Emit(OpCodes.Add);
+ });
}
- private static void EmitAbd(AILEmitterCtx Context)
+ public static void Uabd_V(AILEmitterCtx Context)
{
- Context.Emit(OpCodes.Sub);
-
- Type[] Types = new Type[] { typeof(long) };
+ EmitVectorBinaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+ });
+ }
- Context.EmitCall(typeof(Math).GetMethod(nameof(Math.Abs), Types));
+ public static void Uabdl_V(AILEmitterCtx Context)
+ {
+ EmitVectorWidenRnRmBinaryOpZx(Context, () =>
+ {
+ Context.Emit(OpCodes.Sub);
+ EmitAbs(Context);
+ });
}
public static void Uaddl_V(AILEmitterCtx Context)
diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
index bca45649..83f6ca25 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs
@@ -483,6 +483,11 @@ namespace ChocolArm64.Instruction
EmitVectorOp(Context, Emit, OperFlags.RnRm, true);
}
+ public static void EmitVectorTernaryOpSx(AILEmitterCtx Context, Action Emit)
+ {
+ EmitVectorOp(Context, Emit, OperFlags.RdRnRm, true);
+ }
+
public static void EmitVectorUnaryOpZx(AILEmitterCtx Context, Action Emit)
{
EmitVectorOp(Context, Emit, OperFlags.Rn, false);