Implement Ssubw_V and Usubw_V instructions. (#287)

* Update AOpCodeTable.cs

* Update AInstEmitSimdHelper.cs

* Update AInstEmitSimdArithmetic.cs

* Update AInstEmitSimdMove.cs

* Update AInstEmitSimdCmp.cs

* Update Instructions.cs

* Update CpuTestSimd.cs

* Update CpuTestSimdReg.cs
This commit is contained in:
LDj3SNuD 2018-07-19 02:06:28 +02:00 committed by gdkchan
parent 02b8d80068
commit a3a5545c05
5 changed files with 79 additions and 31 deletions

View file

@ -387,6 +387,7 @@ namespace ChocolArm64
SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm)); SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm)); SetA64("0x00111100>>>xxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
SetA64("0100111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm)); SetA64("0100111101xxxxxx000101xxxxxxxxxx", AInstEmit.Ssra_V, typeof(AOpCodeSimdShImm));
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Ssubw_V, typeof(AOpCodeSimdReg));
SetA64("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs)); SetA64("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs)); SetA64("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", AInstEmit.St__Vss, typeof(AOpCodeSimdMemSs)); SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", AInstEmit.St__Vss, typeof(AOpCodeSimdMemSs));
@ -430,6 +431,7 @@ namespace ChocolArm64
SetA64("0110111101xxxxxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm)); SetA64("0110111101xxxxxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm));
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm)); SetA64("0x10111100>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
SetA64("0110111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm)); SetA64("0110111101xxxxxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", AInstEmit.Usubw_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V, typeof(AOpCodeSimdReg)); SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", AInstEmit.Uzp1_V, typeof(AOpCodeSimdReg));
SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V, typeof(AOpCodeSimdReg)); SetA64("0>001110<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V, typeof(AOpCodeSimdReg));
SetA64("0x001110<<100001001010xxxxxxxxxx", AInstEmit.Xtn_V, typeof(AOpCodeSimd)); SetA64("0x001110<<100001001010xxxxxxxxxx", AInstEmit.Xtn_V, typeof(AOpCodeSimd));

View file

@ -1072,6 +1072,11 @@ namespace ChocolArm64.Instruction
EmitVectorSaturatingNarrowOpSxZx(Context, () => { }); EmitVectorSaturatingNarrowOpSxZx(Context, () => { });
} }
public static void Ssubw_V(AILEmitterCtx Context)
{
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
}
public static void Sub_S(AILEmitterCtx Context) public static void Sub_S(AILEmitterCtx Context)
{ {
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub)); EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
@ -1225,5 +1230,10 @@ namespace ChocolArm64.Instruction
{ {
EmitVectorSaturatingNarrowOpZxZx(Context, () => { }); EmitVectorSaturatingNarrowOpZxZx(Context, () => { });
} }
public static void Usubw_V(AILEmitterCtx Context)
{
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
}
} }
} }

View file

@ -364,7 +364,7 @@ namespace ChocolArm64.Instruction
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Op.GetBitsCount() >> 3; int Bytes = Op.GetBitsCount() >> 3;
int Elems = (!Scalar ? Bytes >> Op.Size : 1); int Elems = !Scalar ? Bytes >> Op.Size : 1;
ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size)); ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
@ -408,7 +408,7 @@ namespace ChocolArm64.Instruction
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
int Bytes = Op.GetBitsCount() >> 3; int Bytes = Op.GetBitsCount() >> 3;
int Elems = (!Scalar ? Bytes >> Op.Size : 1); int Elems = !Scalar ? Bytes >> Op.Size : 1;
ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size)); ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
@ -522,4 +522,4 @@ namespace ChocolArm64.Instruction
Context.MarkLabel(LblEnd); Context.MarkLabel(LblEnd);
} }
} }
} }

View file

