Add Rbit_V instruction. Add 8 tests (Rbit_V; Rev16_V, Rev32_V, Rev64_V). Improve CountSetBits8() algorithm. (#212)
* Update AOpCodeTable.cs * Update AInstEmitSimdArithmetic.cs * Update AInstEmitSimdLogical.cs * Update AVectorHelper.cs * Update ASoftFallback.cs * Update Instructions.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Improve CountSetBits8() algorithm. * Improve CountSetBits8() algorithm.
This commit is contained in:
parent
051740f344
commit
8d7582a918
5 changed files with 55 additions and 21 deletions
|
@ -348,6 +348,7 @@ namespace ChocolArm64
|
||||||
SetA64("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg));
|
SetA64("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg));
|
||||||
SetA64("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm));
|
SetA64("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm));
|
||||||
SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", AInstEmit.Raddhn_V, typeof(AOpCodeSimdReg));
|
SetA64("0x101110<<1xxxxx010000xxxxxxxxxx", AInstEmit.Raddhn_V, typeof(AOpCodeSimdReg));
|
||||||
|
SetA64("0x10111001100000010110xxxxxxxxxx", AInstEmit.Rbit_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0x00111000100000000110xxxxxxxxxx", AInstEmit.Rev16_V, typeof(AOpCodeSimd));
|
SetA64("0x00111000100000000110xxxxxxxxxx", AInstEmit.Rev16_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0x1011100x100000000010xxxxxxxxxx", AInstEmit.Rev32_V, typeof(AOpCodeSimd));
|
SetA64("0x1011100x100000000010xxxxxxxxxx", AInstEmit.Rev32_V, typeof(AOpCodeSimd));
|
||||||
SetA64("0x001110<<100000000010xxxxxxxxxx", AInstEmit.Rev64_V, typeof(AOpCodeSimd));
|
SetA64("0x001110<<100000000010xxxxxxxxxx", AInstEmit.Rev64_V, typeof(AOpCodeSimd));
|
||||||
|
|
|
@ -151,9 +151,9 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
EmitVectorExtractZx(Context, Op.Rn, Index, 0);
|
EmitVectorExtractZx(Context, Op.Rn, Index, 0);
|
||||||
|
|
||||||
Context.Emit(OpCodes.Conv_U1);
|
Context.Emit(OpCodes.Conv_U4);
|
||||||
|
|
||||||
AVectorHelper.EmitCall(Context, nameof(AVectorHelper.CountSetBits8));
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.CountSetBits8));
|
||||||
|
|
||||||
Context.Emit(OpCodes.Conv_U8);
|
Context.Emit(OpCodes.Conv_U8);
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,9 @@ namespace ChocolArm64.Instruction
|
||||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||||
|
|
||||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
int Elems = Bytes >> Op.Size;
|
||||||
|
|
||||||
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
|
for (int Index = 0; Index < Elems; Index++)
|
||||||
{
|
{
|
||||||
EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
|
EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size);
|
||||||
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
|
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
|
||||||
|
@ -145,6 +146,31 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorImmBinaryOp(Context, () => Context.Emit(OpCodes.Or));
|
EmitVectorImmBinaryOp(Context, () => Context.Emit(OpCodes.Or));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Rbit_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
|
int Elems = Op.RegisterSize == ARegisterSize.SIMD128 ? 16 : 8;
|
||||||
|
|
||||||
|
for (int Index = 0; Index < Elems; Index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(Context, Op.Rn, Index, 0);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Conv_U4);
|
||||||
|
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.ReverseBits8));
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Conv_U8);
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Rev16_V(AILEmitterCtx Context)
|
public static void Rev16_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitRev_V(Context, ContainerSize: 1);
|
EmitRev_V(Context, ContainerSize: 1);
|
||||||
|
@ -164,18 +190,17 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
|
||||||
|
|
||||||
int Elems = Bytes >> Op.Size;
|
|
||||||
|
|
||||||
if (Op.Size >= ContainerSize)
|
if (Op.Size >= ContainerSize)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
int Elems = Bytes >> Op.Size;
|
||||||
|
|
||||||
int ContainerMask = (1 << (ContainerSize - Op.Size)) - 1;
|
int ContainerMask = (1 << (ContainerSize - Op.Size)) - 1;
|
||||||
|
|
||||||
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
|
for (int Index = 0; Index < Elems; Index++)
|
||||||
{
|
{
|
||||||
int RevIndex = Index ^ ContainerMask;
|
int RevIndex = Index ^ ContainerMask;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,14 @@ namespace ChocolArm64.Instruction
|
||||||
return (ulong)Size;
|
return (ulong)Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static uint CountSetBits8(uint Value)
|
||||||
|
{
|
||||||
|
Value = ((Value >> 1) & 0x55) + (Value & 0x55);
|
||||||
|
Value = ((Value >> 2) & 0x33) + (Value & 0x33);
|
||||||
|
|
||||||
|
return (Value >> 4) + (Value & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
private const uint Crc32RevPoly = 0xedb88320;
|
private const uint Crc32RevPoly = 0xedb88320;
|
||||||
private const uint Crc32cRevPoly = 0x82f63b78;
|
private const uint Crc32cRevPoly = 0x82f63b78;
|
||||||
|
|
||||||
|
@ -89,6 +97,14 @@ namespace ChocolArm64.Instruction
|
||||||
return Crc;
|
return Crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static uint ReverseBits8(uint Value)
|
||||||
|
{
|
||||||
|
Value = ((Value & 0xaa) >> 1) | ((Value & 0x55) << 1);
|
||||||
|
Value = ((Value & 0xcc) >> 2) | ((Value & 0x33) << 2);
|
||||||
|
|
||||||
|
return (Value >> 4) | ((Value & 0x0f) << 4);
|
||||||
|
}
|
||||||
|
|
||||||
public static uint ReverseBits32(uint Value)
|
public static uint ReverseBits32(uint Value)
|
||||||
{
|
{
|
||||||
Value = ((Value & 0xaaaaaaaa) >> 1) | ((Value & 0x55555555) << 1);
|
Value = ((Value & 0xaaaaaaaa) >> 1) | ((Value & 0x55555555) << 1);
|
||||||
|
|
|
@ -93,14 +93,6 @@ namespace ChocolArm64.Instruction
|
||||||
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
|
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int CountSetBits8(byte Value)
|
|
||||||
{
|
|
||||||
return ((Value >> 0) & 1) + ((Value >> 1) & 1) +
|
|
||||||
((Value >> 2) & 1) + ((Value >> 3) & 1) +
|
|
||||||
((Value >> 4) & 1) + ((Value >> 5) & 1) +
|
|
||||||
((Value >> 6) & 1) + (Value >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double Max(double LHS, double RHS)
|
public static double Max(double LHS, double RHS)
|
||||||
{
|
{
|
||||||
if (LHS == 0.0 && RHS == 0.0)
|
if (LHS == 0.0 && RHS == 0.0)
|
||||||
|
|
Loading…
Reference in a new issue