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:
parent
02b8d80068
commit
a3a5545c05
5 changed files with 79 additions and 31 deletions
|
@ -387,6 +387,7 @@ namespace ChocolArm64
|
|||
SetA64("0100111101xxxxxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
|
||||
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", 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("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__Vms, typeof(AOpCodeSimdMemMs));
|
||||
SetA64("0x00110100x00000xxxxxxxxxxxxxxxx", AInstEmit.St__Vss, typeof(AOpCodeSimdMemSs));
|
||||
|
@ -430,6 +431,7 @@ namespace ChocolArm64
|
|||
SetA64("0110111101xxxxxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm));
|
||||
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", 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<<0xxxxx010110xxxxxxxxxx", AInstEmit.Uzp2_V, typeof(AOpCodeSimdReg));
|
||||
SetA64("0x001110<<100001001010xxxxxxxxxx", AInstEmit.Xtn_V, typeof(AOpCodeSimd));
|
||||
|
|
|
@ -1072,6 +1072,11 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorSaturatingNarrowOpSxZx(Context, () => { });
|
||||
}
|
||||
|
||||
public static void Ssubw_V(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Sub));
|
||||
}
|
||||
|
||||
public static void Sub_S(AILEmitterCtx Context)
|
||||
{
|
||||
EmitScalarBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
||||
|
@ -1225,5 +1230,10 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
EmitVectorSaturatingNarrowOpZxZx(Context, () => { });
|
||||
}
|
||||
|
||||
public static void Usubw_V(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -364,7 +364,7 @@ namespace ChocolArm64.Instruction
|
|||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
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));
|
||||
|
||||
|
@ -408,7 +408,7 @@ namespace ChocolArm64.Instruction
|
|||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
||||
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));
|
||||
|
||||
|
|
|
@ -419,20 +419,25 @@ namespace ChocolArm64.Instruction
|
|||
int SizeF = Op.Size & 1;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (Opers.HasFlag(OperFlags.Rn))
|
||||
if (Rn)
|
||||
{
|
||||
EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
|
||||
}
|
||||
|
||||
if (Opers.HasFlag(OperFlags.Rm))
|
||||
if (Rm)
|
||||
{
|
||||
EmitVectorExtractF(Context, ((AOpCodeSimdReg)Op).Rm, Index, SizeF);
|
||||
}
|
||||
|
@ -469,8 +474,9 @@ namespace ChocolArm64.Instruction
|
|||
int SizeF = Op.Size & 1;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -531,19 +537,23 @@ namespace ChocolArm64.Instruction
|
|||
int Bytes = Op.GetBitsCount() >> 3;
|
||||
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++)
|
||||
{
|
||||
if (Opers.HasFlag(OperFlags.Rd))
|
||||
if (Rd)
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
if (Opers.HasFlag(OperFlags.Rn))
|
||||
if (Rn)
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
if (Opers.HasFlag(OperFlags.Rm))
|
||||
if (Rm)
|
||||
{
|
||||
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
|
||||
}
|
||||
|
@ -662,9 +672,6 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Op.Rd);
|
||||
Context.EmitStvectmp();
|
||||
|
||||
int Elems = 8 >> Op.Size;
|
||||
|
||||
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
|
||||
|
@ -707,9 +714,6 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Op.Rd);
|
||||
Context.EmitStvectmp();
|
||||
|
||||
int Elems = 8 >> Op.Size;
|
||||
|
||||
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
|
||||
|
@ -747,21 +751,25 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
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;
|
||||
int Half = Elems >> 1;
|
||||
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
for (int Index = 0; Index < Pairs; 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, Index < Half ? Op.Rn : Op.Rm, Elem + 1, Op.Size, Signed);
|
||||
EmitVectorExtract(Context, Op.Rn, Idx, Op.Size, Signed);
|
||||
EmitVectorExtract(Context, Op.Rn, Idx + 1, Op.Size, Signed);
|
||||
|
||||
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();
|
||||
|
@ -818,7 +826,7 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
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;
|
||||
|
||||
Context.EmitLdc_I8(0L);
|
||||
|
@ -871,7 +879,7 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
if (Scalar)
|
||||
{
|
||||
EmitVectorZeroLower(Context, Op.Rd);
|
||||
EmitVectorZeroLowerTmp(Context);
|
||||
}
|
||||
|
||||
EmitVectorInsertTmp(Context, Part + Index, Op.Size);
|
||||
|
@ -963,6 +971,11 @@ namespace ChocolArm64.Instruction
|
|||
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)
|
||||
{
|
||||
EmitVectorInsert(Context, Rd, 1, 3, 0);
|
||||
|
@ -1008,6 +1021,20 @@ namespace ChocolArm64.Instruction
|
|||
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)
|
||||
{
|
||||
ThrowIfInvalidF(Index, Size);
|
||||
|
|
|
@ -295,13 +295,22 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;
|
||||
|
||||
if (Part != 0)
|
||||
{
|
||||
Context.EmitLdvec(Op.Rd);
|
||||
Context.EmitStvectmp();
|
||||
}
|
||||
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
EmitVectorZeroUpper(Context, Op.Rd);
|
||||
|
@ -342,7 +351,7 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorExtractZx(Context, Op.Rm, Idx + Part, Op.Size);
|
||||
|
||||
EmitVectorInsertTmp(Context, Idx + 1, Op.Size);
|
||||
EmitVectorInsertTmp(Context, Idx , Op.Size);
|
||||
EmitVectorInsertTmp(Context, Idx, Op.Size);
|
||||
}
|
||||
|
||||
Context.EmitLdvectmp();
|
||||
|
@ -398,7 +407,7 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorExtractZx(Context, Op.Rm, Base + Index, Op.Size);
|
||||
|
||||
EmitVectorInsertTmp(Context, Idx + 1, Op.Size);
|
||||
EmitVectorInsertTmp(Context, Idx , Op.Size);
|
||||
EmitVectorInsertTmp(Context, Idx, Op.Size);
|
||||
}
|
||||
|
||||
Context.EmitLdvectmp();
|
||||
|
|
Loading…
Reference in a new issue