@ -419,20 +419,25 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1; int SizeF = Op.Size & 1;
int Bytes = Op.GetBitsCount() >> 3; int Bytes = Op.GetBitsCount() >> 3;
int Elems = Bytes >> SizeF + 2;
for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++) bool Rd = (Opers & OperFlags.Rd) != 0;
bool Rn = (Opers & OperFlags.Rn) != 0;
bool Rm = (Opers & OperFlags.Rm) != 0;
for (int Index = 0; Index < Elems; Index++)
{ {
if (Opers.HasFlag(OperFlags.Rd)) if (Rd)
{ {
EmitVectorExtractF(Context, Op.Rd, Index, SizeF); EmitVectorExtractF(Context, Op.Rd, Index, SizeF);
} }
if (Opers.HasFlag(OperFlags.Rn)) if (Rn)
{ {
EmitVectorExtractF(Context, Op.Rn, Index, SizeF); EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
} }
if (Opers.HasFlag(OperFlags.Rm)) if (Rm)
{ {
EmitVectorExtractF(Context, ((AOpCodeSimdReg)Op).Rm, Index, SizeF); EmitVectorExtractF(Context, ((AOpCodeSimdReg)Op).Rm, Index, SizeF);
} }
@ -469,8 +474,9 @@ namespace ChocolArm64.Instruction
int SizeF = Op.Size & 1; int SizeF = Op.Size & 1;
int Bytes = Op.GetBitsCount() >> 3; int Bytes = Op.GetBitsCount() >> 3;
int Elems = Bytes >> SizeF + 2;
for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++) for (int Index = 0; Index < Elems; Index++)
{ {
if (Ternary) if (Ternary)
{ {
@ -531,19 +537,23 @@ namespace ChocolArm64.Instruction
int Bytes = Op.GetBitsCount() >> 3; int Bytes = Op.GetBitsCount() >> 3;
int Elems = Bytes >> Op.Size; int Elems = Bytes >> Op.Size;
bool Rd = (Opers & OperFlags.Rd) != 0;
bool Rn = (Opers & OperFlags.Rn) != 0;
bool Rm = (Opers & OperFlags.Rm) != 0;
for (int Index = 0; Index < Elems; Index++) for (int Index = 0; Index < Elems; Index++)
{ {
if (Opers.HasFlag(OperFlags.Rd)) if (Rd)
{ {
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed); EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
} }
if (Opers.HasFlag(OperFlags.Rn)) if (Rn)
{ {
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
} }
if (Opers.HasFlag(OperFlags.Rm)) if (Rm)
{ {
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed); EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
} }
@ -662,9 +672,6 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
Context.EmitLdvec(Op.Rd);
Context.EmitStvectmp();
int Elems = 8 >> Op.Size; int Elems = 8 >> Op.Size;
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
@ -707,9 +714,6 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
Context.EmitLdvec(Op.Rd);
Context.EmitStvectmp();
int Elems = 8 >> Op.Size; int Elems = 8 >> Op.Size;
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
@ -747,21 +751,25 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
int Bytes = Op.GetBitsCount() >> 3; int Words = Op.GetBitsCount() >> 4;
int Pairs = Words >> Op.Size;
int Elems = Bytes >> Op.Size; for (int Index = 0; Index < Pairs; Index++)
int Half = Elems >> 1;
for (int Index = 0; Index < Elems; Index++)
{ {
int Elem = (Index & (Half - 1)) << 1; int Idx = Index << 1;
EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 0, Op.Size, Signed); EmitVectorExtract(Context, Op.Rn, Idx, Op.Size, Signed);
EmitVectorExtract(Context, Index < Half ? Op.Rn : Op.Rm, Elem + 1, Op.Size, Signed); EmitVectorExtract(Context, Op.Rn, Idx + 1, Op.Size, Signed);
Emit(); Emit();
EmitVectorInsertTmp(Context, Index, Op.Size); EmitVectorExtract(Context, Op.Rm, Idx, Op.Size, Signed);
EmitVectorExtract(Context, Op.Rm, Idx + 1, Op.Size, Signed);
Emit();
EmitVectorInsertTmp(Context, Pairs + Index, Op.Size);
EmitVectorInsertTmp(Context, Index, Op.Size);
} }
Context.EmitLdvectmp(); Context.EmitLdvectmp();
@ -818,7 +826,7 @@ namespace ChocolArm64.Instruction
int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0; int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0;
long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (1L << ESize) - 1L; long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (long)(~0UL >> (64 - ESize));
long TMinValue = SignedDst ? -((1 << (ESize - 1))) : 0; long TMinValue = SignedDst ? -((1 << (ESize - 1))) : 0;
Context.EmitLdc_I8(0L); Context.EmitLdc_I8(0L);
@ -871,7 +879,7 @@ namespace ChocolArm64.Instruction
if (Scalar) if (Scalar)
{ {
EmitVectorZeroLower(Context, Op.Rd); EmitVectorZeroLowerTmp(Context);
} }
EmitVectorInsertTmp(Context, Part + Index, Op.Size); EmitVectorInsertTmp(Context, Part + Index, Op.Size);
@ -963,6 +971,11 @@ namespace ChocolArm64.Instruction
EmitVectorInsert(Context, Rd, 0, 3, 0); EmitVectorInsert(Context, Rd, 0, 3, 0);
} }
public static void EmitVectorZeroLowerTmp(AILEmitterCtx Context)
{
EmitVectorInsertTmp(Context, 0, 3, 0);
}
public static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd) public static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
{ {
EmitVectorInsert(Context, Rd, 1, 3, 0); EmitVectorInsert(Context, Rd, 1, 3, 0);
@ -1008,6 +1021,20 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Reg); Context.EmitStvec(Reg);
} }
public static void EmitVectorInsertTmp(AILEmitterCtx Context, int Index, int Size, long Value)
{
ThrowIfInvalid(Index, Size);
Context.EmitLdc_I8(Value);
Context.EmitLdvectmp();
Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Size);
AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorInsertInt));
Context.EmitStvectmp();
}
public static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size) public static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
{ {
ThrowIfInvalidF(Index, Size); ThrowIfInvalidF(Index, Size);

View file

@ -295,13 +295,22 @@ namespace ChocolArm64.Instruction
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
if (Part != 0)
{
Context.EmitLdvec(Op.Rd);
Context.EmitStvectmp();
}
for (int Index = 0; Index < Elems; Index++) for (int Index = 0; Index < Elems; Index++)
{ {
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1); EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1);
EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size); EmitVectorInsertTmp(Context, Part + Index, Op.Size);
} }
Context.EmitLdvectmp();
Context.EmitStvec(Op.Rd);
if (Part == 0) if (Part == 0)
{ {
EmitVectorZeroUpper(Context, Op.Rd); EmitVectorZeroUpper(Context, Op.Rd);
@ -342,7 +351,7 @@ namespace ChocolArm64.Instruction
EmitVectorExtractZx(Context, Op.Rm, Idx + Part, Op.Size); EmitVectorExtractZx(Context, Op.Rm, Idx + Part, Op.Size);
EmitVectorInsertTmp(Context, Idx + 1, Op.Size); EmitVectorInsertTmp(Context, Idx + 1, Op.Size);
EmitVectorInsertTmp(Context, Idx , Op.Size); EmitVectorInsertTmp(Context, Idx, Op.Size);
} }
Context.EmitLdvectmp(); Context.EmitLdvectmp();
@ -398,7 +407,7 @@ namespace ChocolArm64.Instruction
EmitVectorExtractZx(Context, Op.Rm, Base + Index, Op.Size); EmitVectorExtractZx(Context, Op.Rm, Base + Index, Op.Size);
EmitVectorInsertTmp(Context, Idx + 1, Op.Size); EmitVectorInsertTmp(Context, Idx + 1, Op.Size);
EmitVectorInsertTmp(Context, Idx , Op.Size); EmitVectorInsertTmp(Context, Idx, Op.Size);
} }
Context.EmitLdvectmp(); Context.EmitLdvectmp();