mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-12-23 07:45:45 +00:00
Add Flush-to-zero mode (input, output) to FP instructions (slow paths); update FP Tests. Update Naming Conventions for Tests project. (#489)
* Update SoftFloat.cs * Update SoftFallback.cs * Update InstEmitSimdShift.cs * Update InstEmitSimdCvt.cs * Update InstEmitSimdArithmetic.cs * Update CryptoHelper.cs * Update CpuTestSimd.cs * Update CpuTestSimdReg.cs * Update CpuThreadState.cs * Update OpCodeTable.cs * Add files via upload * Nit. * Remove unused using. Nit. * Remove unused using. FZ update. * Nit. * Remove unused using.
This commit is contained in:
parent
53e6664526
commit
1e7ea76f14
28 changed files with 5843 additions and 5639 deletions
|
@ -185,10 +185,10 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
int idx = columns << 2;
|
int idx = columns << 2;
|
||||||
|
|
||||||
byte row0 = inState[idx + 0]; // A, E, I, M: [Row0, Col0-Col3]
|
byte row0 = inState[idx + 0]; // A, E, I, M: [row0, col0-col3]
|
||||||
byte row1 = inState[idx + 1]; // B, F, J, N: [Row1, Col0-Col3]
|
byte row1 = inState[idx + 1]; // B, F, J, N: [row1, col0-col3]
|
||||||
byte row2 = inState[idx + 2]; // C, G, K, O: [Row2, Col0-Col3]
|
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
|
||||||
byte row3 = inState[idx + 3]; // D, H, L, P: [Row3, Col0-Col3]
|
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
|
||||||
|
|
||||||
outState[idx + 0] = (byte)((uint)_gfMul0E[row0] ^ _gfMul0B[row1] ^ _gfMul0D[row2] ^ _gfMul09[row3]);
|
outState[idx + 0] = (byte)((uint)_gfMul0E[row0] ^ _gfMul0B[row1] ^ _gfMul0D[row2] ^ _gfMul09[row3]);
|
||||||
outState[idx + 1] = (byte)((uint)_gfMul09[row0] ^ _gfMul0E[row1] ^ _gfMul0B[row2] ^ _gfMul0D[row3]);
|
outState[idx + 1] = (byte)((uint)_gfMul09[row0] ^ _gfMul0E[row1] ^ _gfMul0B[row2] ^ _gfMul0D[row3]);
|
||||||
|
@ -246,10 +246,10 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
int idx = columns << 2;
|
int idx = columns << 2;
|
||||||
|
|
||||||
byte row0 = inState[idx + 0]; // A, E, I, M: [Row0, Col0-Col3]
|
byte row0 = inState[idx + 0]; // A, E, I, M: [row0, col0-col3]
|
||||||
byte row1 = inState[idx + 1]; // B, F, J, N: [Row1, Col0-Col3]
|
byte row1 = inState[idx + 1]; // B, F, J, N: [row1, col0-col3]
|
||||||
byte row2 = inState[idx + 2]; // C, G, K, O: [Row2, Col0-Col3]
|
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
|
||||||
byte row3 = inState[idx + 3]; // D, H, L, P: [Row3, Col0-Col3]
|
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
|
||||||
|
|
||||||
outState[idx + 0] = (byte)((uint)_gfMul02[row0] ^ _gfMul03[row1] ^ row2 ^ row3);
|
outState[idx + 0] = (byte)((uint)_gfMul02[row0] ^ _gfMul03[row1] ^ row2 ^ row3);
|
||||||
outState[idx + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ row3);
|
outState[idx + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ row3);
|
||||||
|
|
|
@ -203,7 +203,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fadd_S(ILEmitterCtx context)
|
public static void Fadd_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.AddScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.AddScalar));
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fadd_V(ILEmitterCtx context)
|
public static void Fadd_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Add));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Add));
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fdiv_S(ILEmitterCtx context)
|
public static void Fdiv_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.DivideScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.DivideScalar));
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fdiv_V(ILEmitterCtx context)
|
public static void Fdiv_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Divide));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Divide));
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
EmitVectorZero32_128(context, op.Rd);
|
EmitVectorZero32_128(context, op.Rd);
|
||||||
}
|
}
|
||||||
else /* if (Op.Size == 1) */
|
else /* if (op.Size == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmax_S(ILEmitterCtx context)
|
public static void Fmax_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.MaxScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.MaxScalar));
|
||||||
}
|
}
|
||||||
|
@ -348,7 +348,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmax_V(ILEmitterCtx context)
|
public static void Fmax_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Max));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Max));
|
||||||
}
|
}
|
||||||
|
@ -388,7 +388,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmin_S(ILEmitterCtx context)
|
public static void Fmin_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.MinScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.MinScalar));
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmin_V(ILEmitterCtx context)
|
public static void Fmin_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Min));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Min));
|
||||||
}
|
}
|
||||||
|
@ -516,7 +516,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
EmitVectorZero32_128(context, op.Rd);
|
EmitVectorZero32_128(context, op.Rd);
|
||||||
}
|
}
|
||||||
else /* if (Op.Size == 1) */
|
else /* if (op.Size == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmul_S(ILEmitterCtx context)
|
public static void Fmul_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.MultiplyScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.MultiplyScalar));
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fmul_V(ILEmitterCtx context)
|
public static void Fmul_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Multiply));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Multiply));
|
||||||
}
|
}
|
||||||
|
@ -715,7 +715,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
EmitVectorZero32_128(context, op.Rd);
|
EmitVectorZero32_128(context, op.Rd);
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesSsv = new Type[] { typeof(double) };
|
Type[] typesSsv = new Type[] { typeof(double) };
|
||||||
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
@ -772,7 +772,7 @@ namespace ChocolArm64.Instructions
|
||||||
EmitVectorZeroUpper(context, op.Rd);
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesSav = new Type[] { typeof(double) };
|
Type[] typesSav = new Type[] { typeof(double) };
|
||||||
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
@ -1016,7 +1016,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
EmitVectorZero32_128(context, op.Rd);
|
EmitVectorZero32_128(context, op.Rd);
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesSsv = new Type[] { typeof(double) };
|
Type[] typesSsv = new Type[] { typeof(double) };
|
||||||
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
@ -1043,7 +1043,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
EmitScalarBinaryOpF(context, () =>
|
EmitScalarBinaryOpF(context, () =>
|
||||||
{
|
{
|
||||||
EmitSoftFloatCall(context, nameof(SoftFloat32.FprSqrtStepFused));
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,7 +1081,7 @@ namespace ChocolArm64.Instructions
|
||||||
EmitVectorZeroUpper(context, op.Rd);
|
EmitVectorZeroUpper(context, op.Rd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
Type[] typesSav = new Type[] { typeof(double) };
|
Type[] typesSav = new Type[] { typeof(double) };
|
||||||
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
|
||||||
|
@ -1106,7 +1106,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
EmitVectorBinaryOpF(context, () =>
|
EmitVectorBinaryOpF(context, () =>
|
||||||
{
|
{
|
||||||
EmitSoftFloatCall(context, nameof(SoftFloat32.FprSqrtStepFused));
|
EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1114,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fsqrt_S(ILEmitterCtx context)
|
public static void Fsqrt_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.SqrtScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.SqrtScalar));
|
||||||
}
|
}
|
||||||
|
@ -1130,7 +1130,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fsqrt_V(ILEmitterCtx context)
|
public static void Fsqrt_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Sqrt));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Sqrt));
|
||||||
}
|
}
|
||||||
|
@ -1146,7 +1146,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fsub_S(ILEmitterCtx context)
|
public static void Fsub_S(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitScalarSseOrSse2OpF(context, nameof(Sse.SubtractScalar));
|
EmitScalarSseOrSse2OpF(context, nameof(Sse.SubtractScalar));
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1162,7 @@ namespace ChocolArm64.Instructions
|
||||||
public static void Fsub_V(ILEmitterCtx context)
|
public static void Fsub_V(ILEmitterCtx context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP && Optimizations.UseSse
|
if (Optimizations.FastFP && Optimizations.UseSse
|
||||||
&& Optimizations.UseSse2)
|
&& Optimizations.UseSse2)
|
||||||
{
|
{
|
||||||
EmitVectorSseOrSse2OpF(context, nameof(Sse.Subtract));
|
EmitVectorSseOrSse2OpF(context, nameof(Sse.Subtract));
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,9 +89,9 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
context.EmitCall(typeof(SoftFloat1632), nameof(SoftFloat1632.FPConvert));
|
context.EmitCall(typeof(SoftFloat16_32), nameof(SoftFloat16_32.FPConvert));
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
EmitVectorExtractF(context, op.Rn, part + index, 0);
|
EmitVectorExtractF(context, op.Rn, part + index, 0);
|
||||||
|
|
||||||
|
@ -139,12 +139,12 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
context.EmitLdarg(TranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
context.EmitCall(typeof(SoftFloat3216), nameof(SoftFloat3216.FPConvert));
|
context.EmitCall(typeof(SoftFloat32_16), nameof(SoftFloat32_16.FPConvert));
|
||||||
|
|
||||||
context.Emit(OpCodes.Conv_U8);
|
context.Emit(OpCodes.Conv_U8);
|
||||||
EmitVectorInsertTmp(context, part + index, 1);
|
EmitVectorInsertTmp(context, part + index, 1);
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
context.Emit(OpCodes.Conv_R4);
|
context.Emit(OpCodes.Conv_R4);
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
context.Emit(OpCodes.Conv_U8);
|
context.Emit(OpCodes.Conv_U8);
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, signed
|
VectorHelper.EmitCall(context, signed
|
||||||
? nameof(VectorHelper.SatF64ToS64)
|
? nameof(VectorHelper.SatF64ToS64)
|
||||||
|
@ -516,7 +516,7 @@ namespace ChocolArm64.Instructions
|
||||||
? nameof(VectorHelper.SatF32ToS32)
|
? nameof(VectorHelper.SatF32ToS32)
|
||||||
: nameof(VectorHelper.SatF32ToU32));
|
: nameof(VectorHelper.SatF32ToU32));
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, signed
|
VectorHelper.EmitCall(context, signed
|
||||||
? nameof(VectorHelper.SatF64ToS64)
|
? nameof(VectorHelper.SatF64ToS64)
|
||||||
|
@ -565,7 +565,7 @@ namespace ChocolArm64.Instructions
|
||||||
? nameof(VectorHelper.SatF32ToS32)
|
? nameof(VectorHelper.SatF32ToS32)
|
||||||
: nameof(VectorHelper.SatF32ToU32));
|
: nameof(VectorHelper.SatF32ToU32));
|
||||||
}
|
}
|
||||||
else /* if (SizeF == 1) */
|
else /* if (sizeF == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, signed
|
VectorHelper.EmitCall(context, signed
|
||||||
? nameof(VectorHelper.SatF64ToS64)
|
? nameof(VectorHelper.SatF64ToS64)
|
||||||
|
@ -601,7 +601,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS32));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS32));
|
||||||
}
|
}
|
||||||
else /* if (Size == 1) */
|
else /* if (size == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS32));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS32));
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS64));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToS64));
|
||||||
}
|
}
|
||||||
else /* if (Size == 1) */
|
else /* if (size == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS64));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToS64));
|
||||||
}
|
}
|
||||||
|
@ -634,7 +634,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU32));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU32));
|
||||||
}
|
}
|
||||||
else /* if (Size == 1) */
|
else /* if (size == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU32));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU32));
|
||||||
}
|
}
|
||||||
|
@ -645,7 +645,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU64));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF32ToU64));
|
||||||
}
|
}
|
||||||
else /* if (Size == 1) */
|
else /* if (size == 1) */
|
||||||
{
|
{
|
||||||
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU64));
|
VectorHelper.EmitCall(context, nameof(VectorHelper.SatF64ToU64));
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace ChocolArm64.Instructions
|
||||||
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0
|
if (Optimizations.UseSse2 && op.Size > 0
|
||||||
&& op.Size < 3)
|
&& op.Size < 3)
|
||||||
{
|
{
|
||||||
Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
||||||
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
||||||
|
@ -209,7 +209,7 @@ namespace ChocolArm64.Instructions
|
||||||
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0
|
if (Optimizations.UseSse2 && op.Size > 0
|
||||||
&& op.Size < 3)
|
&& op.Size < 3)
|
||||||
{
|
{
|
||||||
Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
Type[] typesShs = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
||||||
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
||||||
|
@ -272,7 +272,7 @@ namespace ChocolArm64.Instructions
|
||||||
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0
|
if (Optimizations.UseSse2 && op.Size > 0
|
||||||
&& op.Size < 3)
|
&& op.Size < 3)
|
||||||
{
|
{
|
||||||
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ namespace ChocolArm64.Instructions
|
||||||
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
OpCodeSimdShImm64 op = (OpCodeSimdShImm64)context.CurrOp;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && op.Size > 0
|
if (Optimizations.UseSse2 && op.Size > 0
|
||||||
&& op.Size < 3)
|
&& op.Size < 3)
|
||||||
{
|
{
|
||||||
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
|
||||||
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
|
||||||
|
@ -658,9 +658,9 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
context.Emit(signed ? OpCodes.Shr : OpCodes.Shr_Un);
|
context.Emit(signed ? OpCodes.Shr : OpCodes.Shr_Un);
|
||||||
}
|
}
|
||||||
else /* if (Op.Size == 3) */
|
else /* if (op.Size == 3) */
|
||||||
{
|
{
|
||||||
EmitShrImm_64(context, signed, round ? roundConst : 0L, shift);
|
EmitShrImm64(context, signed, round ? roundConst : 0L, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accumulate)
|
if (accumulate)
|
||||||
|
@ -795,9 +795,9 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
context.Emit(signedSrc ? OpCodes.Shr : OpCodes.Shr_Un);
|
context.Emit(signedSrc ? OpCodes.Shr : OpCodes.Shr_Un);
|
||||||
}
|
}
|
||||||
else /* if (Op.Size == 2 && Round) */
|
else /* if (op.Size == 2 && round) */
|
||||||
{
|
{
|
||||||
EmitShrImm_64(context, signedSrc, roundConst, shift); // Shift <= 32
|
EmitShrImm64(context, signedSrc, roundConst, shift); // shift <= 32
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitSatQ(context, op.Size, signedSrc, signedDst);
|
EmitSatQ(context, op.Size, signedSrc, signedDst);
|
||||||
|
@ -814,8 +814,8 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dst_64 = (Int(Src_64, Signed) + RoundConst) >> Shift;
|
// dst64 = (Int(src64, signed) + roundConst) >> shift;
|
||||||
private static void EmitShrImm_64(
|
private static void EmitShrImm64(
|
||||||
ILEmitterCtx context,
|
ILEmitterCtx context,
|
||||||
bool signed,
|
bool signed,
|
||||||
long roundConst,
|
long roundConst,
|
||||||
|
@ -825,8 +825,8 @@ namespace ChocolArm64.Instructions
|
||||||
context.EmitLdc_I4(shift);
|
context.EmitLdc_I4(shift);
|
||||||
|
|
||||||
SoftFallback.EmitCall(context, signed
|
SoftFallback.EmitCall(context, signed
|
||||||
? nameof(SoftFallback.SignedShrImm_64)
|
? nameof(SoftFallback.SignedShrImm64)
|
||||||
: nameof(SoftFallback.UnsignedShrImm_64));
|
: nameof(SoftFallback.UnsignedShrImm64));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EmitVectorShImmWidenBinarySx(ILEmitterCtx context, Action emit, int imm)
|
private static void EmitVectorShImmWidenBinarySx(ILEmitterCtx context, Action emit, int imm)
|
||||||
|
|
|
@ -16,8 +16,8 @@ namespace ChocolArm64.Instructions
|
||||||
context.EmitCall(typeof(SoftFallback), mthdName);
|
context.EmitCall(typeof(SoftFallback), mthdName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region "ShrImm_64"
|
#region "ShrImm64"
|
||||||
public static long SignedShrImm_64(long value, long roundConst, int shift)
|
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||||
{
|
{
|
||||||
if (roundConst == 0L)
|
if (roundConst == 0L)
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
return value >> shift;
|
return value >> shift;
|
||||||
}
|
}
|
||||||
else /* if (Shift == 64) */
|
else /* if (shift == 64) */
|
||||||
{
|
{
|
||||||
if (value < 0L)
|
if (value < 0L)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (RoundConst == 1L << (Shift - 1)) */
|
else /* if (roundConst == 1L << (shift - 1)) */
|
||||||
{
|
{
|
||||||
if (shift <= 63)
|
if (shift <= 63)
|
||||||
{
|
{
|
||||||
|
@ -52,14 +52,14 @@ namespace ChocolArm64.Instructions
|
||||||
return add >> shift;
|
return add >> shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (Shift == 64) */
|
else /* if (shift == 64) */
|
||||||
{
|
{
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong UnsignedShrImm_64(ulong value, long roundConst, int shift)
|
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
|
||||||
{
|
{
|
||||||
if (roundConst == 0L)
|
if (roundConst == 0L)
|
||||||
{
|
{
|
||||||
|
@ -67,12 +67,12 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
return value >> shift;
|
return value >> shift;
|
||||||
}
|
}
|
||||||
else /* if (Shift == 64) */
|
else /* if (shift == 64) */
|
||||||
{
|
{
|
||||||
return 0UL;
|
return 0UL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (RoundConst == 1L << (Shift - 1)) */
|
else /* if (roundConst == 1L << (shift - 1)) */
|
||||||
{
|
{
|
||||||
ulong add = value + (ulong)roundConst;
|
ulong add = value + (ulong)roundConst;
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
|
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
|
||||||
}
|
}
|
||||||
else /* if (Shift == 64) */
|
else /* if (shift == 64) */
|
||||||
{
|
{
|
||||||
return 1UL;
|
return 1UL;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
return add >> shift;
|
return add >> shift;
|
||||||
}
|
}
|
||||||
else /* if (Shift == 64) */
|
else /* if (shift == 64) */
|
||||||
{
|
{
|
||||||
return 0UL;
|
return 0UL;
|
||||||
}
|
}
|
||||||
|
@ -285,8 +285,8 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
if (op1 <= (ulong)long.MaxValue)
|
if (op1 <= (ulong)long.MaxValue)
|
||||||
{
|
{
|
||||||
// Op1 from ulong.MinValue to (ulong)long.MaxValue
|
// op1 from ulong.MinValue to (ulong)long.MaxValue
|
||||||
// Op2 from long.MinValue to long.MaxValue
|
// op2 from long.MinValue to long.MaxValue
|
||||||
|
|
||||||
long add = (long)op1 + op2;
|
long add = (long)op1 + op2;
|
||||||
|
|
||||||
|
@ -303,8 +303,8 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
else if (op2 >= 0L)
|
else if (op2 >= 0L)
|
||||||
{
|
{
|
||||||
// Op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||||
// Op2 from (long)ulong.MinValue to long.MaxValue
|
// op2 from (long)ulong.MinValue to long.MaxValue
|
||||||
|
|
||||||
state.SetFpsrFlag(Fpsr.Qc);
|
state.SetFpsrFlag(Fpsr.Qc);
|
||||||
|
|
||||||
|
@ -312,8 +312,8 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||||
// Op2 from long.MinValue to (long)ulong.MinValue - 1L
|
// op2 from long.MinValue to (long)ulong.MinValue - 1L
|
||||||
|
|
||||||
ulong add = op1 + (ulong)op2;
|
ulong add = op1 + (ulong)op2;
|
||||||
|
|
||||||
|
@ -334,8 +334,8 @@ namespace ChocolArm64.Instructions
|
||||||
{
|
{
|
||||||
if (op1 >= 0L)
|
if (op1 >= 0L)
|
||||||
{
|
{
|
||||||
// Op1 from (long)ulong.MinValue to long.MaxValue
|
// op1 from (long)ulong.MinValue to long.MaxValue
|
||||||
// Op2 from ulong.MinValue to ulong.MaxValue
|
// op2 from ulong.MinValue to ulong.MaxValue
|
||||||
|
|
||||||
ulong add = (ulong)op1 + op2;
|
ulong add = (ulong)op1 + op2;
|
||||||
|
|
||||||
|
@ -352,15 +352,15 @@ namespace ChocolArm64.Instructions
|
||||||
}
|
}
|
||||||
else if (op2 > (ulong)long.MaxValue)
|
else if (op2 > (ulong)long.MaxValue)
|
||||||
{
|
{
|
||||||
// Op1 from long.MinValue to (long)ulong.MinValue - 1L
|
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
||||||
// Op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
// op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
||||||
|
|
||||||
return (ulong)op1 + op2;
|
return (ulong)op1 + op2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Op1 from long.MinValue to (long)ulong.MinValue - 1L
|
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
||||||
// Op2 from ulong.MinValue to (ulong)long.MaxValue
|
// op2 from ulong.MinValue to (ulong)long.MaxValue
|
||||||
|
|
||||||
long add = op1 + (long)op2;
|
long add = op1 + (long)op2;
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ namespace ChocolArm64.Instructions
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Count"
|
#region "Count"
|
||||||
public static ulong CountLeadingSigns(ulong value, int size) // Size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
{
|
{
|
||||||
value ^= value >> 1;
|
value ^= value >> 1;
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
private static readonly byte[] ClzNibbleTbl = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
public static ulong CountLeadingZeros(ulong value, int size) // Size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
public static ulong CountLeadingZeros(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||||
{
|
{
|
||||||
if (value == 0ul)
|
if (value == 0ul)
|
||||||
{
|
{
|
||||||
|
@ -419,7 +419,7 @@ namespace ChocolArm64.Instructions
|
||||||
return (ulong)count;
|
return (ulong)count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong CountSetBits8(ulong value) // "Size" is 8 (SIMD&FP Inst.).
|
public static ulong CountSetBits8(ulong value) // "size" is 8 (SIMD&FP Inst.).
|
||||||
{
|
{
|
||||||
if (value == 0xfful)
|
if (value == 0xfful)
|
||||||
{
|
{
|
||||||
|
@ -531,72 +531,72 @@ namespace ChocolArm64.Instructions
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Sha1"
|
#region "Sha1"
|
||||||
public static Vector128<float> HashChoose(Vector128<float> hashAbcd, uint hashE, Vector128<float> wk)
|
public static Vector128<float> HashChoose(Vector128<float> hash_abcd, uint hash_e, Vector128<float> wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
{
|
{
|
||||||
uint t = ShaChoose((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2),
|
uint t = ShaChoose((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)2, 2),
|
(uint)VectorExtractIntZx(hash_abcd, (byte)2, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)3, 2));
|
(uint)VectorExtractIntZx(hash_abcd, (byte)3, 2));
|
||||||
|
|
||||||
hashE += Rol((uint)VectorExtractIntZx(hashAbcd, (byte)0, 2), 5) + t;
|
hash_e += Rol((uint)VectorExtractIntZx(hash_abcd, (byte)0, 2), 5) + t;
|
||||||
hashE += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
hash_e += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
||||||
|
|
||||||
t = Rol((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2), 30);
|
t = Rol((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2), 30);
|
||||||
hashAbcd = VectorInsertInt((ulong)t, hashAbcd, (byte)1, 2);
|
hash_abcd = VectorInsertInt((ulong)t, hash_abcd, (byte)1, 2);
|
||||||
|
|
||||||
Rol32_160(ref hashE, ref hashAbcd);
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashAbcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint FixedRotate(uint hashE)
|
public static uint FixedRotate(uint hash_e)
|
||||||
{
|
{
|
||||||
return hashE.Rol(30);
|
return hash_e.Rol(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> HashMajority(Vector128<float> hashAbcd, uint hashE, Vector128<float> wk)
|
public static Vector128<float> HashMajority(Vector128<float> hash_abcd, uint hash_e, Vector128<float> wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
{
|
{
|
||||||
uint t = ShaMajority((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2),
|
uint t = ShaMajority((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)2, 2),
|
(uint)VectorExtractIntZx(hash_abcd, (byte)2, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)3, 2));
|
(uint)VectorExtractIntZx(hash_abcd, (byte)3, 2));
|
||||||
|
|
||||||
hashE += Rol((uint)VectorExtractIntZx(hashAbcd, (byte)0, 2), 5) + t;
|
hash_e += Rol((uint)VectorExtractIntZx(hash_abcd, (byte)0, 2), 5) + t;
|
||||||
hashE += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
hash_e += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
||||||
|
|
||||||
t = Rol((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2), 30);
|
t = Rol((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2), 30);
|
||||||
hashAbcd = VectorInsertInt((ulong)t, hashAbcd, (byte)1, 2);
|
hash_abcd = VectorInsertInt((ulong)t, hash_abcd, (byte)1, 2);
|
||||||
|
|
||||||
Rol32_160(ref hashE, ref hashAbcd);
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashAbcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> HashParity(Vector128<float> hashAbcd, uint hashE, Vector128<float> wk)
|
public static Vector128<float> HashParity(Vector128<float> hash_abcd, uint hash_e, Vector128<float> wk)
|
||||||
{
|
{
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
{
|
{
|
||||||
uint t = ShaParity((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2),
|
uint t = ShaParity((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)2, 2),
|
(uint)VectorExtractIntZx(hash_abcd, (byte)2, 2),
|
||||||
(uint)VectorExtractIntZx(hashAbcd, (byte)3, 2));
|
(uint)VectorExtractIntZx(hash_abcd, (byte)3, 2));
|
||||||
|
|
||||||
hashE += Rol((uint)VectorExtractIntZx(hashAbcd, (byte)0, 2), 5) + t;
|
hash_e += Rol((uint)VectorExtractIntZx(hash_abcd, (byte)0, 2), 5) + t;
|
||||||
hashE += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
hash_e += (uint)VectorExtractIntZx(wk, (byte)e, 2);
|
||||||
|
|
||||||
t = Rol((uint)VectorExtractIntZx(hashAbcd, (byte)1, 2), 30);
|
t = Rol((uint)VectorExtractIntZx(hash_abcd, (byte)1, 2), 30);
|
||||||
hashAbcd = VectorInsertInt((ulong)t, hashAbcd, (byte)1, 2);
|
hash_abcd = VectorInsertInt((ulong)t, hash_abcd, (byte)1, 2);
|
||||||
|
|
||||||
Rol32_160(ref hashE, ref hashAbcd);
|
Rol32_160(ref hash_e, ref hash_abcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hashAbcd;
|
return hash_abcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> Sha1SchedulePart1(Vector128<float> w03, Vector128<float> w47, Vector128<float> w811)
|
public static Vector128<float> Sha1SchedulePart1(Vector128<float> w0_3, Vector128<float> w4_7, Vector128<float> w8_11)
|
||||||
{
|
{
|
||||||
if (!Sse.IsSupported)
|
if (!Sse.IsSupported)
|
||||||
{
|
{
|
||||||
|
@ -605,16 +605,16 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
Vector128<float> result = new Vector128<float>();
|
Vector128<float> result = new Vector128<float>();
|
||||||
|
|
||||||
ulong t2 = VectorExtractIntZx(w47, (byte)0, 3);
|
ulong t2 = VectorExtractIntZx(w4_7, (byte)0, 3);
|
||||||
ulong t1 = VectorExtractIntZx(w03, (byte)1, 3);
|
ulong t1 = VectorExtractIntZx(w0_3, (byte)1, 3);
|
||||||
|
|
||||||
result = VectorInsertInt((ulong)t1, result, (byte)0, 3);
|
result = VectorInsertInt((ulong)t1, result, (byte)0, 3);
|
||||||
result = VectorInsertInt((ulong)t2, result, (byte)1, 3);
|
result = VectorInsertInt((ulong)t2, result, (byte)1, 3);
|
||||||
|
|
||||||
return Sse.Xor(result, Sse.Xor(w03, w811));
|
return Sse.Xor(result, Sse.Xor(w0_3, w8_11));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> Sha1SchedulePart2(Vector128<float> tw03, Vector128<float> w1215)
|
public static Vector128<float> Sha1SchedulePart2(Vector128<float> tw0_3, Vector128<float> w12_15)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
|
@ -623,8 +623,8 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
Vector128<float> result = new Vector128<float>();
|
Vector128<float> result = new Vector128<float>();
|
||||||
|
|
||||||
Vector128<float> t = Sse.Xor(tw03, Sse.StaticCast<uint, float>(
|
Vector128<float> t = Sse.Xor(tw0_3, Sse.StaticCast<uint, float>(
|
||||||
Sse2.ShiftRightLogical128BitLane(Sse.StaticCast<float, uint>(w1215), (byte)4)));
|
Sse2.ShiftRightLogical128BitLane(Sse.StaticCast<float, uint>(w12_15), (byte)4)));
|
||||||
|
|
||||||
uint tE0 = (uint)VectorExtractIntZx(t, (byte)0, 2);
|
uint tE0 = (uint)VectorExtractIntZx(t, (byte)0, 2);
|
||||||
uint tE1 = (uint)VectorExtractIntZx(t, (byte)1, 2);
|
uint tE1 = (uint)VectorExtractIntZx(t, (byte)1, 2);
|
||||||
|
@ -676,28 +676,28 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
#region "Sha256"
|
#region "Sha256"
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector128<float> HashLower(Vector128<float> hashAbcd, Vector128<float> hashEfgh, Vector128<float> wk)
|
public static Vector128<float> HashLower(Vector128<float> hash_abcd, Vector128<float> hash_efgh, Vector128<float> wk)
|
||||||
{
|
{
|
||||||
return Sha256Hash(hashAbcd, hashEfgh, wk, true);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Vector128<float> HashUpper(Vector128<float> hashEfgh, Vector128<float> hashAbcd, Vector128<float> wk)
|
public static Vector128<float> HashUpper(Vector128<float> hash_efgh, Vector128<float> hash_abcd, Vector128<float> wk)
|
||||||
{
|
{
|
||||||
return Sha256Hash(hashAbcd, hashEfgh, wk, false);
|
return Sha256Hash(hash_abcd, hash_efgh, wk, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> Sha256SchedulePart1(Vector128<float> w03, Vector128<float> w47)
|
public static Vector128<float> Sha256SchedulePart1(Vector128<float> w0_3, Vector128<float> w4_7)
|
||||||
{
|
{
|
||||||
Vector128<float> result = new Vector128<float>();
|
Vector128<float> result = new Vector128<float>();
|
||||||
|
|
||||||
for (int e = 0; e <= 3; e++)
|
for (int e = 0; e <= 3; e++)
|
||||||
{
|
{
|
||||||
uint elt = (uint)VectorExtractIntZx(e <= 2 ? w03 : w47, (byte)(e <= 2 ? e + 1 : 0), 2);
|
uint elt = (uint)VectorExtractIntZx(e <= 2 ? w0_3 : w4_7, (byte)(e <= 2 ? e + 1 : 0), 2);
|
||||||
|
|
||||||
elt = elt.Ror(7) ^ elt.Ror(18) ^ elt.Lsr(3);
|
elt = elt.Ror(7) ^ elt.Ror(18) ^ elt.Lsr(3);
|
||||||
|
|
||||||
elt += (uint)VectorExtractIntZx(w03, (byte)e, 2);
|
elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
|
||||||
|
|
||||||
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
||||||
}
|
}
|
||||||
|
@ -705,11 +705,11 @@ namespace ChocolArm64.Instructions
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector128<float> Sha256SchedulePart2(Vector128<float> w03, Vector128<float> w811, Vector128<float> w1215)
|
public static Vector128<float> Sha256SchedulePart2(Vector128<float> w0_3, Vector128<float> w8_11, Vector128<float> w12_15)
|
||||||
{
|
{
|
||||||
Vector128<float> result = new Vector128<float>();
|
Vector128<float> result = new Vector128<float>();
|
||||||
|
|
||||||
ulong t1 = VectorExtractIntZx(w1215, (byte)1, 3);
|
ulong t1 = VectorExtractIntZx(w12_15, (byte)1, 3);
|
||||||
|
|
||||||
for (int e = 0; e <= 1; e++)
|
for (int e = 0; e <= 1; e++)
|
||||||
{
|
{
|
||||||
|
@ -717,8 +717,8 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
||||||
|
|
||||||
elt += (uint)VectorExtractIntZx(w03, (byte)e, 2);
|
elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
|
||||||
elt += (uint)VectorExtractIntZx(w811, (byte)(e + 1), 2);
|
elt += (uint)VectorExtractIntZx(w8_11, (byte)(e + 1), 2);
|
||||||
|
|
||||||
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
||||||
}
|
}
|
||||||
|
@ -731,8 +731,8 @@ namespace ChocolArm64.Instructions
|
||||||
|
|
||||||
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
elt = elt.Ror(17) ^ elt.Ror(19) ^ elt.Lsr(10);
|
||||||
|
|
||||||
elt += (uint)VectorExtractIntZx(w03, (byte)e, 2);
|
elt += (uint)VectorExtractIntZx(w0_3, (byte)e, 2);
|
||||||
elt += (uint)VectorExtractIntZx(e == 2 ? w811 : w1215, (byte)(e == 2 ? 3 : 0), 2);
|
elt += (uint)VectorExtractIntZx(e == 2 ? w8_11 : w12_15, (byte)(e == 2 ? 3 : 0), 2);
|
||||||
|
|
||||||
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
result = VectorInsertInt((ulong)elt, result, (byte)e, 2);
|
||||||
}
|
}
|
||||||
|
@ -904,13 +904,13 @@ namespace ChocolArm64.Instructions
|
||||||
public static ulong UMulHi128(ulong left, ulong right)
|
public static ulong UMulHi128(ulong left, ulong right)
|
||||||
{
|
{
|
||||||
ulong lHigh = left >> 32;
|
ulong lHigh = left >> 32;
|
||||||
ulong lLow = left & 0xFFFFFFFF;
|
ulong lLow = left & 0xFFFFFFFF;
|
||||||
ulong rHigh = right >> 32;
|
ulong rHigh = right >> 32;
|
||||||
ulong rLow = right & 0xFFFFFFFF;
|
ulong rLow = right & 0xFFFFFFFF;
|
||||||
|
|
||||||
ulong z2 = lLow * rLow;
|
ulong z2 = lLow * rLow;
|
||||||
ulong t = lHigh * rLow + (z2 >> 32);
|
ulong t = lHigh * rLow + (z2 >> 32);
|
||||||
ulong z1 = t & 0xFFFFFFFF;
|
ulong z1 = t & 0xFFFFFFFF;
|
||||||
ulong z0 = t >> 32;
|
ulong z0 = t >> 32;
|
||||||
|
|
||||||
z1 += lLow * rHigh;
|
z1 += lLow * rHigh;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -544,7 +544,7 @@ namespace ChocolArm64
|
||||||
|
|
||||||
foreach (var inst in _allInstA64)
|
foreach (var inst in _allInstA64)
|
||||||
{
|
{
|
||||||
int mask = ToFastLookupIndex(inst.Mask);
|
int mask = ToFastLookupIndex(inst.Mask);
|
||||||
int value = ToFastLookupIndex(inst.Value);
|
int value = ToFastLookupIndex(inst.Value);
|
||||||
|
|
||||||
for (int i = 0; i < _fastLookupSize; i++)
|
for (int i = 0; i < _fastLookupSize; i++)
|
||||||
|
@ -665,8 +665,8 @@ namespace ChocolArm64
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InsertInst(
|
private static void InsertInst(
|
||||||
int xMask,
|
int xMask,
|
||||||
int value,
|
int value,
|
||||||
Inst inst,
|
Inst inst,
|
||||||
ExecutionMode mode)
|
ExecutionMode mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace ChocolArm64.State
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<EventArgs> Interrupt;
|
public event EventHandler<EventArgs> Interrupt;
|
||||||
public event EventHandler<InstExceptionEventArgs> Break;
|
public event EventHandler<InstExceptionEventArgs> Break;
|
||||||
public event EventHandler<InstExceptionEventArgs> SvcCall;
|
public event EventHandler<InstExceptionEventArgs> SvcCall;
|
||||||
public event EventHandler<InstUndefinedEventArgs> Undefined;
|
public event EventHandler<InstUndefinedEventArgs> Undefined;
|
||||||
|
|
|
@ -18,23 +18,23 @@ namespace Ryujinx.Tests.Cpu
|
||||||
public class CpuTest
|
public class CpuTest
|
||||||
{
|
{
|
||||||
protected long Position { get; private set; }
|
protected long Position { get; private set; }
|
||||||
private long Size;
|
private long _size;
|
||||||
|
|
||||||
private long EntryPoint;
|
private long _entryPoint;
|
||||||
|
|
||||||
private IntPtr RamPointer;
|
private IntPtr _ramPointer;
|
||||||
|
|
||||||
private MemoryManager Memory;
|
private MemoryManager _memory;
|
||||||
private CpuThread Thread;
|
private CpuThread _thread;
|
||||||
|
|
||||||
private static bool UnicornAvailable;
|
private static bool _unicornAvailable;
|
||||||
private UnicornAArch64 UnicornEmu;
|
private UnicornAArch64 _unicornEmu;
|
||||||
|
|
||||||
static CpuTest()
|
static CpuTest()
|
||||||
{
|
{
|
||||||
UnicornAvailable = UnicornAArch64.IsAvailable();
|
_unicornAvailable = UnicornAArch64.IsAvailable();
|
||||||
|
|
||||||
if (!UnicornAvailable)
|
if (!_unicornAvailable)
|
||||||
{
|
{
|
||||||
Console.WriteLine("WARNING: Could not find Unicorn.");
|
Console.WriteLine("WARNING: Could not find Unicorn.");
|
||||||
}
|
}
|
||||||
|
@ -44,31 +44,31 @@ namespace Ryujinx.Tests.Cpu
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
Position = 0x1000;
|
Position = 0x1000;
|
||||||
Size = 0x1000;
|
_size = 0x1000;
|
||||||
|
|
||||||
EntryPoint = Position;
|
_entryPoint = Position;
|
||||||
|
|
||||||
Translator Translator = new Translator();
|
Translator translator = new Translator();
|
||||||
RamPointer = Marshal.AllocHGlobal(new IntPtr(Size));
|
_ramPointer = Marshal.AllocHGlobal(new IntPtr(_size));
|
||||||
Memory = new MemoryManager(RamPointer);
|
_memory = new MemoryManager(_ramPointer);
|
||||||
Memory.Map(Position, 0, Size);
|
_memory.Map(Position, 0, _size);
|
||||||
Thread = new CpuThread(Translator, Memory, EntryPoint);
|
_thread = new CpuThread(translator, _memory, _entryPoint);
|
||||||
|
|
||||||
if (UnicornAvailable)
|
if (_unicornAvailable)
|
||||||
{
|
{
|
||||||
UnicornEmu = new UnicornAArch64();
|
_unicornEmu = new UnicornAArch64();
|
||||||
UnicornEmu.MemoryMap((ulong)Position, (ulong)Size, MemoryPermission.READ | MemoryPermission.EXEC);
|
_unicornEmu.MemoryMap((ulong)Position, (ulong)_size, MemoryPermission.READ | MemoryPermission.EXEC);
|
||||||
UnicornEmu.PC = (ulong)EntryPoint;
|
_unicornEmu.PC = (ulong)_entryPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TearDown]
|
[TearDown]
|
||||||
public void Teardown()
|
public void Teardown()
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(RamPointer);
|
Marshal.FreeHGlobal(_ramPointer);
|
||||||
Memory = null;
|
_memory = null;
|
||||||
Thread = null;
|
_thread = null;
|
||||||
UnicornEmu = null;
|
_unicornEmu = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Reset()
|
protected void Reset()
|
||||||
|
@ -77,102 +77,102 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Setup();
|
Setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Opcode(uint Opcode)
|
protected void Opcode(uint opcode)
|
||||||
{
|
{
|
||||||
Thread.Memory.WriteUInt32(Position, Opcode);
|
_thread.Memory.WriteUInt32(Position, opcode);
|
||||||
|
|
||||||
if (UnicornAvailable)
|
if (_unicornAvailable)
|
||||||
{
|
{
|
||||||
UnicornEmu.MemoryWrite32((ulong)Position, Opcode);
|
_unicornEmu.MemoryWrite32((ulong)Position, opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Position += 4;
|
Position += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetThreadState(ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
|
protected void SetThreadState(ulong x0 = 0, ulong x1 = 0, ulong x2 = 0, ulong x3 = 0, ulong x31 = 0,
|
||||||
Vector128<float> V0 = default(Vector128<float>),
|
Vector128<float> v0 = default(Vector128<float>),
|
||||||
Vector128<float> V1 = default(Vector128<float>),
|
Vector128<float> v1 = default(Vector128<float>),
|
||||||
Vector128<float> V2 = default(Vector128<float>),
|
Vector128<float> v2 = default(Vector128<float>),
|
||||||
Vector128<float> V3 = default(Vector128<float>),
|
Vector128<float> v3 = default(Vector128<float>),
|
||||||
bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false,
|
bool overflow = false, bool carry = false, bool zero = false, bool negative = false,
|
||||||
int Fpcr = 0x0, int Fpsr = 0x0)
|
int fpcr = 0x0, int fpsr = 0x0)
|
||||||
{
|
{
|
||||||
Thread.ThreadState.X0 = X0;
|
_thread.ThreadState.X0 = x0;
|
||||||
Thread.ThreadState.X1 = X1;
|
_thread.ThreadState.X1 = x1;
|
||||||
Thread.ThreadState.X2 = X2;
|
_thread.ThreadState.X2 = x2;
|
||||||
Thread.ThreadState.X3 = X3;
|
_thread.ThreadState.X3 = x3;
|
||||||
|
|
||||||
Thread.ThreadState.X31 = X31;
|
_thread.ThreadState.X31 = x31;
|
||||||
|
|
||||||
Thread.ThreadState.V0 = V0;
|
_thread.ThreadState.V0 = v0;
|
||||||
Thread.ThreadState.V1 = V1;
|
_thread.ThreadState.V1 = v1;
|
||||||
Thread.ThreadState.V2 = V2;
|
_thread.ThreadState.V2 = v2;
|
||||||
Thread.ThreadState.V3 = V3;
|
_thread.ThreadState.V3 = v3;
|
||||||
|
|
||||||
Thread.ThreadState.Overflow = Overflow;
|
_thread.ThreadState.Overflow = overflow;
|
||||||
Thread.ThreadState.Carry = Carry;
|
_thread.ThreadState.Carry = carry;
|
||||||
Thread.ThreadState.Zero = Zero;
|
_thread.ThreadState.Zero = zero;
|
||||||
Thread.ThreadState.Negative = Negative;
|
_thread.ThreadState.Negative = negative;
|
||||||
|
|
||||||
Thread.ThreadState.Fpcr = Fpcr;
|
_thread.ThreadState.Fpcr = fpcr;
|
||||||
Thread.ThreadState.Fpsr = Fpsr;
|
_thread.ThreadState.Fpsr = fpsr;
|
||||||
|
|
||||||
if (UnicornAvailable)
|
if (_unicornAvailable)
|
||||||
{
|
{
|
||||||
UnicornEmu.X[0] = X0;
|
_unicornEmu.X[0] = x0;
|
||||||
UnicornEmu.X[1] = X1;
|
_unicornEmu.X[1] = x1;
|
||||||
UnicornEmu.X[2] = X2;
|
_unicornEmu.X[2] = x2;
|
||||||
UnicornEmu.X[3] = X3;
|
_unicornEmu.X[3] = x3;
|
||||||
|
|
||||||
UnicornEmu.SP = X31;
|
_unicornEmu.SP = x31;
|
||||||
|
|
||||||
UnicornEmu.Q[0] = V0;
|
_unicornEmu.Q[0] = v0;
|
||||||
UnicornEmu.Q[1] = V1;
|
_unicornEmu.Q[1] = v1;
|
||||||
UnicornEmu.Q[2] = V2;
|
_unicornEmu.Q[2] = v2;
|
||||||
UnicornEmu.Q[3] = V3;
|
_unicornEmu.Q[3] = v3;
|
||||||
|
|
||||||
UnicornEmu.OverflowFlag = Overflow;
|
_unicornEmu.OverflowFlag = overflow;
|
||||||
UnicornEmu.CarryFlag = Carry;
|
_unicornEmu.CarryFlag = carry;
|
||||||
UnicornEmu.ZeroFlag = Zero;
|
_unicornEmu.ZeroFlag = zero;
|
||||||
UnicornEmu.NegativeFlag = Negative;
|
_unicornEmu.NegativeFlag = negative;
|
||||||
|
|
||||||
UnicornEmu.Fpcr = Fpcr;
|
_unicornEmu.Fpcr = fpcr;
|
||||||
UnicornEmu.Fpsr = Fpsr;
|
_unicornEmu.Fpsr = fpsr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ExecuteOpcodes()
|
protected void ExecuteOpcodes()
|
||||||
{
|
{
|
||||||
using (ManualResetEvent Wait = new ManualResetEvent(false))
|
using (ManualResetEvent wait = new ManualResetEvent(false))
|
||||||
{
|
{
|
||||||
Thread.ThreadState.Break += (sender, e) => Thread.StopExecution();
|
_thread.ThreadState.Break += (sender, e) => _thread.StopExecution();
|
||||||
Thread.WorkFinished += (sender, e) => Wait.Set();
|
_thread.WorkFinished += (sender, e) => wait.Set();
|
||||||
|
|
||||||
Thread.Execute();
|
_thread.Execute();
|
||||||
Wait.WaitOne();
|
wait.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnicornAvailable)
|
if (_unicornAvailable)
|
||||||
{
|
{
|
||||||
UnicornEmu.RunForCount((ulong)(Position - EntryPoint - 8) / 4);
|
_unicornEmu.RunForCount((ulong)(Position - _entryPoint - 8) / 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CpuThreadState GetThreadState() => Thread.ThreadState;
|
protected CpuThreadState GetThreadState() => _thread.ThreadState;
|
||||||
|
|
||||||
protected CpuThreadState SingleOpcode(uint Opcode,
|
protected CpuThreadState SingleOpcode(uint opcode,
|
||||||
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X3 = 0, ulong X31 = 0,
|
ulong x0 = 0, ulong x1 = 0, ulong x2 = 0, ulong x3 = 0, ulong x31 = 0,
|
||||||
Vector128<float> V0 = default(Vector128<float>),
|
Vector128<float> v0 = default(Vector128<float>),
|
||||||
Vector128<float> V1 = default(Vector128<float>),
|
Vector128<float> v1 = default(Vector128<float>),
|
||||||
Vector128<float> V2 = default(Vector128<float>),
|
Vector128<float> v2 = default(Vector128<float>),
|
||||||
Vector128<float> V3 = default(Vector128<float>),
|
Vector128<float> v3 = default(Vector128<float>),
|
||||||
bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false,
|
bool overflow = false, bool carry = false, bool zero = false, bool negative = false,
|
||||||
int Fpcr = 0x0, int Fpsr = 0x0)
|
int fpcr = 0x0, int fpsr = 0x0)
|
||||||
{
|
{
|
||||||
this.Opcode(Opcode);
|
Opcode(opcode);
|
||||||
this.Opcode(0xD4200000); // BRK #0
|
Opcode(0xD4200000); // BRK #0
|
||||||
this.Opcode(0xD65F03C0); // RET
|
Opcode(0xD65F03C0); // RET
|
||||||
SetThreadState(X0, X1, X2, X3, X31, V0, V1, V2, V3, Overflow, Carry, Zero, Negative, Fpcr, Fpsr);
|
SetThreadState(x0, x1, x2, x3, x31, v0, v1, v2, v3, overflow, carry, zero, negative, fpcr, fpsr);
|
||||||
ExecuteOpcodes();
|
ExecuteOpcodes();
|
||||||
|
|
||||||
return GetThreadState();
|
return GetThreadState();
|
||||||
|
@ -181,57 +181,57 @@ namespace Ryujinx.Tests.Cpu
|
||||||
/// <summary>Rounding Mode control field.</summary>
|
/// <summary>Rounding Mode control field.</summary>
|
||||||
public enum RMode
|
public enum RMode
|
||||||
{
|
{
|
||||||
/// <summary>Round to Nearest (RN) mode.</summary>
|
/// <summary>Round to Nearest mode.</summary>
|
||||||
RN,
|
Rn,
|
||||||
/// <summary>Round towards Plus Infinity (RP) mode.</summary>
|
/// <summary>Round towards Plus Infinity mode.</summary>
|
||||||
RP,
|
Rp,
|
||||||
/// <summary>Round towards Minus Infinity (RM) mode.</summary>
|
/// <summary>Round towards Minus Infinity mode.</summary>
|
||||||
RM,
|
Rm,
|
||||||
/// <summary>Round towards Zero (RZ) mode.</summary>
|
/// <summary>Round towards Zero mode.</summary>
|
||||||
RZ
|
Rz
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>Floating-point Control Register.</summary>
|
/// <summary>Floating-point Control Register.</summary>
|
||||||
protected enum FPCR
|
protected enum Fpcr
|
||||||
{
|
{
|
||||||
/// <summary>Rounding Mode control field.</summary>
|
/// <summary>Rounding Mode control field.</summary>
|
||||||
RMode = 22,
|
RMode = 22,
|
||||||
/// <summary>Flush-to-zero mode control bit.</summary>
|
/// <summary>Flush-to-zero mode control bit.</summary>
|
||||||
FZ = 24,
|
Fz = 24,
|
||||||
/// <summary>Default NaN mode control bit.</summary>
|
/// <summary>Default NaN mode control bit.</summary>
|
||||||
DN = 25,
|
Dn = 25,
|
||||||
/// <summary>Alternative half-precision control bit.</summary>
|
/// <summary>Alternative half-precision control bit.</summary>
|
||||||
AHP = 26
|
Ahp = 26
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Floating-point Status Register.</summary>
|
/// <summary>Floating-point Status Register.</summary>
|
||||||
[Flags] protected enum FPSR
|
[Flags] protected enum Fpsr
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
/// <summary>Invalid Operation cumulative floating-point exception bit.</summary>
|
/// <summary>Invalid Operation cumulative floating-point exception bit.</summary>
|
||||||
IOC = 1 << 0,
|
Ioc = 1 << 0,
|
||||||
/// <summary>Divide by Zero cumulative floating-point exception bit.</summary>
|
/// <summary>Divide by Zero cumulative floating-point exception bit.</summary>
|
||||||
DZC = 1 << 1,
|
Dzc = 1 << 1,
|
||||||
/// <summary>Overflow cumulative floating-point exception bit.</summary>
|
/// <summary>Overflow cumulative floating-point exception bit.</summary>
|
||||||
OFC = 1 << 2,
|
Ofc = 1 << 2,
|
||||||
/// <summary>Underflow cumulative floating-point exception bit.</summary>
|
/// <summary>Underflow cumulative floating-point exception bit.</summary>
|
||||||
UFC = 1 << 3,
|
Ufc = 1 << 3,
|
||||||
/// <summary>Inexact cumulative floating-point exception bit.</summary>
|
/// <summary>Inexact cumulative floating-point exception bit.</summary>
|
||||||
IXC = 1 << 4,
|
Ixc = 1 << 4,
|
||||||
/// <summary>Input Denormal cumulative floating-point exception bit.</summary>
|
/// <summary>Input Denormal cumulative floating-point exception bit.</summary>
|
||||||
IDC = 1 << 7,
|
Idc = 1 << 7,
|
||||||
|
|
||||||
/// <summary>Cumulative saturation bit.</summary>
|
/// <summary>Cumulative saturation bit.</summary>
|
||||||
QC = 1 << 27
|
Qc = 1 << 27
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags] protected enum FpSkips
|
[Flags] protected enum FpSkips
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
IfNaN_S = 1,
|
IfNaNS = 1,
|
||||||
IfNaN_D = 2,
|
IfNaND = 2,
|
||||||
|
|
||||||
IfUnderflow = 4,
|
IfUnderflow = 4,
|
||||||
IfOverflow = 8
|
IfOverflow = 8
|
||||||
|
@ -241,204 +241,204 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
|
||||||
UpToOneUlps_S,
|
UpToOneUlpsS,
|
||||||
UpToOneUlps_D
|
UpToOneUlpsD
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void CompareAgainstUnicorn(
|
protected void CompareAgainstUnicorn(
|
||||||
FPSR FpsrMask = FPSR.None,
|
Fpsr fpsrMask = Fpsr.None,
|
||||||
FpSkips FpSkips = FpSkips.None,
|
FpSkips fpSkips = FpSkips.None,
|
||||||
FpTolerances FpTolerances = FpTolerances.None)
|
FpTolerances fpTolerances = FpTolerances.None)
|
||||||
{
|
{
|
||||||
if (!UnicornAvailable)
|
if (!_unicornAvailable)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FpSkips != FpSkips.None)
|
if (fpSkips != FpSkips.None)
|
||||||
{
|
{
|
||||||
ManageFpSkips(FpSkips);
|
ManageFpSkips(fpSkips);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.X0, Is.EqualTo(UnicornEmu.X[0]));
|
Assert.That(_thread.ThreadState.X0, Is.EqualTo(_unicornEmu.X[0]));
|
||||||
Assert.That(Thread.ThreadState.X1, Is.EqualTo(UnicornEmu.X[1]));
|
Assert.That(_thread.ThreadState.X1, Is.EqualTo(_unicornEmu.X[1]));
|
||||||
Assert.That(Thread.ThreadState.X2, Is.EqualTo(UnicornEmu.X[2]));
|
Assert.That(_thread.ThreadState.X2, Is.EqualTo(_unicornEmu.X[2]));
|
||||||
Assert.That(Thread.ThreadState.X3, Is.EqualTo(UnicornEmu.X[3]));
|
Assert.That(_thread.ThreadState.X3, Is.EqualTo(_unicornEmu.X[3]));
|
||||||
Assert.That(Thread.ThreadState.X4, Is.EqualTo(UnicornEmu.X[4]));
|
Assert.That(_thread.ThreadState.X4, Is.EqualTo(_unicornEmu.X[4]));
|
||||||
Assert.That(Thread.ThreadState.X5, Is.EqualTo(UnicornEmu.X[5]));
|
Assert.That(_thread.ThreadState.X5, Is.EqualTo(_unicornEmu.X[5]));
|
||||||
Assert.That(Thread.ThreadState.X6, Is.EqualTo(UnicornEmu.X[6]));
|
Assert.That(_thread.ThreadState.X6, Is.EqualTo(_unicornEmu.X[6]));
|
||||||
Assert.That(Thread.ThreadState.X7, Is.EqualTo(UnicornEmu.X[7]));
|
Assert.That(_thread.ThreadState.X7, Is.EqualTo(_unicornEmu.X[7]));
|
||||||
Assert.That(Thread.ThreadState.X8, Is.EqualTo(UnicornEmu.X[8]));
|
Assert.That(_thread.ThreadState.X8, Is.EqualTo(_unicornEmu.X[8]));
|
||||||
Assert.That(Thread.ThreadState.X9, Is.EqualTo(UnicornEmu.X[9]));
|
Assert.That(_thread.ThreadState.X9, Is.EqualTo(_unicornEmu.X[9]));
|
||||||
Assert.That(Thread.ThreadState.X10, Is.EqualTo(UnicornEmu.X[10]));
|
Assert.That(_thread.ThreadState.X10, Is.EqualTo(_unicornEmu.X[10]));
|
||||||
Assert.That(Thread.ThreadState.X11, Is.EqualTo(UnicornEmu.X[11]));
|
Assert.That(_thread.ThreadState.X11, Is.EqualTo(_unicornEmu.X[11]));
|
||||||
Assert.That(Thread.ThreadState.X12, Is.EqualTo(UnicornEmu.X[12]));
|
Assert.That(_thread.ThreadState.X12, Is.EqualTo(_unicornEmu.X[12]));
|
||||||
Assert.That(Thread.ThreadState.X13, Is.EqualTo(UnicornEmu.X[13]));
|
Assert.That(_thread.ThreadState.X13, Is.EqualTo(_unicornEmu.X[13]));
|
||||||
Assert.That(Thread.ThreadState.X14, Is.EqualTo(UnicornEmu.X[14]));
|
Assert.That(_thread.ThreadState.X14, Is.EqualTo(_unicornEmu.X[14]));
|
||||||
Assert.That(Thread.ThreadState.X15, Is.EqualTo(UnicornEmu.X[15]));
|
Assert.That(_thread.ThreadState.X15, Is.EqualTo(_unicornEmu.X[15]));
|
||||||
Assert.That(Thread.ThreadState.X16, Is.EqualTo(UnicornEmu.X[16]));
|
Assert.That(_thread.ThreadState.X16, Is.EqualTo(_unicornEmu.X[16]));
|
||||||
Assert.That(Thread.ThreadState.X17, Is.EqualTo(UnicornEmu.X[17]));
|
Assert.That(_thread.ThreadState.X17, Is.EqualTo(_unicornEmu.X[17]));
|
||||||
Assert.That(Thread.ThreadState.X18, Is.EqualTo(UnicornEmu.X[18]));
|
Assert.That(_thread.ThreadState.X18, Is.EqualTo(_unicornEmu.X[18]));
|
||||||
Assert.That(Thread.ThreadState.X19, Is.EqualTo(UnicornEmu.X[19]));
|
Assert.That(_thread.ThreadState.X19, Is.EqualTo(_unicornEmu.X[19]));
|
||||||
Assert.That(Thread.ThreadState.X20, Is.EqualTo(UnicornEmu.X[20]));
|
Assert.That(_thread.ThreadState.X20, Is.EqualTo(_unicornEmu.X[20]));
|
||||||
Assert.That(Thread.ThreadState.X21, Is.EqualTo(UnicornEmu.X[21]));
|
Assert.That(_thread.ThreadState.X21, Is.EqualTo(_unicornEmu.X[21]));
|
||||||
Assert.That(Thread.ThreadState.X22, Is.EqualTo(UnicornEmu.X[22]));
|
Assert.That(_thread.ThreadState.X22, Is.EqualTo(_unicornEmu.X[22]));
|
||||||
Assert.That(Thread.ThreadState.X23, Is.EqualTo(UnicornEmu.X[23]));
|
Assert.That(_thread.ThreadState.X23, Is.EqualTo(_unicornEmu.X[23]));
|
||||||
Assert.That(Thread.ThreadState.X24, Is.EqualTo(UnicornEmu.X[24]));
|
Assert.That(_thread.ThreadState.X24, Is.EqualTo(_unicornEmu.X[24]));
|
||||||
Assert.That(Thread.ThreadState.X25, Is.EqualTo(UnicornEmu.X[25]));
|
Assert.That(_thread.ThreadState.X25, Is.EqualTo(_unicornEmu.X[25]));
|
||||||
Assert.That(Thread.ThreadState.X26, Is.EqualTo(UnicornEmu.X[26]));
|
Assert.That(_thread.ThreadState.X26, Is.EqualTo(_unicornEmu.X[26]));
|
||||||
Assert.That(Thread.ThreadState.X27, Is.EqualTo(UnicornEmu.X[27]));
|
Assert.That(_thread.ThreadState.X27, Is.EqualTo(_unicornEmu.X[27]));
|
||||||
Assert.That(Thread.ThreadState.X28, Is.EqualTo(UnicornEmu.X[28]));
|
Assert.That(_thread.ThreadState.X28, Is.EqualTo(_unicornEmu.X[28]));
|
||||||
Assert.That(Thread.ThreadState.X29, Is.EqualTo(UnicornEmu.X[29]));
|
Assert.That(_thread.ThreadState.X29, Is.EqualTo(_unicornEmu.X[29]));
|
||||||
Assert.That(Thread.ThreadState.X30, Is.EqualTo(UnicornEmu.X[30]));
|
Assert.That(_thread.ThreadState.X30, Is.EqualTo(_unicornEmu.X[30]));
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.X31, Is.EqualTo(UnicornEmu.SP));
|
Assert.That(_thread.ThreadState.X31, Is.EqualTo(_unicornEmu.SP));
|
||||||
|
|
||||||
if (FpTolerances == FpTolerances.None)
|
if (fpTolerances == FpTolerances.None)
|
||||||
{
|
{
|
||||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
Assert.That(_thread.ThreadState.V0, Is.EqualTo(_unicornEmu.Q[0]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ManageFpTolerances(FpTolerances);
|
ManageFpTolerances(fpTolerances);
|
||||||
}
|
}
|
||||||
Assert.That(Thread.ThreadState.V1, Is.EqualTo(UnicornEmu.Q[1]));
|
Assert.That(_thread.ThreadState.V1, Is.EqualTo(_unicornEmu.Q[1]));
|
||||||
Assert.That(Thread.ThreadState.V2, Is.EqualTo(UnicornEmu.Q[2]));
|
Assert.That(_thread.ThreadState.V2, Is.EqualTo(_unicornEmu.Q[2]));
|
||||||
Assert.That(Thread.ThreadState.V3, Is.EqualTo(UnicornEmu.Q[3]));
|
Assert.That(_thread.ThreadState.V3, Is.EqualTo(_unicornEmu.Q[3]));
|
||||||
Assert.That(Thread.ThreadState.V4, Is.EqualTo(UnicornEmu.Q[4]));
|
Assert.That(_thread.ThreadState.V4, Is.EqualTo(_unicornEmu.Q[4]));
|
||||||
Assert.That(Thread.ThreadState.V5, Is.EqualTo(UnicornEmu.Q[5]));
|
Assert.That(_thread.ThreadState.V5, Is.EqualTo(_unicornEmu.Q[5]));
|
||||||
Assert.That(Thread.ThreadState.V6, Is.EqualTo(UnicornEmu.Q[6]));
|
Assert.That(_thread.ThreadState.V6, Is.EqualTo(_unicornEmu.Q[6]));
|
||||||
Assert.That(Thread.ThreadState.V7, Is.EqualTo(UnicornEmu.Q[7]));
|
Assert.That(_thread.ThreadState.V7, Is.EqualTo(_unicornEmu.Q[7]));
|
||||||
Assert.That(Thread.ThreadState.V8, Is.EqualTo(UnicornEmu.Q[8]));
|
Assert.That(_thread.ThreadState.V8, Is.EqualTo(_unicornEmu.Q[8]));
|
||||||
Assert.That(Thread.ThreadState.V9, Is.EqualTo(UnicornEmu.Q[9]));
|
Assert.That(_thread.ThreadState.V9, Is.EqualTo(_unicornEmu.Q[9]));
|
||||||
Assert.That(Thread.ThreadState.V10, Is.EqualTo(UnicornEmu.Q[10]));
|
Assert.That(_thread.ThreadState.V10, Is.EqualTo(_unicornEmu.Q[10]));
|
||||||
Assert.That(Thread.ThreadState.V11, Is.EqualTo(UnicornEmu.Q[11]));
|
Assert.That(_thread.ThreadState.V11, Is.EqualTo(_unicornEmu.Q[11]));
|
||||||
Assert.That(Thread.ThreadState.V12, Is.EqualTo(UnicornEmu.Q[12]));
|
Assert.That(_thread.ThreadState.V12, Is.EqualTo(_unicornEmu.Q[12]));
|
||||||
Assert.That(Thread.ThreadState.V13, Is.EqualTo(UnicornEmu.Q[13]));
|
Assert.That(_thread.ThreadState.V13, Is.EqualTo(_unicornEmu.Q[13]));
|
||||||
Assert.That(Thread.ThreadState.V14, Is.EqualTo(UnicornEmu.Q[14]));
|
Assert.That(_thread.ThreadState.V14, Is.EqualTo(_unicornEmu.Q[14]));
|
||||||
Assert.That(Thread.ThreadState.V15, Is.EqualTo(UnicornEmu.Q[15]));
|
Assert.That(_thread.ThreadState.V15, Is.EqualTo(_unicornEmu.Q[15]));
|
||||||
Assert.That(Thread.ThreadState.V16, Is.EqualTo(UnicornEmu.Q[16]));
|
Assert.That(_thread.ThreadState.V16, Is.EqualTo(_unicornEmu.Q[16]));
|
||||||
Assert.That(Thread.ThreadState.V17, Is.EqualTo(UnicornEmu.Q[17]));
|
Assert.That(_thread.ThreadState.V17, Is.EqualTo(_unicornEmu.Q[17]));
|
||||||
Assert.That(Thread.ThreadState.V18, Is.EqualTo(UnicornEmu.Q[18]));
|
Assert.That(_thread.ThreadState.V18, Is.EqualTo(_unicornEmu.Q[18]));
|
||||||
Assert.That(Thread.ThreadState.V19, Is.EqualTo(UnicornEmu.Q[19]));
|
Assert.That(_thread.ThreadState.V19, Is.EqualTo(_unicornEmu.Q[19]));
|
||||||
Assert.That(Thread.ThreadState.V20, Is.EqualTo(UnicornEmu.Q[20]));
|
Assert.That(_thread.ThreadState.V20, Is.EqualTo(_unicornEmu.Q[20]));
|
||||||
Assert.That(Thread.ThreadState.V21, Is.EqualTo(UnicornEmu.Q[21]));
|
Assert.That(_thread.ThreadState.V21, Is.EqualTo(_unicornEmu.Q[21]));
|
||||||
Assert.That(Thread.ThreadState.V22, Is.EqualTo(UnicornEmu.Q[22]));
|
Assert.That(_thread.ThreadState.V22, Is.EqualTo(_unicornEmu.Q[22]));
|
||||||
Assert.That(Thread.ThreadState.V23, Is.EqualTo(UnicornEmu.Q[23]));
|
Assert.That(_thread.ThreadState.V23, Is.EqualTo(_unicornEmu.Q[23]));
|
||||||
Assert.That(Thread.ThreadState.V24, Is.EqualTo(UnicornEmu.Q[24]));
|
Assert.That(_thread.ThreadState.V24, Is.EqualTo(_unicornEmu.Q[24]));
|
||||||
Assert.That(Thread.ThreadState.V25, Is.EqualTo(UnicornEmu.Q[25]));
|
Assert.That(_thread.ThreadState.V25, Is.EqualTo(_unicornEmu.Q[25]));
|
||||||
Assert.That(Thread.ThreadState.V26, Is.EqualTo(UnicornEmu.Q[26]));
|
Assert.That(_thread.ThreadState.V26, Is.EqualTo(_unicornEmu.Q[26]));
|
||||||
Assert.That(Thread.ThreadState.V27, Is.EqualTo(UnicornEmu.Q[27]));
|
Assert.That(_thread.ThreadState.V27, Is.EqualTo(_unicornEmu.Q[27]));
|
||||||
Assert.That(Thread.ThreadState.V28, Is.EqualTo(UnicornEmu.Q[28]));
|
Assert.That(_thread.ThreadState.V28, Is.EqualTo(_unicornEmu.Q[28]));
|
||||||
Assert.That(Thread.ThreadState.V29, Is.EqualTo(UnicornEmu.Q[29]));
|
Assert.That(_thread.ThreadState.V29, Is.EqualTo(_unicornEmu.Q[29]));
|
||||||
Assert.That(Thread.ThreadState.V30, Is.EqualTo(UnicornEmu.Q[30]));
|
Assert.That(_thread.ThreadState.V30, Is.EqualTo(_unicornEmu.Q[30]));
|
||||||
Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31]));
|
Assert.That(_thread.ThreadState.V31, Is.EqualTo(_unicornEmu.Q[31]));
|
||||||
Assert.That(Thread.ThreadState.V31, Is.EqualTo(UnicornEmu.Q[31]));
|
Assert.That(_thread.ThreadState.V31, Is.EqualTo(_unicornEmu.Q[31]));
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.Fpcr, Is.EqualTo(UnicornEmu.Fpcr));
|
Assert.That(_thread.ThreadState.Fpcr, Is.EqualTo(_unicornEmu.Fpcr));
|
||||||
Assert.That(Thread.ThreadState.Fpsr & (int)FpsrMask, Is.EqualTo(UnicornEmu.Fpsr & (int)FpsrMask));
|
Assert.That(_thread.ThreadState.Fpsr & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpsr & (int)fpsrMask));
|
||||||
|
|
||||||
Assert.That(Thread.ThreadState.Overflow, Is.EqualTo(UnicornEmu.OverflowFlag));
|
Assert.That(_thread.ThreadState.Overflow, Is.EqualTo(_unicornEmu.OverflowFlag));
|
||||||
Assert.That(Thread.ThreadState.Carry, Is.EqualTo(UnicornEmu.CarryFlag));
|
Assert.That(_thread.ThreadState.Carry, Is.EqualTo(_unicornEmu.CarryFlag));
|
||||||
Assert.That(Thread.ThreadState.Zero, Is.EqualTo(UnicornEmu.ZeroFlag));
|
Assert.That(_thread.ThreadState.Zero, Is.EqualTo(_unicornEmu.ZeroFlag));
|
||||||
Assert.That(Thread.ThreadState.Negative, Is.EqualTo(UnicornEmu.NegativeFlag));
|
Assert.That(_thread.ThreadState.Negative, Is.EqualTo(_unicornEmu.NegativeFlag));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ManageFpSkips(FpSkips FpSkips)
|
private void ManageFpSkips(FpSkips fpSkips)
|
||||||
{
|
{
|
||||||
if (FpSkips.HasFlag(FpSkips.IfNaN_S))
|
if (fpSkips.HasFlag(FpSkips.IfNaNS))
|
||||||
{
|
{
|
||||||
if (float.IsNaN(VectorExtractSingle(UnicornEmu.Q[0], (byte)0)))
|
if (float.IsNaN(VectorExtractSingle(_unicornEmu.Q[0], (byte)0)))
|
||||||
{
|
{
|
||||||
Assert.Ignore("NaN test.");
|
Assert.Ignore("NaN test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (FpSkips.HasFlag(FpSkips.IfNaN_D))
|
else if (fpSkips.HasFlag(FpSkips.IfNaND))
|
||||||
{
|
{
|
||||||
if (double.IsNaN(VectorExtractDouble(UnicornEmu.Q[0], (byte)0)))
|
if (double.IsNaN(VectorExtractDouble(_unicornEmu.Q[0], (byte)0)))
|
||||||
{
|
{
|
||||||
Assert.Ignore("NaN test.");
|
Assert.Ignore("NaN test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FpSkips.HasFlag(FpSkips.IfUnderflow))
|
if (fpSkips.HasFlag(FpSkips.IfUnderflow))
|
||||||
{
|
{
|
||||||
if ((UnicornEmu.Fpsr & (int)FPSR.UFC) != 0)
|
if ((_unicornEmu.Fpsr & (int)Fpsr.Ufc) != 0)
|
||||||
{
|
{
|
||||||
Assert.Ignore("Underflow test.");
|
Assert.Ignore("Underflow test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FpSkips.HasFlag(FpSkips.IfOverflow))
|
if (fpSkips.HasFlag(FpSkips.IfOverflow))
|
||||||
{
|
{
|
||||||
if ((UnicornEmu.Fpsr & (int)FPSR.OFC) != 0)
|
if ((_unicornEmu.Fpsr & (int)Fpsr.Ofc) != 0)
|
||||||
{
|
{
|
||||||
Assert.Ignore("Overflow test.");
|
Assert.Ignore("Overflow test.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ManageFpTolerances(FpTolerances FpTolerances)
|
private void ManageFpTolerances(FpTolerances fpTolerances)
|
||||||
{
|
{
|
||||||
if (!Is.EqualTo(UnicornEmu.Q[0]).ApplyTo(Thread.ThreadState.V0).IsSuccess)
|
if (!Is.EqualTo(_unicornEmu.Q[0]).ApplyTo(_thread.ThreadState.V0).IsSuccess)
|
||||||
{
|
{
|
||||||
if (FpTolerances == FpTolerances.UpToOneUlps_S)
|
if (fpTolerances == FpTolerances.UpToOneUlpsS)
|
||||||
{
|
{
|
||||||
if (IsNormalOrSubnormal_S(VectorExtractSingle(UnicornEmu.Q[0], (byte)0)) &&
|
if (IsNormalOrSubnormalS(VectorExtractSingle(_unicornEmu.Q[0], (byte)0)) &&
|
||||||
IsNormalOrSubnormal_S(VectorExtractSingle(Thread.ThreadState.V0, (byte)0)))
|
IsNormalOrSubnormalS(VectorExtractSingle(_thread.ThreadState.V0, (byte)0)))
|
||||||
{
|
{
|
||||||
Assert.That (VectorExtractSingle(Thread.ThreadState.V0, (byte)0),
|
Assert.That (VectorExtractSingle(_thread.ThreadState.V0, (byte)0),
|
||||||
Is.EqualTo(VectorExtractSingle(UnicornEmu.Q[0], (byte)0)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractSingle(_unicornEmu.Q[0], (byte)0)).Within(1).Ulps);
|
||||||
Assert.That (VectorExtractSingle(Thread.ThreadState.V0, (byte)1),
|
Assert.That (VectorExtractSingle(_thread.ThreadState.V0, (byte)1),
|
||||||
Is.EqualTo(VectorExtractSingle(UnicornEmu.Q[0], (byte)1)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractSingle(_unicornEmu.Q[0], (byte)1)).Within(1).Ulps);
|
||||||
Assert.That (VectorExtractSingle(Thread.ThreadState.V0, (byte)2),
|
Assert.That (VectorExtractSingle(_thread.ThreadState.V0, (byte)2),
|
||||||
Is.EqualTo(VectorExtractSingle(UnicornEmu.Q[0], (byte)2)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractSingle(_unicornEmu.Q[0], (byte)2)).Within(1).Ulps);
|
||||||
Assert.That (VectorExtractSingle(Thread.ThreadState.V0, (byte)3),
|
Assert.That (VectorExtractSingle(_thread.ThreadState.V0, (byte)3),
|
||||||
Is.EqualTo(VectorExtractSingle(UnicornEmu.Q[0], (byte)3)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractSingle(_unicornEmu.Q[0], (byte)3)).Within(1).Ulps);
|
||||||
|
|
||||||
Console.WriteLine(FpTolerances);
|
Console.WriteLine(fpTolerances);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
Assert.That(_thread.ThreadState.V0, Is.EqualTo(_unicornEmu.Q[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FpTolerances == FpTolerances.UpToOneUlps_D)
|
if (fpTolerances == FpTolerances.UpToOneUlpsD)
|
||||||
{
|
{
|
||||||
if (IsNormalOrSubnormal_D(VectorExtractDouble(UnicornEmu.Q[0], (byte)0)) &&
|
if (IsNormalOrSubnormalD(VectorExtractDouble(_unicornEmu.Q[0], (byte)0)) &&
|
||||||
IsNormalOrSubnormal_D(VectorExtractDouble(Thread.ThreadState.V0, (byte)0)))
|
IsNormalOrSubnormalD(VectorExtractDouble(_thread.ThreadState.V0, (byte)0)))
|
||||||
{
|
{
|
||||||
Assert.That (VectorExtractDouble(Thread.ThreadState.V0, (byte)0),
|
Assert.That (VectorExtractDouble(_thread.ThreadState.V0, (byte)0),
|
||||||
Is.EqualTo(VectorExtractDouble(UnicornEmu.Q[0], (byte)0)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractDouble(_unicornEmu.Q[0], (byte)0)).Within(1).Ulps);
|
||||||
Assert.That (VectorExtractDouble(Thread.ThreadState.V0, (byte)1),
|
Assert.That (VectorExtractDouble(_thread.ThreadState.V0, (byte)1),
|
||||||
Is.EqualTo(VectorExtractDouble(UnicornEmu.Q[0], (byte)1)).Within(1).Ulps);
|
Is.EqualTo(VectorExtractDouble(_unicornEmu.Q[0], (byte)1)).Within(1).Ulps);
|
||||||
|
|
||||||
Console.WriteLine(FpTolerances);
|
Console.WriteLine(fpTolerances);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert.That(Thread.ThreadState.V0, Is.EqualTo(UnicornEmu.Q[0]));
|
Assert.That(_thread.ThreadState.V0, Is.EqualTo(_unicornEmu.Q[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNormalOrSubnormal_S(float f) => float.IsNormal(f) || float.IsSubnormal(f);
|
bool IsNormalOrSubnormalS(float f) => float.IsNormal(f) || float.IsSubnormal(f);
|
||||||
|
|
||||||
bool IsNormalOrSubnormal_D(double d) => double.IsNormal(d) || double.IsSubnormal(d);
|
bool IsNormalOrSubnormalD(double d) => double.IsNormal(d) || double.IsSubnormal(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE0(double E0)
|
protected static Vector128<float> MakeVectorE0(double e0)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<long, float>(Sse2.SetVector128(0, BitConverter.DoubleToInt64Bits(E0)));
|
return Sse.StaticCast<long, float>(Sse2.SetVector128(0, BitConverter.DoubleToInt64Bits(e0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE0E1(double E0, double E1)
|
protected static Vector128<float> MakeVectorE0E1(double e0, double e1)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
|
@ -446,154 +446,154 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<long, float>(
|
return Sse.StaticCast<long, float>(
|
||||||
Sse2.SetVector128(BitConverter.DoubleToInt64Bits(E1), BitConverter.DoubleToInt64Bits(E0)));
|
Sse2.SetVector128(BitConverter.DoubleToInt64Bits(e1), BitConverter.DoubleToInt64Bits(e0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE1(double E1)
|
protected static Vector128<float> MakeVectorE1(double e1)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<long, float>(Sse2.SetVector128(BitConverter.DoubleToInt64Bits(E1), 0));
|
return Sse.StaticCast<long, float>(Sse2.SetVector128(BitConverter.DoubleToInt64Bits(e1), 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static float VectorExtractSingle(Vector128<float> Vector, byte Index)
|
protected static float VectorExtractSingle(Vector128<float> vector, byte index)
|
||||||
{
|
{
|
||||||
if (!Sse41.IsSupported)
|
if (!Sse41.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Value = Sse41.Extract(Sse.StaticCast<float, int>(Vector), Index);
|
int value = Sse41.Extract(Sse.StaticCast<float, int>(vector), index);
|
||||||
|
|
||||||
return BitConverter.Int32BitsToSingle(Value);
|
return BitConverter.Int32BitsToSingle(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static double VectorExtractDouble(Vector128<float> Vector, byte Index)
|
protected static double VectorExtractDouble(Vector128<float> vector, byte index)
|
||||||
{
|
{
|
||||||
if (!Sse41.IsSupported)
|
if (!Sse41.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
long Value = Sse41.Extract(Sse.StaticCast<float, long>(Vector), Index);
|
long value = Sse41.Extract(Sse.StaticCast<float, long>(vector), index);
|
||||||
|
|
||||||
return BitConverter.Int64BitsToDouble(Value);
|
return BitConverter.Int64BitsToDouble(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE0(ulong E0)
|
protected static Vector128<float> MakeVectorE0(ulong e0)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, E0));
|
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(0, e0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE0E1(ulong E0, ulong E1)
|
protected static Vector128<float> MakeVectorE0E1(ulong e0, ulong e1)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(E1, E0));
|
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(e1, e0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Vector128<float> MakeVectorE1(ulong E1)
|
protected static Vector128<float> MakeVectorE1(ulong e1)
|
||||||
{
|
{
|
||||||
if (!Sse2.IsSupported)
|
if (!Sse2.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(E1, 0));
|
return Sse.StaticCast<ulong, float>(Sse2.SetVector128(e1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ulong GetVectorE0(Vector128<float> Vector)
|
protected static ulong GetVectorE0(Vector128<float> vector)
|
||||||
{
|
{
|
||||||
if (!Sse41.IsSupported)
|
if (!Sse41.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse41.Extract(Sse.StaticCast<float, ulong>(Vector), (byte)0);
|
return Sse41.Extract(Sse.StaticCast<float, ulong>(vector), (byte)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ulong GetVectorE1(Vector128<float> Vector)
|
protected static ulong GetVectorE1(Vector128<float> vector)
|
||||||
{
|
{
|
||||||
if (!Sse41.IsSupported)
|
if (!Sse41.IsSupported)
|
||||||
{
|
{
|
||||||
throw new PlatformNotSupportedException();
|
throw new PlatformNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Sse41.Extract(Sse.StaticCast<float, ulong>(Vector), (byte)1);
|
return Sse41.Extract(Sse.StaticCast<float, ulong>(vector), (byte)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ushort GenNormal_H()
|
protected static ushort GenNormalH()
|
||||||
{
|
{
|
||||||
uint Rnd;
|
uint rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextUShort();
|
do rnd = TestContext.CurrentContext.Random.NextUShort();
|
||||||
while (( Rnd & 0x7C00u) == 0u ||
|
while (( rnd & 0x7C00u) == 0u ||
|
||||||
(~Rnd & 0x7C00u) == 0u);
|
(~rnd & 0x7C00u) == 0u);
|
||||||
|
|
||||||
return (ushort)Rnd;
|
return (ushort)rnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ushort GenSubnormal_H()
|
protected static ushort GenSubnormalH()
|
||||||
{
|
{
|
||||||
uint Rnd;
|
uint rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextUShort();
|
do rnd = TestContext.CurrentContext.Random.NextUShort();
|
||||||
while ((Rnd & 0x03FFu) == 0u);
|
while ((rnd & 0x03FFu) == 0u);
|
||||||
|
|
||||||
return (ushort)(Rnd & 0x83FFu);
|
return (ushort)(rnd & 0x83FFu);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static uint GenNormal_S()
|
protected static uint GenNormalS()
|
||||||
{
|
{
|
||||||
uint Rnd;
|
uint rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextUInt();
|
do rnd = TestContext.CurrentContext.Random.NextUInt();
|
||||||
while (( Rnd & 0x7F800000u) == 0u ||
|
while (( rnd & 0x7F800000u) == 0u ||
|
||||||
(~Rnd & 0x7F800000u) == 0u);
|
(~rnd & 0x7F800000u) == 0u);
|
||||||
|
|
||||||
return Rnd;
|
return rnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static uint GenSubnormal_S()
|
protected static uint GenSubnormalS()
|
||||||
{
|
{
|
||||||
uint Rnd;
|
uint rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextUInt();
|
do rnd = TestContext.CurrentContext.Random.NextUInt();
|
||||||
while ((Rnd & 0x007FFFFFu) == 0u);
|
while ((rnd & 0x007FFFFFu) == 0u);
|
||||||
|
|
||||||
return Rnd & 0x807FFFFFu;
|
return rnd & 0x807FFFFFu;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ulong GenNormal_D()
|
protected static ulong GenNormalD()
|
||||||
{
|
{
|
||||||
ulong Rnd;
|
ulong rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextULong();
|
do rnd = TestContext.CurrentContext.Random.NextULong();
|
||||||
while (( Rnd & 0x7FF0000000000000ul) == 0ul ||
|
while (( rnd & 0x7FF0000000000000ul) == 0ul ||
|
||||||
(~Rnd & 0x7FF0000000000000ul) == 0ul);
|
(~rnd & 0x7FF0000000000000ul) == 0ul);
|
||||||
|
|
||||||
return Rnd;
|
return rnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ulong GenSubnormal_D()
|
protected static ulong GenSubnormalD()
|
||||||
{
|
{
|
||||||
ulong Rnd;
|
ulong rnd;
|
||||||
|
|
||||||
do Rnd = TestContext.CurrentContext.Random.NextULong();
|
do rnd = TestContext.CurrentContext.Random.NextULong();
|
||||||
while ((Rnd & 0x000FFFFFFFFFFFFFul) == 0ul);
|
while ((rnd & 0x000FFFFFFFFFFFFFul) == 0ul);
|
||||||
|
|
||||||
return Rnd & 0x800FFFFFFFFFFFFFul;
|
return rnd & 0x800FFFFFFFFFFFFFul;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,189 +1,187 @@
|
||||||
#define Alu
|
#define Alu
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Alu")] // Tested: second half of 2018.
|
[Category("Alu")]
|
||||||
public sealed class CpuTestAlu : CpuTest
|
public sealed class CpuTestAlu : CpuTest
|
||||||
{
|
{
|
||||||
#if Alu
|
#if Alu
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("CLS <Xd>, <Xn>")]
|
[Test, Pairwise, Description("CLS <Xd>, <Xn>")]
|
||||||
public void Cls_64bit([Values(0u, 31u)] uint Rd,
|
public void Cls_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC01400; // CLS X0, X0
|
uint opcode = 0xDAC01400; // CLS X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CLS <Wd>, <Wn>")]
|
[Test, Pairwise, Description("CLS <Wd>, <Wn>")]
|
||||||
public void Cls_32bit([Values(0u, 31u)] uint Rd,
|
public void Cls_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC01400; // CLS W0, W0
|
uint opcode = 0x5AC01400; // CLS W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
|
[Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
|
||||||
public void Clz_64bit([Values(0u, 31u)] uint Rd,
|
public void Clz_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC01000; // CLZ X0, X0
|
uint opcode = 0xDAC01000; // CLZ X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
|
[Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
|
||||||
public void Clz_32bit([Values(0u, 31u)] uint Rd,
|
public void Clz_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC01000; // CLZ W0, W0
|
uint opcode = 0x5AC01000; // CLZ W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
|
[Test, Pairwise, Description("RBIT <Xd>, <Xn>")]
|
||||||
public void Rbit_64bit([Values(0u, 31u)] uint Rd,
|
public void Rbit_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00000; // RBIT X0, X0
|
uint opcode = 0xDAC00000; // RBIT X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
|
[Test, Pairwise, Description("RBIT <Wd>, <Wn>")]
|
||||||
public void Rbit_32bit([Values(0u, 31u)] uint Rd,
|
public void Rbit_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00000; // RBIT W0, W0
|
uint opcode = 0x5AC00000; // RBIT W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV16 <Xd>, <Xn>")]
|
||||||
public void Rev16_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev16_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00400; // REV16 X0, X0
|
uint opcode = 0xDAC00400; // REV16 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
|
[Test, Pairwise, Description("REV16 <Wd>, <Wn>")]
|
||||||
public void Rev16_32bit([Values(0u, 31u)] uint Rd,
|
public void Rev16_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00400; // REV16 W0, W0
|
uint opcode = 0x5AC00400; // REV16 W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV32 <Xd>, <Xn>")]
|
||||||
public void Rev32_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev32_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00800; // REV32 X0, X0
|
uint opcode = 0xDAC00800; // REV32 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("REV <Wd>, <Wn>")]
|
[Test, Pairwise, Description("REV <Wd>, <Wn>")]
|
||||||
public void Rev32_32bit([Values(0u, 31u)] uint Rd,
|
public void Rev32_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5AC00800; // REV W0, W0
|
uint opcode = 0x5AC00800; // REV W0, W0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
|
[Test, Pairwise, Description("REV64 <Xd>, <Xn>")]
|
||||||
public void Rev64_64bit([Values(0u, 31u)] uint Rd,
|
public void Rev64_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDAC00C00; // REV64 X0, X0
|
uint opcode = 0xDAC00C00; // REV64 X0, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#define AluImm
|
#define AluImm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("AluImm")] // Tested: second half of 2018.
|
[Category("AluImm")]
|
||||||
public sealed class CpuTestAluImm : CpuTest
|
public sealed class CpuTestAluImm : CpuTest
|
||||||
{
|
{
|
||||||
#if AluImm
|
#if AluImm
|
||||||
|
@ -16,436 +14,420 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCntImmr = 2;
|
private const int RndCntImmr = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||||
public void Add_64bit([Values(0u, 31u)] uint Rd,
|
public void Add_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xnSp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
|
uint opcode = 0x91000000; // ADD X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
SingleOpcode(opcode, x1: xnSp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
SingleOpcode(opcode, x31: xnSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("ADD <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||||
public void Add_32bit([Values(0u, 31u)] uint Rd,
|
public void Add_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wnWsp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
|
uint opcode = 0x11000000; // ADD W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
SingleOpcode(opcode, x1: wnWsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
SingleOpcode(opcode, x31: wnWsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("ADDS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||||
public void Adds_64bit([Values(0u, 31u)] uint Rd,
|
public void Adds_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xnSp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
|
uint opcode = 0xB1000000; // ADDS X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
SingleOpcode(opcode, x1: xnSp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
SingleOpcode(opcode, x31: xnSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("ADDS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||||
public void Adds_32bit([Values(0u, 31u)] uint Rd,
|
public void Adds_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wnWsp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
|
uint opcode = 0x31000000; // ADDS W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
SingleOpcode(opcode, x1: wnWsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
SingleOpcode(opcode, x31: wnWsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void And_N1_64bit([Values(0u, 31u)] uint Rd,
|
public void And_N1_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92400000; // AND X0, X0, #0x1
|
uint opcode = 0x92400000; // AND X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("AND <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void And_N0_64bit([Values(0u, 31u)] uint Rd,
|
public void And_N0_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92000000; // AND X0, X0, #0x100000001
|
uint opcode = 0x92000000; // AND X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("AND <Wd|WSP>, <Wn>, #<imm>")]
|
||||||
public void And_32bit([Values(0u, 31u)] uint Rd,
|
public void And_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x12000000; // AND W0, W0, #0x1
|
uint opcode = 0x12000000; // AND W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||||
public void Ands_N1_64bit([Values(0u, 31u)] uint Rd,
|
public void Ands_N1_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2400000; // ANDS X0, X0, #0x1
|
uint opcode = 0xF2400000; // ANDS X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Xd>, <Xn>, #<imm>")]
|
||||||
public void Ands_N0_64bit([Values(0u, 31u)] uint Rd,
|
public void Ands_N0_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
|
uint opcode = 0xF2000000; // ANDS X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("ANDS <Wd>, <Wn>, #<imm>")]
|
||||||
public void Ands_32bit([Values(0u, 31u)] uint Rd,
|
public void Ands_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x72000000; // ANDS W0, W0, #0x1
|
uint opcode = 0x72000000; // ANDS W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void Eor_N1_64bit([Values(0u, 31u)] uint Rd,
|
public void Eor_N1_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2400000; // EOR X0, X0, #0x1
|
uint opcode = 0xD2400000; // EOR X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("EOR <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void Eor_N0_64bit([Values(0u, 31u)] uint Rd,
|
public void Eor_N0_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2000000; // EOR X0, X0, #0x100000001
|
uint opcode = 0xD2000000; // EOR X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("EOR <Wd>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("EOR <Wd>, <Wn>, #<imm>")]
|
||||||
public void Eor_32bit([Values(0u, 31u)] uint Rd,
|
public void Eor_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x52000000; // EOR W0, W0, #0x1
|
uint opcode = 0x52000000; // EOR W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void Orr_N1_64bit([Values(0u, 31u)] uint Rd,
|
public void Orr_N1_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 31u, 32u, 62u)] [Random(0u, 62u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB2400000; // ORR X0, X0, #0x1
|
uint opcode = 0xB2400000; // ORR X0, X0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
[Test, Pairwise, Description("ORR <Xd|SP>, <Xn>, #<imm>")]
|
||||||
public void Orr_N0_64bit([Values(0u, 31u)] uint Rd,
|
public void Orr_N0_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB2000000; // ORR X0, X0, #0x100000001
|
uint opcode = 0xB2000000; // ORR X0, X0, #0x100000001
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
|
[Test, Pairwise, Description("ORR <Wd|WSP>, <Wn>, #<imm>")]
|
||||||
public void Orr_32bit([Values(0u, 31u)] uint Rd,
|
public void Orr_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
[Values(0u, 15u, 16u, 30u)] [Random(0u, 30u, RndCntImms)] uint imms, // <imm>
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr) // <imm>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x32000000; // ORR W0, W0, #0x1
|
uint opcode = 0x32000000; // ORR W0, W0, #0x1
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("SUB <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||||
public void Sub_64bit([Values(0u, 31u)] uint Rd,
|
public void Sub_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xnSp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
|
uint opcode = 0xD1000000; // SUB X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
SingleOpcode(opcode, x1: xnSp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
SingleOpcode(opcode, x31: xnSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("SUB <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||||
public void Sub_32bit([Values(0u, 31u)] uint Rd,
|
public void Sub_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wnWsp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
|
uint opcode = 0x51000000; // SUB W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
SingleOpcode(opcode, x1: wnWsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
SingleOpcode(opcode, x31: wnWsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("SUBS <Xd>, <Xn|SP>, #<imm>{, <shift>}")]
|
||||||
public void Subs_64bit([Values(0u, 31u)] uint Rd,
|
public void Subs_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn_SP,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xnSp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
|
uint opcode = 0xF1000000; // SUBS X0, X0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Xn_SP);
|
SingleOpcode(opcode, x1: xnSp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Xn_SP);
|
SingleOpcode(opcode, x31: xnSp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
[Test, Pairwise, Description("SUBS <Wd>, <Wn|WSP>, #<imm>{, <shift>}")]
|
||||||
public void Subs_32bit([Values(0u, 31u)] uint Rd,
|
public void Subs_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn_WSP,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wnWsp,
|
||||||
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
[Values(0u, 4095u)] [Random(0u, 4095u, RndCntImm)] uint imm,
|
||||||
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
[Values(0b00u, 0b01u)] uint shift) // <LSL #0, LSL #12>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
|
uint opcode = 0x71000000; // SUBS W0, W0, #0, LSL #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
opcode |= ((shift & 3) << 22) | ((imm & 4095) << 10);
|
||||||
|
|
||||||
CpuThreadState ThreadState;
|
if (rn != 31)
|
||||||
|
|
||||||
if (Rn != 31)
|
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X1: Wn_WSP);
|
SingleOpcode(opcode, x1: wnWsp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ThreadState = SingleOpcode(Opcode, X31: Wn_WSP);
|
SingleOpcode(opcode, x31: wnWsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,10 @@
|
||||||
#define Bfm
|
#define Bfm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Bfm")] // Tested: second half of 2018.
|
[Category("Bfm")]
|
||||||
public sealed class CpuTestBfm : CpuTest
|
public sealed class CpuTestBfm : CpuTest
|
||||||
{
|
{
|
||||||
#if Bfm
|
#if Bfm
|
||||||
|
@ -15,117 +13,117 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCntImms = 2;
|
private const int RndCntImms = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||||
public void Bfm_64bit([Values(0u, 31u)] uint Rd,
|
public void Bfm_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Random(RndCnt)] ulong _Xd,
|
[Random(RndCnt)] ulong xd,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xB3400000; // BFM X0, X0, #0, #0
|
uint opcode = 0xB3400000; // BFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x0: xd, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("BFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("BFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||||
public void Bfm_32bit([Values(0u, 31u)] uint Rd,
|
public void Bfm_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Random(RndCnt)] uint _Wd,
|
[Random(RndCnt)] uint wd,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x33000000; // BFM W0, W0, #0, #0
|
uint opcode = 0x33000000; // BFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x0: wd, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("SBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||||
public void Sbfm_64bit([Values(0u, 31u)] uint Rd,
|
public void Sbfm_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x93400000; // SBFM X0, X0, #0, #0
|
uint opcode = 0x93400000; // SBFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("SBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||||
public void Sbfm_32bit([Values(0u, 31u)] uint Rd,
|
public void Sbfm_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x13000000; // SBFM W0, W0, #0, #0
|
uint opcode = 0x13000000; // SBFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("UBFM <Xd>, <Xn>, #<immr>, #<imms>")]
|
||||||
public void Ubfm_64bit([Values(0u, 31u)] uint Rd,
|
public void Ubfm_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
[Values(0u, 31u, 32u, 63u)] [Random(0u, 63u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD3400000; // UBFM X0, X0, #0, #0
|
uint opcode = 0xD3400000; // UBFM X0, X0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
[Test, Pairwise, Description("UBFM <Wd>, <Wn>, #<immr>, #<imms>")]
|
||||||
public void Ubfm_32bit([Values(0u, 31u)] uint Rd,
|
public void Ubfm_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint immr,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint imms)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x53000000; // UBFM W0, W0, #0, #0
|
uint opcode = 0x53000000; // UBFM W0, W0, #0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
opcode |= ((immr & 63) << 16) | ((imms & 63) << 10);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#define CcmpImm
|
#define CcmpImm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("CcmpImm")] // Tested: second half of 2018.
|
[Category("CcmpImm")]
|
||||||
public sealed class CpuTestCcmpImm : CpuTest
|
public sealed class CpuTestCcmpImm : CpuTest
|
||||||
{
|
{
|
||||||
#if CcmpImm
|
#if CcmpImm
|
||||||
|
@ -15,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCntNzcv = 2;
|
private const int RndCntNzcv = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_64bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
|
@ -25,21 +23,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xBA400800; // CCMN X0, #0, #0, EQ
|
uint opcode = 0xBA400800; // CCMN X0, #0, #0, EQ
|
||||||
Opcode |= ((Rn & 31) << 5);
|
opcode |= ((rn & 31) << 5);
|
||||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMN <Wn>, #<imm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_32bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
|
@ -47,21 +45,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x3A400800; // CCMN W0, #0, #0, EQ
|
uint opcode = 0x3A400800; // CCMN W0, #0, #0, EQ
|
||||||
Opcode |= ((Rn & 31) << 5);
|
opcode |= ((rn & 31) << 5);
|
||||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMP <Xn>, #<imm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMP <Xn>, #<imm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmp_64bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
|
@ -69,21 +67,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xFA400800; // CCMP X0, #0, #0, EQ
|
uint opcode = 0xFA400800; // CCMP X0, #0, #0, EQ
|
||||||
Opcode |= ((Rn & 31) << 5);
|
opcode |= ((rn & 31) << 5);
|
||||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMP <Wn>, #<imm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMP <Wn>, #<imm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
public void Ccmp_32bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
[Values(0u, 31u)] [Random(0u, 31u, RndCntImm)] uint imm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
|
@ -91,13 +89,13 @@ namespace Ryujinx.Tests.Cpu
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x7A400800; // CCMP W0, #0, #0, EQ
|
uint opcode = 0x7A400800; // CCMP W0, #0, #0, EQ
|
||||||
Opcode |= ((Rn & 31) << 5);
|
opcode |= ((rn & 31) << 5);
|
||||||
Opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((imm & 31) << 16) | ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#define CcmpReg
|
#define CcmpReg
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("CcmpReg")] // Tested: second half of 2018.
|
[Category("CcmpReg")]
|
||||||
public sealed class CpuTestCcmpReg : CpuTest
|
public sealed class CpuTestCcmpReg : CpuTest
|
||||||
{
|
{
|
||||||
#if CcmpReg
|
#if CcmpReg
|
||||||
|
@ -14,97 +12,97 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCntNzcv = 2;
|
private const int RndCntNzcv = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_64bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xBA400000; // CCMN X0, X0, #0, EQ
|
uint opcode = 0xBA400000; // CCMN X0, X0, #0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5);
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMN <Wn>, <Wm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMN <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmn_32bit([Values(1u, 31u)] uint Rn,
|
public void Ccmn_32bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x3A400000; // CCMN W0, W0, #0, EQ
|
uint opcode = 0x3A400000; // CCMN W0, W0, #0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5);
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMP <Xn>, <Xm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMP <Xn>, <Xm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmp_64bit([Values(1u, 31u)] uint Rn,
|
public void Ccmp_64bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xFA400000; // CCMP X0, X0, #0, EQ
|
uint opcode = 0xFA400000; // CCMP X0, X0, #0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5);
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CCMP <Wn>, <Wm>, #<nzcv>, <cond>")]
|
[Test, Pairwise, Description("CCMP <Wn>, <Wm>, #<nzcv>, <cond>")]
|
||||||
public void Ccmp_32bit([Values(1u, 31u)] uint Rn,
|
public void Ccmp_32bit([Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
[Random(0u, 15u, RndCntNzcv)] uint nzcv,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x7A400000; // CCMP W0, W0, #0, EQ
|
uint opcode = 0x7A400000; // CCMP W0, W0, #0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5);
|
||||||
Opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
opcode |= ((cond & 15) << 12) | ((nzcv & 15) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,205 +1,203 @@
|
||||||
#define Csel
|
#define Csel
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Csel")] // Tested: second half of 2018.
|
[Category("Csel")]
|
||||||
public sealed class CpuTestCsel : CpuTest
|
public sealed class CpuTestCsel : CpuTest
|
||||||
{
|
{
|
||||||
#if Csel
|
#if Csel
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
[Test, Pairwise, Description("CSEL <Xd>, <Xn>, <Xm>, <cond>")]
|
||||||
public void Csel_64bit([Values(0u, 31u)] uint Rd,
|
public void Csel_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9A800000; // CSEL X0, X0, X0, EQ
|
uint opcode = 0x9A800000; // CSEL X0, X0, X0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
|
[Test, Pairwise, Description("CSEL <Wd>, <Wn>, <Wm>, <cond>")]
|
||||||
public void Csel_32bit([Values(0u, 31u)] uint Rd,
|
public void Csel_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1A800000; // CSEL W0, W0, W0, EQ
|
uint opcode = 0x1A800000; // CSEL W0, W0, W0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
|
[Test, Pairwise, Description("CSINC <Xd>, <Xn>, <Xm>, <cond>")]
|
||||||
public void Csinc_64bit([Values(0u, 31u)] uint Rd,
|
public void Csinc_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9A800400; // CSINC X0, X0, X0, EQ
|
uint opcode = 0x9A800400; // CSINC X0, X0, X0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
|
[Test, Pairwise, Description("CSINC <Wd>, <Wn>, <Wm>, <cond>")]
|
||||||
public void Csinc_32bit([Values(0u, 31u)] uint Rd,
|
public void Csinc_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1A800400; // CSINC W0, W0, W0, EQ
|
uint opcode = 0x1A800400; // CSINC W0, W0, W0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
|
[Test, Pairwise, Description("CSINV <Xd>, <Xn>, <Xm>, <cond>")]
|
||||||
public void Csinv_64bit([Values(0u, 31u)] uint Rd,
|
public void Csinv_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDA800000; // CSINV X0, X0, X0, EQ
|
uint opcode = 0xDA800000; // CSINV X0, X0, X0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
|
[Test, Pairwise, Description("CSINV <Wd>, <Wn>, <Wm>, <cond>")]
|
||||||
public void Csinv_32bit([Values(0u, 31u)] uint Rd,
|
public void Csinv_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5A800000; // CSINV W0, W0, W0, EQ
|
uint opcode = 0x5A800000; // CSINV W0, W0, W0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
|
[Test, Pairwise, Description("CSNEG <Xd>, <Xn>, <Xm>, <cond>")]
|
||||||
public void Csneg_64bit([Values(0u, 31u)] uint Rd,
|
public void Csneg_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0xDA800400; // CSNEG X0, X0, X0, EQ
|
uint opcode = 0xDA800400; // CSNEG X0, X0, X0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
|
[Test, Pairwise, Description("CSNEG <Wd>, <Wn>, <Wm>, <cond>")]
|
||||||
public void Csneg_32bit([Values(0u, 31u)] uint Rd,
|
public void Csneg_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
[Values(0b0000u, 0b0001u, 0b0010u, 0b0011u, // <EQ, NE, CS/HS, CC/LO,
|
||||||
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
0b0100u, 0b0101u, 0b0110u, 0b0111u, // MI, PL, VS, VC,
|
||||||
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
|
||||||
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
0b1100u, 0b1101u, 0b1110u, 0b1111u)] uint cond) // GT, LE, AL, NV>
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5A800400; // CSNEG W0, W0, W0, EQ
|
uint opcode = 0x5A800400; // CSNEG W0, W0, W0, EQ
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= ((cond & 15) << 12);
|
opcode |= ((cond & 15) << 12);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[TestCase(0xFFFFFFFDu)] // Roots.
|
[TestCase(0xFFFFFFFDu)] // Roots.
|
||||||
[TestCase(0x00000005u)]
|
[TestCase(0x00000005u)]
|
||||||
public void Misc1(uint A)
|
public void Misc1(uint a)
|
||||||
{
|
{
|
||||||
// ((A + 3) * (A - 5)) / ((A + 5) * (A - 3)) = 0
|
// ((a + 3) * (a - 5)) / ((a + 5) * (a - 3)) = 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ADD W2, W0, 3
|
ADD W2, W0, 3
|
||||||
|
@ -27,7 +27,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
RET
|
RET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetThreadState(X0: A);
|
SetThreadState(x0: a);
|
||||||
Opcode(0x11000C02);
|
Opcode(0x11000C02);
|
||||||
Opcode(0x51001401);
|
Opcode(0x51001401);
|
||||||
Opcode(0x1B017C42);
|
Opcode(0x1B017C42);
|
||||||
|
@ -60,9 +60,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase( 12f, -3f)]
|
[TestCase( 12f, -3f)]
|
||||||
[TestCase( 12f, 6f)]
|
[TestCase( 12f, 6f)]
|
||||||
[TestCase( 20f, 5f)]
|
[TestCase( 20f, 5f)]
|
||||||
public void Misc2(float A, float B)
|
public void Misc2(float a, float b)
|
||||||
{
|
{
|
||||||
// 1 / ((1 / A + 1 / B) ^ 2) = 16
|
// 1 / ((1 / a + 1 / b) ^ 2) = 16
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FMOV S2, 1.0e+0
|
FMOV S2, 1.0e+0
|
||||||
|
@ -76,8 +76,8 @@ namespace Ryujinx.Tests.Cpu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetThreadState(
|
SetThreadState(
|
||||||
V0: Sse.SetScalarVector128(A),
|
v0: Sse.SetScalarVector128(a),
|
||||||
V1: Sse.SetScalarVector128(B));
|
v1: Sse.SetScalarVector128(b));
|
||||||
Opcode(0x1E2E1002);
|
Opcode(0x1E2E1002);
|
||||||
Opcode(0x1E201840);
|
Opcode(0x1E201840);
|
||||||
Opcode(0x1E211841);
|
Opcode(0x1E211841);
|
||||||
|
@ -109,9 +109,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase( 12d, -3d)]
|
[TestCase( 12d, -3d)]
|
||||||
[TestCase( 12d, 6d)]
|
[TestCase( 12d, 6d)]
|
||||||
[TestCase( 20d, 5d)]
|
[TestCase( 20d, 5d)]
|
||||||
public void Misc3(double A, double B)
|
public void Misc3(double a, double b)
|
||||||
{
|
{
|
||||||
// 1 / ((1 / A + 1 / B) ^ 2) = 16
|
// 1 / ((1 / a + 1 / b) ^ 2) = 16
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FMOV D2, 1.0e+0
|
FMOV D2, 1.0e+0
|
||||||
|
@ -125,8 +125,8 @@ namespace Ryujinx.Tests.Cpu
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetThreadState(
|
SetThreadState(
|
||||||
V0: Sse.StaticCast<double, float>(Sse2.SetScalarVector128(A)),
|
v0: Sse.StaticCast<double, float>(Sse2.SetScalarVector128(a)),
|
||||||
V1: Sse.StaticCast<double, float>(Sse2.SetScalarVector128(B)));
|
v1: Sse.StaticCast<double, float>(Sse2.SetScalarVector128(b)));
|
||||||
Opcode(0x1E6E1002);
|
Opcode(0x1E6E1002);
|
||||||
Opcode(0x1E601840);
|
Opcode(0x1E601840);
|
||||||
Opcode(0x1E611841);
|
Opcode(0x1E611841);
|
||||||
|
@ -141,25 +141,25 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MiscF([Range(0u, 92u, 1u)] uint A)
|
public void MiscF([Range(0u, 92u, 1u)] uint a)
|
||||||
{
|
{
|
||||||
ulong F_n(uint n)
|
ulong Fn(uint n)
|
||||||
{
|
{
|
||||||
ulong a = 0, b = 1, c;
|
ulong x = 0, y = 1, z;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
return a;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 2; i <= n; i++)
|
for (uint i = 2; i <= n; i++)
|
||||||
{
|
{
|
||||||
c = a + b;
|
z = x + y;
|
||||||
a = b;
|
x = y;
|
||||||
b = c;
|
y = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -186,7 +186,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
0x0000000000001050: RET
|
0x0000000000001050: RET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SetThreadState(X0: A);
|
SetThreadState(x0: a);
|
||||||
Opcode(0x2A0003E4);
|
Opcode(0x2A0003E4);
|
||||||
Opcode(0x340001C0);
|
Opcode(0x340001C0);
|
||||||
Opcode(0x7100041F);
|
Opcode(0x7100041F);
|
||||||
|
@ -210,13 +210,13 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode(0xD65F03C0);
|
Opcode(0xD65F03C0);
|
||||||
ExecuteOpcodes();
|
ExecuteOpcodes();
|
||||||
|
|
||||||
Assert.That(GetThreadState().X0, Is.EqualTo(F_n(A)));
|
Assert.That(GetThreadState().X0, Is.EqualTo(Fn(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void MiscR()
|
public void MiscR()
|
||||||
{
|
{
|
||||||
const ulong Result = 5;
|
const ulong result = 5;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
0x0000000000001000: MOV X0, #2
|
0x0000000000001000: MOV X0, #2
|
||||||
|
@ -233,7 +233,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode(0xD65F03C0);
|
Opcode(0xD65F03C0);
|
||||||
ExecuteOpcodes();
|
ExecuteOpcodes();
|
||||||
|
|
||||||
Assert.That(GetThreadState().X0, Is.EqualTo(Result));
|
Assert.That(GetThreadState().X0, Is.EqualTo(result));
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
|
@ -252,19 +252,19 @@ namespace Ryujinx.Tests.Cpu
|
||||||
Opcode(0xD65F03C0);
|
Opcode(0xD65F03C0);
|
||||||
ExecuteOpcodes();
|
ExecuteOpcodes();
|
||||||
|
|
||||||
Assert.That(GetThreadState().X0, Is.EqualTo(Result));
|
Assert.That(GetThreadState().X0, Is.EqualTo(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase( 0ul)]
|
[TestCase( 0ul)]
|
||||||
[TestCase( 1ul)]
|
[TestCase( 1ul)]
|
||||||
[TestCase( 2ul)]
|
[TestCase( 2ul)]
|
||||||
[TestCase(42ul)]
|
[TestCase(42ul)]
|
||||||
public void SanityCheck(ulong A)
|
public void SanityCheck(ulong a)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD503201F; // NOP
|
uint opcode = 0xD503201F; // NOP
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: A);
|
CpuThreadState threadState = SingleOpcode(opcode, x0: a);
|
||||||
|
|
||||||
Assert.That(ThreadState.X0, Is.EqualTo(A));
|
Assert.That(threadState.X0, Is.EqualTo(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,111 +1,109 @@
|
||||||
#define Mov
|
#define Mov
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Mov")] // Tested: second half of 2018.
|
[Category("Mov")]
|
||||||
public sealed class CpuTestMov : CpuTest
|
public sealed class CpuTestMov : CpuTest
|
||||||
{
|
{
|
||||||
#if Mov
|
#if Mov
|
||||||
private const int RndCntImm = 2;
|
private const int RndCntImm = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movk_64bit([Values(0u, 31u)] uint Rd,
|
public void Movk_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Random(RndCntImm)] ulong _Xd,
|
[Random(RndCntImm)] ulong xd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xF2800000; // MOVK X0, #0, LSL #0
|
uint opcode = 0xF2800000; // MOVK X0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _Xd, X31: _X31);
|
SingleOpcode(opcode, x0: xd, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVK <Wd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movk_32bit([Values(0u, 31u)] uint Rd,
|
public void Movk_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Random(RndCntImm)] uint _Wd,
|
[Random(RndCntImm)] uint wd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u)] uint shift)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x72800000; // MOVK W0, #0, LSL #0
|
uint opcode = 0x72800000; // MOVK W0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _Wd, X31: _W31);
|
SingleOpcode(opcode, x0: wd, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVN <Xd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movn_64bit([Values(0u, 31u)] uint Rd,
|
public void Movn_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x92800000; // MOVN X0, #0, LSL #0
|
uint opcode = 0x92800000; // MOVN X0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
SingleOpcode(opcode, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVN <Wd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movn_32bit([Values(0u, 31u)] uint Rd,
|
public void Movn_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u)] uint shift)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x12800000; // MOVN W0, #0, LSL #0
|
uint opcode = 0x12800000; // MOVN W0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
SingleOpcode(opcode, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVZ <Xd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movz_64bit([Values(0u, 31u)] uint Rd,
|
public void Movz_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u, 32u, 48u)] uint shift)
|
[Values(0u, 16u, 32u, 48u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
|
uint opcode = 0xD2800000; // MOVZ X0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _X31);
|
SingleOpcode(opcode, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
|
[Test, Pairwise, Description("MOVZ <Wd>, #<imm>{, LSL #<shift>}")]
|
||||||
public void Movz_32bit([Values(0u, 31u)] uint Rd,
|
public void Movz_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
[Values(0u, 65535u)] [Random(0u, 65535u, RndCntImm)] uint imm,
|
||||||
[Values(0u, 16u)] uint shift)
|
[Values(0u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x52800000; // MOVZ W0, #0, LSL #0
|
uint opcode = 0x52800000; // MOVZ W0, #0, LSL #0
|
||||||
Opcode |= ((Rd & 31) << 0);
|
opcode |= ((rd & 31) << 0);
|
||||||
Opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
opcode |= (((shift / 16) & 3) << 21) | ((imm & 65535) << 5);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _W31);
|
SingleOpcode(opcode, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,227 +1,225 @@
|
||||||
#define Mul
|
#define Mul
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Mul")] // Tested: second half of 2018.
|
[Category("Mul")]
|
||||||
public sealed class CpuTestMul : CpuTest
|
public sealed class CpuTestMul : CpuTest
|
||||||
{
|
{
|
||||||
#if Mul
|
#if Mul
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
[Test, Pairwise, Description("MADD <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||||
public void Madd_64bit([Values(0u, 31u)] uint Rd,
|
public void Madd_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B000000; // MADD X0, X0, X0, X0
|
uint opcode = 0x9B000000; // MADD X0, X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
|
[Test, Pairwise, Description("MADD <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||||
public void Madd_32bit([Values(0u, 31u)] uint Rd,
|
public void Madd_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1B000000; // MADD W0, W0, W0, W0
|
uint opcode = 0x1B000000; // MADD W0, W0, W0, W0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: wa, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
|
[Test, Pairwise, Description("MSUB <Xd>, <Xn>, <Xm>, <Xa>")]
|
||||||
public void Msub_64bit([Values(0u, 31u)] uint Rd,
|
public void Msub_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B008000; // MSUB X0, X0, X0, X0
|
uint opcode = 0x9B008000; // MSUB X0, X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
|
[Test, Pairwise, Description("MSUB <Wd>, <Wn>, <Wm>, <Wa>")]
|
||||||
public void Msub_32bit([Values(0u, 31u)] uint Rd,
|
public void Msub_32bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wa)
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1B008000; // MSUB W0, W0, W0, W0
|
uint opcode = 0x1B008000; // MSUB W0, W0, W0, W0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Wa, X31: _W31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: wa, x31: w31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
[Test, Pairwise, Description("SMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||||
public void Smaddl_64bit([Values(0u, 31u)] uint Rd,
|
public void Smaddl_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
|
uint opcode = 0x9B200000; // SMADDL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
[Test, Pairwise, Description("UMADDL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||||
public void Umaddl_64bit([Values(0u, 31u)] uint Rd,
|
public void Umaddl_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
|
uint opcode = 0x9BA00000; // UMADDL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
[Test, Pairwise, Description("SMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||||
public void Smsubl_64bit([Values(0u, 31u)] uint Rd,
|
public void Smsubl_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
|
uint opcode = 0x9B208000; // SMSUBL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
[Test, Pairwise, Description("UMSUBL <Xd>, <Wn>, <Wm>, <Xa>")]
|
||||||
public void Umsubl_64bit([Values(0u, 31u)] uint Rd,
|
public void Umsubl_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(3u, 31u)] uint Ra,
|
[Values(3u, 31u)] uint ra,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wn,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint Wm,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xa)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xa)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
|
uint opcode = 0x9BA08000; // UMSUBL X0, W0, W0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Ra & 31) << 10) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((ra & 31) << 10) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, X2: Wm, X3: Xa, X31: _X31);
|
SingleOpcode(opcode, x1: wn, x2: wm, x3: xa, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
[Test, Pairwise, Description("SMULH <Xd>, <Xn>, <Xm>")]
|
||||||
public void Smulh_64bit([Values(0u, 31u)] uint Rd,
|
public void Smulh_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9B407C00; // SMULH X0, X0, X0
|
uint opcode = 0x9B407C00; // SMULH X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
[Test, Pairwise, Description("UMULH <Xd>, <Xn>, <Xm>")]
|
||||||
public void Umulh_64bit([Values(0u, 31u)] uint Rd,
|
public void Umulh_64bit([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[Values(2u, 31u)] uint Rm,
|
[Values(2u, 31u)] uint rm,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xn,
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xn,
|
||||||
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
[Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
|
||||||
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong Xm)
|
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] [Random(RndCnt)] ulong xm)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x9BC07C00; // UMULH X0, X0, X0
|
uint opcode = 0x9BC07C00; // UMULH X0, X0, X0
|
||||||
Opcode |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, X2: Xm, X31: _X31);
|
SingleOpcode(opcode, x1: xn, x2: xm, x31: x31);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,15 +15,15 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0xC1200000u, 0xBDCC8000u)]
|
[TestCase(0xC1200000u, 0xBDCC8000u)]
|
||||||
[TestCase(0x001FFFFFu, 0x7F800000u)]
|
[TestCase(0x001FFFFFu, 0x7F800000u)]
|
||||||
[TestCase(0x007FF000u, 0x7E800000u)]
|
[TestCase(0x007FF000u, 0x7E800000u)]
|
||||||
public void Frecpe_S(uint A, uint Result)
|
public void Frecpe_S(uint a, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x5EA1D820; // FRECPE S0, S1
|
uint opcode = 0x5EA1D820; // FRECPE S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -66,21 +66,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frinta_S(uint A, bool DefaultNaN, uint Result)
|
public void Frinta_S(uint a, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
uint opcode = 0x1E264020; // FRINTA S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -97,22 +97,22 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x2E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frinta_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frinta_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
@ -158,28 +158,28 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frinti_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
public void Frinti_S(uint a, char roundMode, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E27C020; // FRINTI S0, S1
|
uint opcode = 0x1E27C020; // FRINTI S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(roundMode)
|
||||||
{
|
{
|
||||||
case 'N': FpcrTemp = 0x0; break;
|
case 'N': fpcrTemp = 0x0; break;
|
||||||
case 'P': FpcrTemp = 0x400000; break;
|
case 'P': fpcrTemp = 0x400000; break;
|
||||||
case 'M': FpcrTemp = 0x800000; break;
|
case 'M': fpcrTemp = 0x800000; break;
|
||||||
case 'Z': FpcrTemp = 0xC00000; break;
|
case 'Z': fpcrTemp = 0xC00000; break;
|
||||||
}
|
}
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
fpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -216,29 +216,29 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2EA19820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frinti_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frinti_V(uint opcode, ulong a, ulong b, char roundMode, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(roundMode)
|
||||||
{
|
{
|
||||||
case 'N': FpcrTemp = 0x0; break;
|
case 'N': fpcrTemp = 0x0; break;
|
||||||
case 'P': FpcrTemp = 0x400000; break;
|
case 'P': fpcrTemp = 0x400000; break;
|
||||||
case 'M': FpcrTemp = 0x800000; break;
|
case 'M': fpcrTemp = 0x800000; break;
|
||||||
case 'Z': FpcrTemp = 0xC00000; break;
|
case 'Z': fpcrTemp = 0xC00000; break;
|
||||||
}
|
}
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
fpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
@ -282,21 +282,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintm_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintm_S(uint a, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E254020; // FRINTM S0, S1
|
uint opcode = 0x1E254020; // FRINTM S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -309,22 +309,22 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E219820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frintm_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frintm_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
@ -369,21 +369,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintn_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintn_S(uint a, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E264020; // FRINTA S0, S1
|
uint opcode = 0x1E264020; // FRINTA S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -399,22 +399,22 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0E218820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0E218820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frintn_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frintn_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
@ -458,21 +458,21 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintp_S(uint A, bool DefaultNaN, uint Result)
|
public void Frintp_S(uint a, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E24C020; // FRINTP S0, S1
|
uint opcode = 0x1E24C020; // FRINTP S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -485,22 +485,22 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
[TestCase(0x0EA18820u, 0x7F800000FF800000ul, 0x0000000000000000ul, false, 0x7F800000FF800000ul, 0x0000000000000000ul)]
|
||||||
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, false, 0xFFC000017FC00002ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x0EA18820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frintp_V(uint Opcode, ulong A, ulong B, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frintp_V(uint opcode, ulong a, ulong b, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp = 0x2000000;
|
fpcrTemp = 0x2000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
|
@ -546,28 +546,28 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'P', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'M', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
[TestCase(0x7FC00002u, 'Z', true, 0x7FC00000u, Ignore = "NaN test.")]
|
||||||
public void Frintx_S(uint A, char RoundType, bool DefaultNaN, uint Result)
|
public void Frintx_S(uint a, char roundMode, bool defaultNaN, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x1E274020; // FRINTX S0, S1
|
uint opcode = 0x1E274020; // FRINTX S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(roundMode)
|
||||||
{
|
{
|
||||||
case 'N': FpcrTemp = 0x0; break;
|
case 'N': fpcrTemp = 0x0; break;
|
||||||
case 'P': FpcrTemp = 0x400000; break;
|
case 'P': fpcrTemp = 0x400000; break;
|
||||||
case 'M': FpcrTemp = 0x800000; break;
|
case 'M': fpcrTemp = 0x800000; break;
|
||||||
case 'Z': FpcrTemp = 0xC00000; break;
|
case 'Z': fpcrTemp = 0xC00000; break;
|
||||||
}
|
}
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
fpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
@ -604,44 +604,44 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'P', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'M', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
[TestCase(0x2E219820u, 0xFF8000017FC00002ul, 0x0000000000000000ul, 'Z', true, 0x7FC000007FC00000ul, 0x0000000000000000ul, Ignore = "NaN test.")]
|
||||||
public void Frintx_V(uint Opcode, ulong A, ulong B, char RoundType, bool DefaultNaN, ulong Result0, ulong Result1)
|
public void Frintx_V(uint opcode, ulong a, ulong b, char roundMode, bool defaultNaN, ulong result0, ulong result1)
|
||||||
{
|
{
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, B);
|
Vector128<float> v1 = MakeVectorE0E1(a, b);
|
||||||
|
|
||||||
int FpcrTemp = 0x0;
|
int fpcrTemp = 0x0;
|
||||||
switch(RoundType)
|
switch(roundMode)
|
||||||
{
|
{
|
||||||
case 'N': FpcrTemp = 0x0; break;
|
case 'N': fpcrTemp = 0x0; break;
|
||||||
case 'P': FpcrTemp = 0x400000; break;
|
case 'P': fpcrTemp = 0x400000; break;
|
||||||
case 'M': FpcrTemp = 0x800000; break;
|
case 'M': fpcrTemp = 0x800000; break;
|
||||||
case 'Z': FpcrTemp = 0xC00000; break;
|
case 'Z': fpcrTemp = 0xC00000; break;
|
||||||
}
|
}
|
||||||
if (DefaultNaN)
|
if (defaultNaN)
|
||||||
{
|
{
|
||||||
FpcrTemp |= 1 << 25;
|
fpcrTemp |= 1 << 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1, Fpcr: FpcrTemp);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1, fpcr: fpcrTemp);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result0));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result0));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(Result1));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(result1));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(0x41200000u, 0x3EA18000u)]
|
[TestCase(0x41200000u, 0x3EA18000u)]
|
||||||
public void Frsqrte_S(uint A, uint Result)
|
public void Frsqrte_S(uint a, uint result)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x7EA1D820; // FRSQRTE S0, S1
|
uint opcode = 0x7EA1D820; // FRSQRTE S0, S1
|
||||||
|
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V1: V1);
|
CpuThreadState threadState = SingleOpcode(opcode, v1: v1);
|
||||||
|
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(Result));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(result));
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,98 +11,98 @@ namespace Ryujinx.Tests.Cpu
|
||||||
public class CpuTestSimdCrypto : CpuTest
|
public class CpuTestSimdCrypto : CpuTest
|
||||||
{
|
{
|
||||||
[Test, Description("AESD <Vd>.16B, <Vn>.16B")]
|
[Test, Description("AESD <Vd>.16B, <Vn>.16B")]
|
||||||
public void Aesd_V([Values(0u)] uint Rd,
|
public void Aesd_V([Values(0u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[Values(0x7B5B546573745665ul)] ulong ValueH,
|
[Values(0x7B5B546573745665ul)] ulong valueH,
|
||||||
[Values(0x63746F725D53475Dul)] ulong ValueL,
|
[Values(0x63746F725D53475Dul)] ulong valueL,
|
||||||
[Random(2)] ulong RoundKeyH,
|
[Random(2)] ulong roundKeyH,
|
||||||
[Random(2)] ulong RoundKeyL,
|
[Random(2)] ulong roundKeyL,
|
||||||
[Values(0x8DCAB9BC035006BCul)] ulong ResultH,
|
[Values(0x8DCAB9BC035006BCul)] ulong resultH,
|
||||||
[Values(0x8F57161E00CAFD8Dul)] ulong ResultL)
|
[Values(0x8F57161E00CAFD8Dul)] ulong resultL)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E285800; // AESD V0.16B, V0.16B
|
uint opcode = 0x4E285800; // AESD V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
Vector128<float> v0 = MakeVectorE0E1(roundKeyL ^ valueL, roundKeyH ^ valueH);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
Vector128<float> v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
CpuThreadState threadState = SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(resultL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(resultH));
|
||||||
});
|
});
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
Assert.That(GetVectorE0(threadState.V1), Is.EqualTo(roundKeyL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
Assert.That(GetVectorE1(threadState.V1), Is.EqualTo(roundKeyH));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("AESE <Vd>.16B, <Vn>.16B")]
|
[Test, Description("AESE <Vd>.16B, <Vn>.16B")]
|
||||||
public void Aese_V([Values(0u)] uint Rd,
|
public void Aese_V([Values(0u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[Values(0x7B5B546573745665ul)] ulong ValueH,
|
[Values(0x7B5B546573745665ul)] ulong valueH,
|
||||||
[Values(0x63746F725D53475Dul)] ulong ValueL,
|
[Values(0x63746F725D53475Dul)] ulong valueL,
|
||||||
[Random(2)] ulong RoundKeyH,
|
[Random(2)] ulong roundKeyH,
|
||||||
[Random(2)] ulong RoundKeyL,
|
[Random(2)] ulong roundKeyL,
|
||||||
[Values(0x8F92A04DFBED204Dul)] ulong ResultH,
|
[Values(0x8F92A04DFBED204Dul)] ulong resultH,
|
||||||
[Values(0x4C39B1402192A84Cul)] ulong ResultL)
|
[Values(0x4C39B1402192A84Cul)] ulong resultL)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E284800; // AESE V0.16B, V0.16B
|
uint opcode = 0x4E284800; // AESE V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(RoundKeyL ^ ValueL, RoundKeyH ^ ValueH);
|
Vector128<float> v0 = MakeVectorE0E1(roundKeyL ^ valueL, roundKeyH ^ valueH);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(RoundKeyL, RoundKeyH);
|
Vector128<float> v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
CpuThreadState threadState = SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(resultL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(resultH));
|
||||||
});
|
});
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(RoundKeyL));
|
Assert.That(GetVectorE0(threadState.V1), Is.EqualTo(roundKeyL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(RoundKeyH));
|
Assert.That(GetVectorE1(threadState.V1), Is.EqualTo(roundKeyH));
|
||||||
});
|
});
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("AESIMC <Vd>.16B, <Vn>.16B")]
|
[Test, Description("AESIMC <Vd>.16B, <Vn>.16B")]
|
||||||
public void Aesimc_V([Values(0u)] uint Rd,
|
public void Aesimc_V([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(0x8DCAB9DC035006BCul)] ulong ValueH,
|
[Values(0x8DCAB9DC035006BCul)] ulong valueH,
|
||||||
[Values(0x8F57161E00CAFD8Dul)] ulong ValueL,
|
[Values(0x8F57161E00CAFD8Dul)] ulong valueL,
|
||||||
[Values(0xD635A667928B5EAEul)] ulong ResultH,
|
[Values(0xD635A667928B5EAEul)] ulong resultH,
|
||||||
[Values(0xEEC9CC3BC55F5777ul)] ulong ResultL)
|
[Values(0xEEC9CC3BC55F5777ul)] ulong resultL)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
|
uint opcode = 0x4E287800; // AESIMC V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
Vector128<float> v = MakeVectorE0E1(valueL, valueH);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(
|
CpuThreadState threadState = SingleOpcode(
|
||||||
Opcode,
|
opcode,
|
||||||
V0: Rn == 0u ? V : default(Vector128<float>),
|
v0: rn == 0u ? v : default(Vector128<float>),
|
||||||
V1: Rn == 1u ? V : default(Vector128<float>));
|
v1: rn == 1u ? v : default(Vector128<float>));
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(resultL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(resultH));
|
||||||
});
|
});
|
||||||
if (Rn == 1u)
|
if (rn == 1u)
|
||||||
{
|
{
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(ValueL));
|
Assert.That(GetVectorE0(threadState.V1), Is.EqualTo(valueL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
Assert.That(GetVectorE1(threadState.V1), Is.EqualTo(valueH));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,34 +110,34 @@ namespace Ryujinx.Tests.Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Description("AESMC <Vd>.16B, <Vn>.16B")]
|
[Test, Description("AESMC <Vd>.16B, <Vn>.16B")]
|
||||||
public void Aesmc_V([Values(0u)] uint Rd,
|
public void Aesmc_V([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(0x627A6F6644B109C8ul)] ulong ValueH,
|
[Values(0x627A6F6644B109C8ul)] ulong valueH,
|
||||||
[Values(0x2B18330A81C3B3E5ul)] ulong ValueL,
|
[Values(0x2B18330A81C3B3E5ul)] ulong valueL,
|
||||||
[Values(0x7B5B546573745665ul)] ulong ResultH,
|
[Values(0x7B5B546573745665ul)] ulong resultH,
|
||||||
[Values(0x63746F725D53475Dul)] ulong ResultL)
|
[Values(0x63746F725D53475Dul)] ulong resultL)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E286800; // AESMC V0.16B, V0.16B
|
uint opcode = 0x4E286800; // AESMC V0.16B, V0.16B
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
Vector128<float> V = MakeVectorE0E1(ValueL, ValueH);
|
Vector128<float> v = MakeVectorE0E1(valueL, valueH);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(
|
CpuThreadState threadState = SingleOpcode(
|
||||||
Opcode,
|
opcode,
|
||||||
V0: Rn == 0u ? V : default(Vector128<float>),
|
v0: rn == 0u ? v : default(Vector128<float>),
|
||||||
V1: Rn == 1u ? V : default(Vector128<float>));
|
v1: rn == 1u ? v : default(Vector128<float>));
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V0), Is.EqualTo(ResultL));
|
Assert.That(GetVectorE0(threadState.V0), Is.EqualTo(resultL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V0), Is.EqualTo(ResultH));
|
Assert.That(GetVectorE1(threadState.V0), Is.EqualTo(resultH));
|
||||||
});
|
});
|
||||||
if (Rn == 1u)
|
if (rn == 1u)
|
||||||
{
|
{
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(GetVectorE0(ThreadState.V1), Is.EqualTo(ValueL));
|
Assert.That(GetVectorE0(threadState.V1), Is.EqualTo(valueL));
|
||||||
Assert.That(GetVectorE1(ThreadState.V1), Is.EqualTo(ValueH));
|
Assert.That(GetVectorE1(threadState.V1), Is.EqualTo(valueH));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#define SimdIns
|
#define SimdIns
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdIns")] // Tested: second half of 2018.
|
[Category("SimdIns")]
|
||||||
public sealed class CpuTestSimdIns : CpuTest
|
public sealed class CpuTestSimdIns : CpuTest
|
||||||
{
|
{
|
||||||
#if SimdIns
|
#if SimdIns
|
||||||
|
@ -54,125 +52,125 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("DUP <Vd>.<T>, <R><n>")]
|
[Test, Pairwise, Description("DUP <Vd>.<T>, <R><n>")]
|
||||||
public void Dup_Gp_W([Values(0u)] uint Rd,
|
public void Dup_Gp_W([Values(0u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[ValueSource("_W_")] [Random(RndCnt)] uint Wn,
|
[ValueSource("_W_")] [Random(RndCnt)] uint wn,
|
||||||
[Values(0, 1, 2)] int Size, // Q0: <8B, 4H, 2S>
|
[Values(0, 1, 2)] int size, // Q0: <8B, 4H, 2S>
|
||||||
[Values(0b0u, 0b1u)] uint Q) // Q1: <16B, 8H, 4S>
|
[Values(0b0u, 0b1u)] uint q) // Q1: <16B, 8H, 4S>
|
||||||
{
|
{
|
||||||
uint Imm5 = (1u << Size) & 0x1Fu;
|
uint imm5 = (1u << size) & 0x1Fu;
|
||||||
|
|
||||||
uint Opcode = 0x0E000C00; // RESERVED
|
uint opcode = 0x0E000C00; // RESERVED
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (Imm5 << 16);
|
opcode |= (imm5 << 16);
|
||||||
Opcode |= ((Q & 1) << 30);
|
opcode |= ((q & 1) << 30);
|
||||||
|
|
||||||
ulong Z = TestContext.CurrentContext.Random.NextULong();
|
ulong z = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Wn, V0: V0);
|
SingleOpcode(opcode, x1: wn, v0: v0);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("DUP <Vd>.<T>, <R><n>")]
|
[Test, Pairwise, Description("DUP <Vd>.<T>, <R><n>")]
|
||||||
public void Dup_Gp_X([Values(0u)] uint Rd,
|
public void Dup_Gp_X([Values(0u)] uint rd,
|
||||||
[Values(1u, 31u)] uint Rn,
|
[Values(1u, 31u)] uint rn,
|
||||||
[ValueSource("_X_")] [Random(RndCnt)] ulong Xn)
|
[ValueSource("_X_")] [Random(RndCnt)] ulong xn)
|
||||||
{
|
{
|
||||||
uint Opcode = 0x4E080C00; // DUP V0.2D, X0
|
uint opcode = 0x4E080C00; // DUP V0.2D, X0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
|
|
||||||
ulong Z = TestContext.CurrentContext.Random.NextULong();
|
ulong z = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X1: Xn, V0: V0);
|
SingleOpcode(opcode, x1: xn, v0: v0);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SMOV <Wd>, <Vn>.<Ts>[<index>]")]
|
[Test, Pairwise, Description("SMOV <Wd>, <Vn>.<Ts>[<index>]")]
|
||||||
public void Smov_S_W([Values(0u, 31u)] uint Rd,
|
public void Smov_S_W([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[ValueSource("_8B4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_8B4H_")] [Random(RndCnt)] ulong a,
|
||||||
[Values(0, 1)] int Size, // <B, H>
|
[Values(0, 1)] int size, // <B, H>
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index)
|
[Values(0u, 1u, 2u, 3u)] uint index)
|
||||||
{
|
{
|
||||||
uint Imm5 = (Index << (Size + 1) | 1u << Size) & 0x1Fu;
|
uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
|
||||||
|
|
||||||
uint Opcode = 0x0E002C00; // RESERVED
|
uint opcode = 0x0E002C00; // RESERVED
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (Imm5 << 16);
|
opcode |= (imm5 << 16);
|
||||||
|
|
||||||
ulong _X0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
|
ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _X0, X31: _W31, V1: V1);
|
SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SMOV <Xd>, <Vn>.<Ts>[<index>]")]
|
[Test, Pairwise, Description("SMOV <Xd>, <Vn>.<Ts>[<index>]")]
|
||||||
public void Smov_S_X([Values(0u, 31u)] uint Rd,
|
public void Smov_S_X([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Values(0, 1, 2)] int Size, // <B, H, S>
|
[Values(0, 1, 2)] int size, // <B, H, S>
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint Imm5 = (Index << (Size + 1) | 1u << Size) & 0x1Fu;
|
uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
|
||||||
|
|
||||||
uint Opcode = 0x4E002C00; // RESERVED
|
uint opcode = 0x4E002C00; // RESERVED
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (Imm5 << 16);
|
opcode |= (imm5 << 16);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _X31, V1: V1);
|
SingleOpcode(opcode, x31: x31, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UMOV <Wd>, <Vn>.<Ts>[<index>]")]
|
[Test, Pairwise, Description("UMOV <Wd>, <Vn>.<Ts>[<index>]")]
|
||||||
public void Umov_S_W([Values(0u, 31u)] uint Rd,
|
public void Umov_S_W([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_8B4H2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Values(0, 1, 2)] int Size, // <B, H, S>
|
[Values(0, 1, 2)] int size, // <B, H, S>
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint Imm5 = (Index << (Size + 1) | 1u << Size) & 0x1Fu;
|
uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
|
||||||
|
|
||||||
uint Opcode = 0x0E003C00; // RESERVED
|
uint opcode = 0x0E003C00; // RESERVED
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (Imm5 << 16);
|
opcode |= (imm5 << 16);
|
||||||
|
|
||||||
ulong _X0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
|
ulong x0 = (ulong)TestContext.CurrentContext.Random.NextUInt() << 32;
|
||||||
uint _W31 = TestContext.CurrentContext.Random.NextUInt();
|
uint w31 = TestContext.CurrentContext.Random.NextUInt();
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X0: _X0, X31: _W31, V1: V1);
|
SingleOpcode(opcode, x0: x0, x31: w31, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("UMOV <Xd>, <Vn>.<Ts>[<index>]")]
|
[Test, Pairwise, Description("UMOV <Xd>, <Vn>.<Ts>[<index>]")]
|
||||||
public void Umov_S_X([Values(0u, 31u)] uint Rd,
|
public void Umov_S_X([Values(0u, 31u)] uint rd,
|
||||||
[Values(1u)] uint Rn,
|
[Values(1u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Values(3)] int Size, // <D>
|
[Values(3)] int size, // <D>
|
||||||
[Values(0u)] uint Index)
|
[Values(0u)] uint index)
|
||||||
{
|
{
|
||||||
uint Imm5 = (Index << (Size + 1) | 1u << Size) & 0x1Fu;
|
uint imm5 = (index << (size + 1) | 1u << size) & 0x1Fu;
|
||||||
|
|
||||||
uint Opcode = 0x4E003C00; // RESERVED
|
uint opcode = 0x4E003C00; // RESERVED
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (Imm5 << 16);
|
opcode |= (imm5 << 16);
|
||||||
|
|
||||||
ulong _X31 = TestContext.CurrentContext.Random.NextULong();
|
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, X31: _X31, V1: V1);
|
SingleOpcode(opcode, x31: x31, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,14 +1,12 @@
|
||||||
#define SimdRegElem
|
#define SimdRegElem
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdRegElem")] // Tested: second half of 2018.
|
[Category("SimdRegElem")]
|
||||||
public sealed class CpuTestSimdRegElem : CpuTest
|
public sealed class CpuTestSimdRegElem : CpuTest
|
||||||
{
|
{
|
||||||
#if SimdRegElem
|
#if SimdRegElem
|
||||||
|
@ -52,56 +50,56 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void Mla_Mls_Mul_Ve_4H_8H([ValueSource("_Mla_Mls_Mul_Ve_4H_8H_")] uint Opcodes,
|
public void Mla_Mls_Mul_Ve_4H_8H([ValueSource("_Mla_Mls_Mul_Ve_4H_8H_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong a,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong B,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint Index,
|
[Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint index,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <4H, 8H>
|
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
|
||||||
{
|
{
|
||||||
uint H = (Index >> 2) & 1;
|
uint h = (index >> 2) & 1;
|
||||||
uint L = (Index >> 1) & 1;
|
uint l = (index >> 1) & 1;
|
||||||
uint M = Index & 1;
|
uint m = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (L << 21) | (M << 20) | (H << 11);
|
opcodes |= (l << 21) | (m << 20) | (h << 11);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void Mla_Mls_Mul_Ve_2S_4S([ValueSource("_Mla_Mls_Mul_Ve_2S_4S_")] uint Opcodes,
|
public void Mla_Mls_Mul_Ve_2S_4S([ValueSource("_Mla_Mls_Mul_Ve_2S_4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong a,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong B,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index,
|
[Values(0u, 1u, 2u, 3u)] uint index,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
|
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
|
||||||
{
|
{
|
||||||
uint H = (Index >> 1) & 1;
|
uint h = (index >> 1) & 1;
|
||||||
uint L = Index & 1;
|
uint l = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 15) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 15) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (L << 21) | (H << 11);
|
opcodes |= (l << 21) | (h << 11);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#define SimdRegElemF
|
#define SimdRegElemF
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -9,7 +7,7 @@ using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdRegElemF")] // Tested: second half of 2018.
|
[Category("SimdRegElemF")]
|
||||||
public sealed class CpuTestSimdRegElemF : CpuTest
|
public sealed class CpuTestSimdRegElemF : CpuTest
|
||||||
{
|
{
|
||||||
#if SimdRegElemF
|
#if SimdRegElemF
|
||||||
|
@ -46,14 +44,14 @@ namespace Ryujinx.Tests.Cpu
|
||||||
yield return 0x000000007FBFFFFFul; // +SNaN (all ones payload)
|
yield return 0x000000007FBFFFFFul; // +SNaN (all ones payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int Cnt = 1; Cnt <= RndCnt; Cnt++)
|
for (int cnt = 1; cnt <= RndCnt; cnt++)
|
||||||
{
|
{
|
||||||
ulong Grbg = TestContext.CurrentContext.Random.NextUInt();
|
ulong grbg = TestContext.CurrentContext.Random.NextUInt();
|
||||||
ulong Rnd1 = GenNormal_S();
|
ulong rnd1 = GenNormalS();
|
||||||
ulong Rnd2 = GenSubnormal_S();
|
ulong rnd2 = GenSubnormalS();
|
||||||
|
|
||||||
yield return (Grbg << 32) | Rnd1;
|
yield return (grbg << 32) | rnd1;
|
||||||
yield return (Grbg << 32) | Rnd2;
|
yield return (grbg << 32) | rnd2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,13 +86,13 @@ namespace Ryujinx.Tests.Cpu
|
||||||
yield return 0x7FBFFFFF7FBFFFFFul; // +SNaN (all ones payload)
|
yield return 0x7FBFFFFF7FBFFFFFul; // +SNaN (all ones payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int Cnt = 1; Cnt <= RndCnt; Cnt++)
|
for (int cnt = 1; cnt <= RndCnt; cnt++)
|
||||||
{
|
{
|
||||||
ulong Rnd1 = GenNormal_S();
|
ulong rnd1 = GenNormalS();
|
||||||
ulong Rnd2 = GenSubnormal_S();
|
ulong rnd2 = GenSubnormalS();
|
||||||
|
|
||||||
yield return (Rnd1 << 32) | Rnd1;
|
yield return (rnd1 << 32) | rnd1;
|
||||||
yield return (Rnd2 << 32) | Rnd2;
|
yield return (rnd2 << 32) | rnd2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,13 +127,13 @@ namespace Ryujinx.Tests.Cpu
|
||||||
yield return 0x7FF7FFFFFFFFFFFFul; // +SNaN (all ones payload)
|
yield return 0x7FF7FFFFFFFFFFFFul; // +SNaN (all ones payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int Cnt = 1; Cnt <= RndCnt; Cnt++)
|
for (int cnt = 1; cnt <= RndCnt; cnt++)
|
||||||
{
|
{
|
||||||
ulong Rnd1 = GenNormal_D();
|
ulong rnd1 = GenNormalD();
|
||||||
ulong Rnd2 = GenSubnormal_D();
|
ulong rnd2 = GenSubnormalD();
|
||||||
|
|
||||||
yield return Rnd1;
|
yield return rnd1;
|
||||||
yield return Rnd2;
|
yield return rnd2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -221,203 +219,227 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private static readonly bool NoNaNs = false;
|
private static readonly bool NoNaNs = false;
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit] // Fused.
|
[Test, Pairwise] [Explicit] // Fused.
|
||||||
public void F_Mla_Mls_Se_S([ValueSource("_F_Mla_Mls_Se_S_")] uint Opcodes,
|
public void F_Mla_Mls_Se_S([ValueSource("_F_Mla_Mls_Se_S_")] uint opcodes,
|
||||||
[ValueSource("_1S_F_")] ulong Z,
|
[ValueSource("_1S_F_")] ulong z,
|
||||||
[ValueSource("_1S_F_")] ulong A,
|
[ValueSource("_1S_F_")] ulong a,
|
||||||
[ValueSource("_2S_F_")] ulong B,
|
[ValueSource("_2S_F_")] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index)
|
[Values(0u, 1u, 2u, 3u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = (Index >> 1) & 1;
|
uint h = (index >> 1) & 1;
|
||||||
uint L = Index & 1;
|
uint l = index & 1;
|
||||||
|
|
||||||
Opcodes |= (L << 21) | (H << 11);
|
opcodes |= (l << 21) | (h << 11);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FPSR.IOC, FpSkips.IfUnderflow, FpTolerances.UpToOneUlps_S);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsS);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit] // Fused.
|
[Test, Pairwise] [Explicit] // Fused.
|
||||||
public void F_Mla_Mls_Se_D([ValueSource("_F_Mla_Mls_Se_D_")] uint Opcodes,
|
public void F_Mla_Mls_Se_D([ValueSource("_F_Mla_Mls_Se_D_")] uint opcodes,
|
||||||
[ValueSource("_1D_F_")] ulong Z,
|
[ValueSource("_1D_F_")] ulong z,
|
||||||
[ValueSource("_1D_F_")] ulong A,
|
[ValueSource("_1D_F_")] ulong a,
|
||||||
[ValueSource("_1D_F_")] ulong B,
|
[ValueSource("_1D_F_")] ulong b,
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = Index & 1;
|
uint h = index & 1;
|
||||||
|
|
||||||
Opcodes |= H << 11;
|
opcodes |= h << 11;
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FPSR.IOC, FpSkips.IfUnderflow, FpTolerances.UpToOneUlps_D);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsD);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit] // Fused.
|
[Test, Pairwise] [Explicit] // Fused.
|
||||||
public void F_Mla_Mls_Ve_2S_4S([ValueSource("_F_Mla_Mls_Ve_2S_4S_")] uint Opcodes,
|
public void F_Mla_Mls_Ve_2S_4S([ValueSource("_F_Mla_Mls_Ve_2S_4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_2S_F_")] ulong Z,
|
[ValueSource("_2S_F_")] ulong z,
|
||||||
[ValueSource("_2S_F_")] ulong A,
|
[ValueSource("_2S_F_")] ulong a,
|
||||||
[ValueSource("_2S_F_")] ulong B,
|
[ValueSource("_2S_F_")] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index,
|
[Values(0u, 1u, 2u, 3u)] uint index,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
|
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
|
||||||
{
|
{
|
||||||
uint H = (Index >> 1) & 1;
|
uint h = (index >> 1) & 1;
|
||||||
uint L = Index & 1;
|
uint l = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (L << 21) | (H << 11);
|
opcodes |= (l << 21) | (h << 11);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FPSR.IOC, FpSkips.IfUnderflow, FpTolerances.UpToOneUlps_S);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsS);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit] // Fused.
|
[Test, Pairwise] [Explicit] // Fused.
|
||||||
public void F_Mla_Mls_Ve_2D([ValueSource("_F_Mla_Mls_Ve_2D_")] uint Opcodes,
|
public void F_Mla_Mls_Ve_2D([ValueSource("_F_Mla_Mls_Ve_2D_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_1D_F_")] ulong Z,
|
[ValueSource("_1D_F_")] ulong z,
|
||||||
[ValueSource("_1D_F_")] ulong A,
|
[ValueSource("_1D_F_")] ulong a,
|
||||||
[ValueSource("_1D_F_")] ulong B,
|
[ValueSource("_1D_F_")] ulong b,
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = Index & 1;
|
uint h = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= H << 11;
|
opcodes |= h << 11;
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FPSR.IOC, FpSkips.IfUnderflow, FpTolerances.UpToOneUlps_D);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsD);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit]
|
[Test, Pairwise] [Explicit]
|
||||||
public void F_Mul_Mulx_Se_S([ValueSource("_F_Mul_Mulx_Se_S_")] uint Opcodes,
|
public void F_Mul_Mulx_Se_S([ValueSource("_F_Mul_Mulx_Se_S_")] uint opcodes,
|
||||||
[ValueSource("_1S_F_")] ulong A,
|
[ValueSource("_1S_F_")] ulong a,
|
||||||
[ValueSource("_2S_F_")] ulong B,
|
[ValueSource("_2S_F_")] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index)
|
[Values(0u, 1u, 2u, 3u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = (Index >> 1) & 1;
|
uint h = (index >> 1) & 1;
|
||||||
uint L = Index & 1;
|
uint l = index & 1;
|
||||||
|
|
||||||
Opcodes |= (L << 21) | (H << 11);
|
opcodes |= (l << 21) | (h << 11);
|
||||||
|
|
||||||
ulong Z = TestContext.CurrentContext.Random.NextULong();
|
ulong z = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.IOC);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit]
|
[Test, Pairwise] [Explicit]
|
||||||
public void F_Mul_Mulx_Se_D([ValueSource("_F_Mul_Mulx_Se_D_")] uint Opcodes,
|
public void F_Mul_Mulx_Se_D([ValueSource("_F_Mul_Mulx_Se_D_")] uint opcodes,
|
||||||
[ValueSource("_1D_F_")] ulong A,
|
[ValueSource("_1D_F_")] ulong a,
|
||||||
[ValueSource("_1D_F_")] ulong B,
|
[ValueSource("_1D_F_")] ulong b,
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = Index & 1;
|
uint h = index & 1;
|
||||||
|
|
||||||
Opcodes |= H << 11;
|
opcodes |= h << 11;
|
||||||
|
|
||||||
ulong Z = TestContext.CurrentContext.Random.NextULong();
|
ulong z = TestContext.CurrentContext.Random.NextULong();
|
||||||
Vector128<float> V0 = MakeVectorE1(Z);
|
Vector128<float> v0 = MakeVectorE1(z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.IOC);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit]
|
[Test, Pairwise] [Explicit]
|
||||||
public void F_Mul_Mulx_Ve_2S_4S([ValueSource("_F_Mul_Mulx_Ve_2S_4S_")] uint Opcodes,
|
public void F_Mul_Mulx_Ve_2S_4S([ValueSource("_F_Mul_Mulx_Ve_2S_4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_2S_F_")] ulong Z,
|
[ValueSource("_2S_F_")] ulong z,
|
||||||
[ValueSource("_2S_F_")] ulong A,
|
[ValueSource("_2S_F_")] ulong a,
|
||||||
[ValueSource("_2S_F_")] ulong B,
|
[ValueSource("_2S_F_")] ulong b,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint Index,
|
[Values(0u, 1u, 2u, 3u)] uint index,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
|
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
|
||||||
{
|
{
|
||||||
uint H = (Index >> 1) & 1;
|
uint h = (index >> 1) & 1;
|
||||||
uint L = Index & 1;
|
uint l = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (L << 21) | (H << 11);
|
opcodes |= (l << 21) | (h << 11);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.IOC);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise] [Explicit]
|
[Test, Pairwise] [Explicit]
|
||||||
public void F_Mul_Mulx_Ve_2D([ValueSource("_F_Mul_Mulx_Ve_2D_")] uint Opcodes,
|
public void F_Mul_Mulx_Ve_2D([ValueSource("_F_Mul_Mulx_Ve_2D_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[Values(2u, 0u)] uint Rm,
|
[Values(2u, 0u)] uint rm,
|
||||||
[ValueSource("_1D_F_")] ulong Z,
|
[ValueSource("_1D_F_")] ulong z,
|
||||||
[ValueSource("_1D_F_")] ulong A,
|
[ValueSource("_1D_F_")] ulong a,
|
||||||
[ValueSource("_1D_F_")] ulong B,
|
[ValueSource("_1D_F_")] ulong b,
|
||||||
[Values(0u, 1u)] uint Index)
|
[Values(0u, 1u)] uint index)
|
||||||
{
|
{
|
||||||
uint H = Index & 1;
|
uint h = index & 1;
|
||||||
|
|
||||||
Opcodes |= ((Rm & 31) << 16) | ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rm & 31) << 16) | ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= H << 11;
|
opcodes |= h << 11;
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
Vector128<float> V2 = MakeVectorE0E1(B, B * H);
|
Vector128<float> v2 = MakeVectorE0E1(b, b * h);
|
||||||
|
|
||||||
int Fpcr = (int)TestContext.CurrentContext.Random.NextUInt() & (1 << (int)FPCR.DN);
|
int rnd = (int)TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1, V2: V2, Fpcr: Fpcr);
|
int fpcr = rnd & (1 << (int)Fpcr.Fz);
|
||||||
|
fpcr |= rnd & (1 << (int)Fpcr.Dn);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.IOC);
|
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, fpcr: fpcr);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#define SimdShImm
|
#define SimdShImm
|
||||||
|
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
using System.Runtime.Intrinsics;
|
using System.Runtime.Intrinsics;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdShImm")] // Tested: second half of 2018.
|
[Category("SimdShImm")]
|
||||||
public sealed class CpuTestSimdShImm : CpuTest
|
public sealed class CpuTestSimdShImm : CpuTest
|
||||||
{
|
{
|
||||||
#if SimdShImm
|
#if SimdShImm
|
||||||
|
@ -236,426 +234,426 @@ namespace Ryujinx.Tests.Cpu
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("SHL <V><d>, <V><n>, #<shift>")]
|
[Test, Pairwise, Description("SHL <V><d>, <V><n>, #<shift>")]
|
||||||
public void Shl_S_D([Values(0u)] uint Rd,
|
public void Shl_S_D([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(0u, 63u)] uint Shift)
|
[Range(0u, 63u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 + Shift) & 0x7F;
|
uint immHb = (64 + shift) & 0x7F;
|
||||||
|
|
||||||
uint Opcode = 0x5F405400; // SHL D0, D0, #0
|
uint opcode = 0x5F405400; // SHL D0, D0, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (ImmHB << 16);
|
opcode |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
||||||
public void Shl_V_8B_16B([Values(0u)] uint Rd,
|
public void Shl_V_8B_16B([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_8B_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_8B_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_8B_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(0u, 7u)] uint Shift,
|
[Range(0u, 7u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <8B, 16B>
|
[Values(0b0u, 0b1u)] uint q) // <8B, 16B>
|
||||||
{
|
{
|
||||||
uint ImmHB = (8 + Shift) & 0x7F;
|
uint immHb = (8 + shift) & 0x7F;
|
||||||
|
|
||||||
uint Opcode = 0x0F085400; // SHL V0.8B, V0.8B, #0
|
uint opcode = 0x0F085400; // SHL V0.8B, V0.8B, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (ImmHB << 16);
|
opcode |= (immHb << 16);
|
||||||
Opcode |= ((Q & 1) << 30);
|
opcode |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
||||||
public void Shl_V_4H_8H([Values(0u)] uint Rd,
|
public void Shl_V_4H_8H([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(0u, 15u)] uint Shift,
|
[Range(0u, 15u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <4H, 8H>
|
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
|
||||||
{
|
{
|
||||||
uint ImmHB = (16 + Shift) & 0x7F;
|
uint immHb = (16 + shift) & 0x7F;
|
||||||
|
|
||||||
uint Opcode = 0x0F105400; // SHL V0.4H, V0.4H, #0
|
uint opcode = 0x0F105400; // SHL V0.4H, V0.4H, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (ImmHB << 16);
|
opcode |= (immHb << 16);
|
||||||
Opcode |= ((Q & 1) << 30);
|
opcode |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
||||||
public void Shl_V_2S_4S([Values(0u)] uint Rd,
|
public void Shl_V_2S_4S([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(0u, 31u)] uint Shift,
|
[Range(0u, 31u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
|
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
|
||||||
{
|
{
|
||||||
uint ImmHB = (32 + Shift) & 0x7F;
|
uint immHb = (32 + shift) & 0x7F;
|
||||||
|
|
||||||
uint Opcode = 0x0F205400; // SHL V0.2S, V0.2S, #0
|
uint opcode = 0x0F205400; // SHL V0.2S, V0.2S, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (ImmHB << 16);
|
opcode |= (immHb << 16);
|
||||||
Opcode |= ((Q & 1) << 30);
|
opcode |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
[Test, Pairwise, Description("SHL <Vd>.<T>, <Vn>.<T>, #<shift>")]
|
||||||
public void Shl_V_2D([Values(0u)] uint Rd,
|
public void Shl_V_2D([Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(0u, 63u)] uint Shift)
|
[Range(0u, 63u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 + Shift) & 0x7F;
|
uint immHb = (64 + shift) & 0x7F;
|
||||||
|
|
||||||
uint Opcode = 0x4F405400; // SHL V0.2D, V0.2D, #0
|
uint opcode = 0x4F405400; // SHL V0.2D, V0.2D, #0
|
||||||
Opcode |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcode |= (ImmHB << 16);
|
opcode |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1);
|
SingleOpcode(opcode, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImm_S_D([ValueSource("_ShrImm_S_D_")] uint Opcodes,
|
public void ShrImm_S_D([ValueSource("_ShrImm_S_D_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 64u)] uint Shift)
|
[Range(1u, 64u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (128 - Shift) & 0x7F;
|
uint immHb = (128 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImm_V_8B_16B([ValueSource("_ShrImm_V_8B_16B_")] uint Opcodes,
|
public void ShrImm_V_8B_16B([ValueSource("_ShrImm_V_8B_16B_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_8B_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_8B_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_8B_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_8B_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 8u)] uint Shift,
|
[Range(1u, 8u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <8B, 16B>
|
[Values(0b0u, 0b1u)] uint q) // <8B, 16B>
|
||||||
{
|
{
|
||||||
uint ImmHB = (16 - Shift) & 0x7F;
|
uint immHb = (16 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImm_V_4H_8H([ValueSource("_ShrImm_V_4H_8H_")] uint Opcodes,
|
public void ShrImm_V_4H_8H([ValueSource("_ShrImm_V_4H_8H_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 16u)] uint Shift,
|
[Range(1u, 16u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <4H, 8H>
|
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
|
||||||
{
|
{
|
||||||
uint ImmHB = (32 - Shift) & 0x7F;
|
uint immHb = (32 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImm_V_2S_4S([ValueSource("_ShrImm_V_2S_4S_")] uint Opcodes,
|
public void ShrImm_V_2S_4S([ValueSource("_ShrImm_V_2S_4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 32u)] uint Shift,
|
[Range(1u, 32u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2S, 4S>
|
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 - Shift) & 0x7F;
|
uint immHb = (64 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A * Q);
|
Vector128<float> v1 = MakeVectorE0E1(a, a * q);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImm_V_2D([ValueSource("_ShrImm_V_2D_")] uint Opcodes,
|
public void ShrImm_V_2D([ValueSource("_ShrImm_V_2D_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 64u)] uint Shift)
|
[Range(1u, 64u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (128 - Shift) & 0x7F;
|
uint immHb = (128 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmNarrow_V_8H8B_8H16B([ValueSource("_ShrImmNarrow_V_8H8B_8H16B_")] uint Opcodes,
|
public void ShrImmNarrow_V_8H8B_8H16B([ValueSource("_ShrImmNarrow_V_8H8B_8H16B_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 8u)] uint Shift,
|
[Range(1u, 8u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <8H8B, 8H16B>
|
[Values(0b0u, 0b1u)] uint q) // <8H8B, 8H16B>
|
||||||
{
|
{
|
||||||
uint ImmHB = (16 - Shift) & 0x7F;
|
uint immHb = (16 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmNarrow_V_4S4H_4S8H([ValueSource("_ShrImmNarrow_V_4S4H_4S8H_")] uint Opcodes,
|
public void ShrImmNarrow_V_4S4H_4S8H([ValueSource("_ShrImmNarrow_V_4S4H_4S8H_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 16u)] uint Shift,
|
[Range(1u, 16u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <4S4H, 4S8H>
|
[Values(0b0u, 0b1u)] uint q) // <4S4H, 4S8H>
|
||||||
{
|
{
|
||||||
uint ImmHB = (32 - Shift) & 0x7F;
|
uint immHb = (32 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmNarrow_V_2D2S_2D4S([ValueSource("_ShrImmNarrow_V_2D2S_2D4S_")] uint Opcodes,
|
public void ShrImmNarrow_V_2D2S_2D4S([ValueSource("_ShrImmNarrow_V_2D2S_2D4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 32u)] uint Shift,
|
[Range(1u, 32u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2D2S, 2D4S>
|
[Values(0b0u, 0b1u)] uint q) // <2D2S, 2D4S>
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 - Shift) & 0x7F;
|
uint immHb = (64 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0E1(A, A);
|
Vector128<float> v1 = MakeVectorE0E1(a, a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_S_HB([ValueSource("_ShrImmSaturatingNarrow_S_HB_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_S_HB([ValueSource("_ShrImmSaturatingNarrow_S_HB_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1H_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 8u)] uint Shift)
|
[Range(1u, 8u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (16 - Shift) & 0x7F;
|
uint immHb = (16 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_S_SH([ValueSource("_ShrImmSaturatingNarrow_S_SH_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_S_SH([ValueSource("_ShrImmSaturatingNarrow_S_SH_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1S_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 16u)] uint Shift)
|
[Range(1u, 16u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (32 - Shift) & 0x7F;
|
uint immHb = (32 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_S_DS([ValueSource("_ShrImmSaturatingNarrow_S_DS_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_S_DS([ValueSource("_ShrImmSaturatingNarrow_S_DS_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 32u)] uint Shift)
|
[Range(1u, 32u)] uint shift)
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 - Shift) & 0x7F;
|
uint immHb = (64 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_V_8H8B_8H16B([ValueSource("_ShrImmSaturatingNarrow_V_8H8B_8H16B_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_V_8H8B_8H16B([ValueSource("_ShrImmSaturatingNarrow_V_8H8B_8H16B_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_4H_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_4H_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 8u)] uint Shift,
|
[Range(1u, 8u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <8H8B, 8H16B>
|
[Values(0b0u, 0b1u)] uint q) // <8H8B, 8H16B>
|
||||||
{
|
{
|
||||||
uint ImmHB = (16 - Shift) & 0x7F;
|
uint immHb = (16 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_V_4S4H_4S8H([ValueSource("_ShrImmSaturatingNarrow_V_4S4H_4S8H_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_V_4S4H_4S8H([ValueSource("_ShrImmSaturatingNarrow_V_4S4H_4S8H_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_2S_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_2S_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 16u)] uint Shift,
|
[Range(1u, 16u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <4S4H, 4S8H>
|
[Values(0b0u, 0b1u)] uint q) // <4S4H, 4S8H>
|
||||||
{
|
{
|
||||||
uint ImmHB = (32 - Shift) & 0x7F;
|
uint immHb = (32 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void ShrImmSaturatingNarrow_V_2D2S_2D4S([ValueSource("_ShrImmSaturatingNarrow_V_2D2S_2D4S_")] uint Opcodes,
|
public void ShrImmSaturatingNarrow_V_2D2S_2D4S([ValueSource("_ShrImmSaturatingNarrow_V_2D2S_2D4S_")] uint opcodes,
|
||||||
[Values(0u)] uint Rd,
|
[Values(0u)] uint rd,
|
||||||
[Values(1u, 0u)] uint Rn,
|
[Values(1u, 0u)] uint rn,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong Z,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong z,
|
||||||
[ValueSource("_1D_")] [Random(RndCnt)] ulong A,
|
[ValueSource("_1D_")] [Random(RndCnt)] ulong a,
|
||||||
[Range(1u, 32u)] uint Shift,
|
[Range(1u, 32u)] uint shift,
|
||||||
[Values(0b0u, 0b1u)] uint Q) // <2D2S, 2D4S>
|
[Values(0b0u, 0b1u)] uint q) // <2D2S, 2D4S>
|
||||||
{
|
{
|
||||||
uint ImmHB = (64 - Shift) & 0x7F;
|
uint immHb = (64 - shift) & 0x7F;
|
||||||
|
|
||||||
Opcodes |= ((Rn & 31) << 5) | ((Rd & 31) << 0);
|
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
|
||||||
Opcodes |= (ImmHB << 16);
|
opcodes |= (immHb << 16);
|
||||||
Opcodes |= ((Q & 1) << 30);
|
opcodes |= ((q & 1) << 30);
|
||||||
|
|
||||||
Vector128<float> V0 = MakeVectorE0E1(Z, Z);
|
Vector128<float> v0 = MakeVectorE0E1(z, z);
|
||||||
Vector128<float> V1 = MakeVectorE0(A);
|
Vector128<float> v1 = MakeVectorE0(a);
|
||||||
|
|
||||||
CpuThreadState ThreadState = SingleOpcode(Opcodes, V0: V0, V1: V1);
|
SingleOpcode(opcodes, v0: v0, v1: v1);
|
||||||
|
|
||||||
CompareAgainstUnicorn(FpsrMask: FPSR.QC);
|
CompareAgainstUnicorn(fpsrMask: Fpsr.Qc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue