aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64
diff options
context:
space:
mode:
authorLDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com>2018-06-18 19:55:26 +0200
committergdkchan <gab.dark.100@gmail.com>2018-06-18 14:55:26 -0300
commit3bdd109f45cc3edc0217f5e952a6cc672ce53580 (patch)
tree599a1e8b28f04ca750fde0f069500dee702088bc /ChocolArm64
parent35e695552e75a20e54a2bd7fb372d0492c955ca1 (diff)
Add Cmeq_S, Cmge_S, Cmgt_S, Cmhi_S, Cmhs_S, Cmle_S, Cmlt_S (Reg, Zero) & Cmtst_S compare instructions. Add 22 compare tests (Scalar, Vector). Add Eor_V, Not_V tests. (#171)
* Add files via upload * Add files via upload * Delete CpuTestScalar.cs * Update CpuTestSimdArithmetic.cs
Diffstat (limited to 'ChocolArm64')
-rw-r--r--ChocolArm64/AOpCodeTable.cs11
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdCmp.cs137
2 files changed, 103 insertions, 45 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs
index 903d6e0f..853c06a6 100644
--- a/ChocolArm64/AOpCodeTable.cs
+++ b/ChocolArm64/AOpCodeTable.cs
@@ -187,16 +187,27 @@ namespace ChocolArm64
SetA64("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<100000010010xxxxxxxxxx", AInstEmit.Cls_V, typeof(AOpCodeSimd));
SetA64("0x101110<<100000010010xxxxxxxxxx", AInstEmit.Clz_V, typeof(AOpCodeSimd));
+ SetA64("01111110111xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_S, typeof(AOpCodeSimdReg));
+ SetA64("0101111011100000100110xxxxxxxxxx", AInstEmit.Cmeq_S, typeof(AOpCodeSimd));
SetA64("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
+ SetA64("01011110111xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_S, typeof(AOpCodeSimdReg));
+ SetA64("0111111011100000100010xxxxxxxxxx", AInstEmit.Cmge_S, typeof(AOpCodeSimd));
SetA64("0>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
SetA64("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
+ SetA64("01011110111xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_S, typeof(AOpCodeSimdReg));
+ SetA64("0101111011100000100010xxxxxxxxxx", AInstEmit.Cmgt_S, typeof(AOpCodeSimd));
SetA64("0>001110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
+ SetA64("01111110111xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_S, typeof(AOpCodeSimdReg));
SetA64("0>101110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
+ SetA64("01111110111xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_S, typeof(AOpCodeSimdReg));
SetA64("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
+ SetA64("0111111011100000100110xxxxxxxxxx", AInstEmit.Cmle_S, typeof(AOpCodeSimd));
SetA64("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
+ SetA64("0101111011100000101010xxxxxxxxxx", AInstEmit.Cmlt_S, typeof(AOpCodeSimd));
SetA64("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
+ SetA64("01011110111xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_S, typeof(AOpCodeSimdReg));
SetA64("0>001110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_V, typeof(AOpCodeSimdReg));
SetA64("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
SetA64("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
diff --git a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
index 3ffab1e8..ba8ac3e2 100644
--- a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
+++ b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs
@@ -12,6 +12,11 @@ namespace ChocolArm64.Instruction
{
static partial class AInstEmit
{
+ public static void Cmeq_S(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Beq_S, Scalar: true);
+ }
+
public static void Cmeq_V(AILEmitterCtx Context)
{
if (AOptimizations.UseSse2 && Context.CurrOp is AOpCodeSimdReg Op && Op.Size < 3)
@@ -20,13 +25,23 @@ namespace ChocolArm64.Instruction
}
else
{
- EmitVectorCmp(Context, OpCodes.Beq_S);
+ EmitCmp(Context, OpCodes.Beq_S, Scalar: false);
}
}
+ public static void Cmge_S(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Bge_S, Scalar: true);
+ }
+
public static void Cmge_V(AILEmitterCtx Context)
{
- EmitVectorCmp(Context, OpCodes.Bge_S);
+ EmitCmp(Context, OpCodes.Bge_S, Scalar: false);
+ }
+
+ public static void Cmgt_S(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Bgt_S, Scalar: true);
}
public static void Cmgt_V(AILEmitterCtx Context)
@@ -37,67 +52,58 @@ namespace ChocolArm64.Instruction
}
else
{
- EmitVectorCmp(Context, OpCodes.Bgt_S);
+ EmitCmp(Context, OpCodes.Bgt_S, Scalar: false);
}
}
- public static void Cmhi_V(AILEmitterCtx Context)
+ public static void Cmhi_S(AILEmitterCtx Context)
{
- EmitVectorCmp(Context, OpCodes.Bgt_Un_S);
+ EmitCmp(Context, OpCodes.Bgt_Un_S, Scalar: true);
}
- public static void Cmhs_V(AILEmitterCtx Context)
+ public static void Cmhi_V(AILEmitterCtx Context)
{
- EmitVectorCmp(Context, OpCodes.Bge_Un_S);
+ EmitCmp(Context, OpCodes.Bgt_Un_S, Scalar: false);
}
- public static void Cmle_V(AILEmitterCtx Context)
+ public static void Cmhs_S(AILEmitterCtx Context)
{
- EmitVectorCmp(Context, OpCodes.Ble_S);
+ EmitCmp(Context, OpCodes.Bge_Un_S, Scalar: true);
}
- public static void Cmlt_V(AILEmitterCtx Context)
+ public static void Cmhs_V(AILEmitterCtx Context)
{
- EmitVectorCmp(Context, OpCodes.Blt_S);
+ EmitCmp(Context, OpCodes.Bge_Un_S, Scalar: false);
}
- public static void Cmtst_V(AILEmitterCtx Context)
+ public static void Cmle_S(AILEmitterCtx Context)
{
- AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
-
- int Bytes = Context.CurrOp.GetBitsCount() >> 3;
-
- ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
-
- for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
- {
- EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
- EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
-
- AILLabel LblTrue = new AILLabel();
- AILLabel LblEnd = new AILLabel();
-
- Context.Emit(OpCodes.And);
-
- Context.EmitLdc_I8(0);
-
- Context.Emit(OpCodes.Bne_Un_S, LblTrue);
-
- EmitVectorInsert(Context, Op.Rd, Index, Op.Size, 0);
+ EmitCmp(Context, OpCodes.Ble_S, Scalar: true);
+ }
- Context.Emit(OpCodes.Br_S, LblEnd);
+ public static void Cmle_V(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Ble_S, Scalar: false);
+ }
- Context.MarkLabel(LblTrue);
+ public static void Cmlt_S(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Blt_S, Scalar: true);
+ }
- EmitVectorInsert(Context, Op.Rd, Index, Op.Size, (long)SzMask);
+ public static void Cmlt_V(AILEmitterCtx Context)
+ {
+ EmitCmp(Context, OpCodes.Blt_S, Scalar: false);
+ }
- Context.MarkLabel(LblEnd);
- }
+ public static void Cmtst_S(AILEmitterCtx Context)
+ {
+ EmitCmtst(Context, Scalar: true);
+ }
- if (Op.RegisterSize == ARegisterSize.SIMD64)
- {
- EmitVectorZeroUpper(Context, Op.Rd);
- }
+ public static void Cmtst_V(AILEmitterCtx Context)
+ {
+ EmitCmtst(Context, Scalar: false);
}
public static void Fccmp_S(AILEmitterCtx Context)
@@ -325,15 +331,16 @@ namespace ChocolArm64.Instruction
}
}
- private static void EmitVectorCmp(AILEmitterCtx Context, OpCode ILOp)
+ private static void EmitCmp(AILEmitterCtx Context, OpCode ILOp, bool Scalar)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Elems = (!Scalar ? Bytes >> Op.Size : 1);
ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
- for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
+ for (int Index = 0; Index < Elems; Index++)
{
EmitVectorExtractSx(Context, Op.Rn, Index, Op.Size);
@@ -362,7 +369,47 @@ namespace ChocolArm64.Instruction
Context.MarkLabel(LblEnd);
}
- if (Op.RegisterSize == ARegisterSize.SIMD64)
+ if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
+ private static void EmitCmtst(AILEmitterCtx Context, bool Scalar)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+ int Elems = (!Scalar ? Bytes >> Op.Size : 1);
+
+ ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
+
+ for (int Index = 0; Index < Elems; Index++)
+ {
+ EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
+ EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
+
+ AILLabel LblTrue = new AILLabel();
+ AILLabel LblEnd = new AILLabel();
+
+ Context.Emit(OpCodes.And);
+
+ Context.EmitLdc_I8(0);
+
+ Context.Emit(OpCodes.Bne_Un_S, LblTrue);
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size, 0);
+
+ Context.Emit(OpCodes.Br_S, LblEnd);
+
+ Context.MarkLabel(LblTrue);
+
+ EmitVectorInsert(Context, Op.Rd, Index, Op.Size, (long)SzMask);
+
+ Context.MarkLabel(LblEnd);
+ }
+
+ if ((Op.RegisterSize == ARegisterSize.SIMD64) || Scalar)
{
EmitVectorZeroUpper(Context, Op.Rd);
}