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
This commit is contained in:
LDj3SNuD 2018-06-18 19:55:26 +02:00 committed by gdkchan
parent ed80772500
commit 7084bf58a4
2 changed files with 103 additions and 45 deletions

View file

@ -187,16 +187,27 @@ namespace ChocolArm64
SetA64("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg)); SetA64("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<100000010010xxxxxxxxxx", AInstEmit.Cls_V, typeof(AOpCodeSimd)); SetA64("0x001110<<100000010010xxxxxxxxxx", AInstEmit.Cls_V, typeof(AOpCodeSimd));
SetA64("0x101110<<100000010010xxxxxxxxxx", AInstEmit.Clz_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>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd)); 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>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
SetA64("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd)); 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<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd)); 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("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("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("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("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("0>001110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_V, typeof(AOpCodeSimdReg));
SetA64("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd)); SetA64("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
SetA64("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns)); SetA64("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));

View file

@ -12,6 +12,11 @@ namespace ChocolArm64.Instruction
{ {
static partial class AInstEmit 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) public static void Cmeq_V(AILEmitterCtx Context)
{ {
if (AOptimizations.UseSse2 && Context.CurrOp is AOpCodeSimdReg Op && Op.Size < 3) if (AOptimizations.UseSse2 && Context.CurrOp is AOpCodeSimdReg Op && Op.Size < 3)
@ -20,13 +25,23 @@ namespace ChocolArm64.Instruction
} }
else 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) 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) public static void Cmgt_V(AILEmitterCtx Context)
@ -37,67 +52,58 @@ namespace ChocolArm64.Instruction
} }
else else
{ {
EmitVectorCmp(Context, OpCodes.Bgt_S); EmitCmp(Context, OpCodes.Bgt_S, Scalar: false);
} }
} }
public static void Cmhi_S(AILEmitterCtx Context)
{
EmitCmp(Context, OpCodes.Bgt_Un_S, Scalar: true);
}
public static void Cmhi_V(AILEmitterCtx Context) public static void Cmhi_V(AILEmitterCtx Context)
{ {
EmitVectorCmp(Context, OpCodes.Bgt_Un_S); EmitCmp(Context, OpCodes.Bgt_Un_S, Scalar: false);
}
public static void Cmhs_S(AILEmitterCtx Context)
{
EmitCmp(Context, OpCodes.Bge_Un_S, Scalar: true);
} }
public static void Cmhs_V(AILEmitterCtx Context) public static void Cmhs_V(AILEmitterCtx Context)
{ {
EmitVectorCmp(Context, OpCodes.Bge_Un_S); EmitCmp(Context, OpCodes.Bge_Un_S, Scalar: false);
}
public static void Cmle_S(AILEmitterCtx Context)
{
EmitCmp(Context, OpCodes.Ble_S, Scalar: true);
} }
public static void Cmle_V(AILEmitterCtx Context) public static void Cmle_V(AILEmitterCtx Context)
{ {
EmitVectorCmp(Context, OpCodes.Ble_S); EmitCmp(Context, OpCodes.Ble_S, Scalar: false);
}
public static void Cmlt_S(AILEmitterCtx Context)
{
EmitCmp(Context, OpCodes.Blt_S, Scalar: true);
} }
public static void Cmlt_V(AILEmitterCtx Context) public static void Cmlt_V(AILEmitterCtx Context)
{ {
EmitVectorCmp(Context, OpCodes.Blt_S); EmitCmp(Context, OpCodes.Blt_S, Scalar: false);
}
public static void Cmtst_S(AILEmitterCtx Context)
{
EmitCmtst(Context, Scalar: true);
} }
public static void Cmtst_V(AILEmitterCtx Context) public static void Cmtst_V(AILEmitterCtx Context)
{ {
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; EmitCmtst(Context, Scalar: false);
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);
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)
{
EmitVectorZeroUpper(Context, Op.Rd);
}
} }
public static void Fccmp_S(AILEmitterCtx Context) 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; AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3; int Bytes = Context.CurrOp.GetBitsCount() >> 3;
int Elems = (!Scalar ? Bytes >> Op.Size : 1);
ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size)); 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); EmitVectorExtractSx(Context, Op.Rn, Index, Op.Size);
@ -362,7 +369,47 @@ namespace ChocolArm64.Instruction
Context.MarkLabel(LblEnd); 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); EmitVectorZeroUpper(Context, Op.Rd);
} }