Address Feedback from LDj3SNuD

Opcode table reordered to have alphabetical sorting within groups,
Vmaxnm and Vminnm have split names to be less ambiguous, SoftFloat nits,
Test nits and Test simplification with ValueSource.
This commit is contained in:
riperiperi 2020-02-13 22:26:09 +00:00
commit ea6fc47fac
11 changed files with 168 additions and 407 deletions

View file

@ -73,23 +73,6 @@
return (imm, size);
}
public static long VFPExpandImm(long imm, int n)
{
int e = (n == 16) ? 5 : ((n == 32) ? 8 : 11);
int f = (n) * 8 - e - 1;
long sign = (imm & 0x80) << (n - 8);
var bit6 = (imm >> 6) & 0x1;
long exp = ((imm >> 4) & 0x3);
if (bit6 == 1) exp |= ShlOnes(0, e - 3) << 2;
if (bit6 == 0) exp |= (long)1 << (e - 1);
long frac = (imm & 0xf) << (f - 4);
return sign | (exp << f) | frac;
}
private static long ShlOnes(long value, int shift)
{
if (shift != 0)

View file

@ -741,32 +741,32 @@ namespace ARMeilleure.Decoders
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, typeof(OpCode32AluUx));
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, typeof(OpCode32AluUx));
// FP & SIMD (AArch32)
// FP & SIMD
SetA32("<<<<11101x110000xxxx10xx11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, typeof(OpCode32SimdRegS));
SetA32("111100111x11xx01xxxx0x110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, typeof(OpCode32SimdReg));
SetA32("111100100xxxxxxxxxxx1000xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_I, typeof(OpCode32SimdReg));
SetA32("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, typeof(OpCode32SimdRegS));
SetA32("111100100x00xxxxxxxx1101xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_V, typeof(OpCode32SimdReg));
SetA32("111100100xxxxxxxxxxx1000xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_I, typeof(OpCode32SimdReg));
SetA32("111100100x00xxxxxxxx0001xxx1xxxx", InstName.Vand, InstEmit32.Vand_I, typeof(OpCode32SimdBinary));
SetA32("111100110x11xxxxxxxx0001xxx1xxxx", InstName.Vbif, InstEmit32.Vbif, typeof(OpCode32SimdBinary));
SetA32("111100110x10xxxxxxxx0001xxx1xxxx", InstName.Vbit, InstEmit32.Vbit, typeof(OpCode32SimdBinary));
SetA32("111100110x01xxxxxxxx0001xxx1xxxx", InstName.Vbsl, InstEmit32.Vbsl, typeof(OpCode32SimdBinary));
SetA32("111100110x10xxxxxxxx0001xxx1xxxx", InstName.Vbit, InstEmit32.Vbit, typeof(OpCode32SimdBinary));
SetA32("111100111x11xx01xxxx0x010xx0xxxx", InstName.Vceq, InstEmit32.Vceq_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, typeof(OpCode32SimdReg));
SetA32("111100110x<<xxxxxxxx1000xxx1xxxx", InstName.Vceq, InstEmit32.Vceq_I, typeof(OpCode32SimdReg));
SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, typeof(OpCode32SimdReg));
SetA32("111100111x11xx01xxxx0x010xx0xxxx", InstName.Vceq, InstEmit32.Vceq_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100111x11xx01xxxx0x001xx0xxxx", InstName.Vcge, InstEmit32.Vcge_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100110x00xxxxxxxx1110xxx0xxxx", InstName.Vcge, InstEmit32.Vcge_V, typeof(OpCode32SimdReg));
SetA32("1111001x0x<<xxxxxxxx0011xxx1xxxx", InstName.Vcge, InstEmit32.Vcge_I, typeof(OpCode32SimdReg));
SetA32("111100110x00xxxxxxxx1110xxx0xxxx", InstName.Vcge, InstEmit32.Vcge_V, typeof(OpCode32SimdReg));
SetA32("111100111x11xx01xxxx0x001xx0xxxx", InstName.Vcge, InstEmit32.Vcge_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100111x11xx01xxxx0x000xx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100110x10xxxxxxxx1110xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_V, typeof(OpCode32SimdReg));
SetA32("1111001x0x<<xxxxxxxx0011xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_I, typeof(OpCode32SimdReg));
SetA32("111100110x10xxxxxxxx1110xxx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_V, typeof(OpCode32SimdReg));
SetA32("111100111x11xx01xxxx0x000xx0xxxx", InstName.Vcgt, InstEmit32.Vcgt_Z, typeof(OpCode32SimdCmpZ));
SetA32("111100111x11xx01xxxx0x011xx0xxxx", InstName.Vcle, InstEmit32.Vcle_Z, typeof(OpCode32SimdCmpZ));
@ -774,11 +774,11 @@ namespace ARMeilleure.Decoders
SetA32("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, typeof(OpCode32SimdS));
SetA32("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, typeof(OpCode32SimdS));
SetA32("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, typeof(OpCode32SimdCmpZ)); // FP and integer, vector.
SetA32("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, typeof(OpCode32SimdS)); // FP 32 and 64, scalar.
SetA32("<<<<11101x11110xxxxx10xx11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // FP32 to int.
SetA32("<<<<11101x111000xxxx10xxx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // Int to FP32.
SetA32("111111101x1111xxxxxx10>>x1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_R, typeof(OpCode32SimdCvtFI)); // The many FP32 to int encodings (fp).
SetA32("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, typeof(OpCode32SimdCmpZ)); // FP and integer, vector.
SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, typeof(OpCode32SimdRegS));
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdDupGP));
@ -812,19 +812,20 @@ namespace ARMeilleure.Decoders
SetA32("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
SetA32("111100100x00xxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, typeof(OpCode32SimdReg));
SetA32("1111001x0x<<xxxxxxxx0110xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_I, typeof(OpCode32SimdReg));
SetA32("111100100x00xxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, typeof(OpCode32SimdReg));
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, typeof(OpCode32SimdReg));
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, typeof(OpCode32SimdReg));
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, typeof(OpCode32SimdReg));
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.VMMmn, InstEmit32.VmaxNm_S, typeof(OpCode32SimdRegS));
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.VMMmn, InstEmit32.VminNm_S, typeof(OpCode32SimdRegS));
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.VmaxNm_S, typeof(OpCode32SimdRegS));
SetA32("111100110x0xxxxxxxxx1111xxx1xxxx", InstName.Vmaxnm, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.Vminnm, InstEmit32.VminNm_S, typeof(OpCode32SimdRegS));
SetA32("111100110x1xxxxxxxxx1111xxx1xxxx", InstName.Vminnm, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, typeof(OpCode32SimdReg));
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));
SetA32("111100100x00xxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, typeof(OpCode32SimdReg));
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, typeof(OpCode32SimdReg));
SetA32("1111001x1x<<xxxxxxxx000xx1x0xxxx", InstName.Vmla, InstEmit32.Vmla_1, typeof(OpCode32SimdRegElem));
SetA32("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, typeof(OpCode32SimdRegS));
@ -849,26 +850,26 @@ namespace ARMeilleure.Decoders
SetA32("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, typeof(OpCode32SimdSpecial));
SetA32("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, typeof(OpCode32SimdSpecial));
SetA32("1111001x1x<<xxxxxxxx100xx1x0xxxx", InstName.Vmul, InstEmit32.Vmul_1, typeof(OpCode32SimdRegElem));
SetA32("1111001x0xxxxxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, typeof(OpCode32SimdReg));
SetA32("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, typeof(OpCode32SimdRegS));
SetA32("111100110x00xxxxxxxx1101xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_V, typeof(OpCode32SimdReg));
SetA32("1111001x0xxxxxxxxxxx1001xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_I, typeof(OpCode32SimdReg));
SetA32("1111001x1x<<xxxxxxxx100xx1x0xxxx", InstName.Vmul, InstEmit32.Vmul_1, typeof(OpCode32SimdRegElem));
SetA32("1111001x1x000xxxxxxx0xx00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm)); // D/Q vector I32.
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm));
SetA32("1111001x1x000xxxxxxx110x0x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm));
SetA32("111100111x11xx01xxxx0x111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, typeof(OpCode32Simd));
SetA32("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, typeof(OpCode32SimdS));
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, typeof(OpCode32SimdRegS));
SetA32("111100111x11xx01xxxx0x111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, typeof(OpCode32Simd));
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, typeof(OpCode32SimdRegS));
SetA32("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_S, typeof(OpCode32SimdRegS));
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, typeof(OpCode32SimdRegS));
SetA32("111100100x10xxxxxxxx0001xxx1xxxx", InstName.Vorr, InstEmit32.Vorr_I, typeof(OpCode32SimdBinary));
SetA32("111100110x00xxxxxxxx1101x0x0xxxx", InstName.Vpadd, InstEmit32.Vpadd_V, typeof(OpCode32SimdReg));
SetA32("111100100x<<xxxxxxxx1011x0x1xxxx", InstName.Vpadd, InstEmit32.Vpadd_I, typeof(OpCode32SimdReg));
SetA32("111100110x00xxxxxxxx1101x0x0xxxx", InstName.Vpadd, InstEmit32.Vpadd_V, typeof(OpCode32SimdReg));
SetA32("111100111x11xx00xxxx000<<xx0xxxx", InstName.Vrev, InstEmit32.Vrev, typeof(OpCode32SimdRev));
SetA32("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, typeof(OpCode32SimdCvtFI));
@ -876,8 +877,8 @@ namespace ARMeilleure.Decoders
SetA32("111111100xxxxxxxxxxx101xx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, typeof(OpCode32SimdSel));
SetA32("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, typeof(OpCode32SimdReg));
SetA32("111100101x>>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, typeof(OpCode32SimdShImm));
SetA32("1111001x0xxxxxxxxxxx0100xxx0xxxx", InstName.Vshl, InstEmit32.Vshl_I, typeof(OpCode32SimdReg));
SetA32("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, typeof(OpCode32SimdShImm));
SetA32("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, typeof(OpCode32SimdShImm));
@ -905,22 +906,22 @@ namespace ARMeilleure.Decoders
SetA32("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, typeof(OpCode32SimdMemMult));
SetA32("<<<<11010x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, typeof(OpCode32SimdMemMult));
SetA32("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, typeof(OpCode32SimdMemImm));
SetA32("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, typeof(OpCode32SimdS));
SetA32("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, typeof(OpCode32SimdSqrte));
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, typeof(OpCode32SimdReg));
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, typeof(OpCode32SimdSqrte));
SetA32("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, typeof(OpCode32SimdReg));
SetA32("<<<<11101x110001xxxx101x11x0xxxx", InstName.Vsqrt, InstEmit32.Vsqrt_S, typeof(OpCode32SimdS));
SetA32("<<<<1101xx00xxxxxxxx101xxxxxxxxx", InstName.Vstr, InstEmit32.Vstr, typeof(OpCode32SimdMemImm));
SetA32("111100110xxxxxxxxxxx1000xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_I, typeof(OpCode32SimdReg));
SetA32("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, typeof(OpCode32SimdRegS));
SetA32("111100100x10xxxxxxxx1101xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_V, typeof(OpCode32SimdReg));
SetA32("111100110xxxxxxxxxxx1000xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_I, typeof(OpCode32SimdReg));
SetA32("111100111x11xxxxxxxx10xxxxx0xxxx", InstName.Vtbl, InstEmit32.Vtbl, typeof(OpCode32SimdTbl));
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, typeof(OpCode32SimdCmpZ));
SetA32("111100111x11<<10xxxx00010xx0xxxx", InstName.Vuzp, InstEmit32.Vuzp, typeof(OpCode32SimdCmpZ));
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, typeof(OpCode32SimdCmpZ));
#endregion
#endregion
FillFastLookupTable(_instA32FastLookup, _allInstA32);
FillFastLookupTable(_instT32FastLookup, _allInstT32);

View file

@ -544,10 +544,11 @@ namespace ARMeilleure.Instructions
Vldm,
Vldr,
Vmax,
Vmaxnm,
Vmin,
Vminnm,
Vmla,
Vmls,
VMMmn,
Vmov,
Vmovn,
Vmrs,

View file

@ -119,10 +119,9 @@ namespace ARMeilleure.Instructions
return result;
}
private static float _DefaultNaN = BitConverter.Int32BitsToSingle(0x7fc00000);
private static float FPDefaultNaN()
{
return _DefaultNaN;
return BitConverter.Int32BitsToSingle(0x7fc00000);
}
private static float FPInfinity(bool sign)
@ -1343,6 +1342,7 @@ namespace ARMeilleure.Instructions
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
float product;
if ((inf1 && zero2) || (zero1 && inf2))
{
product = FPZero(false);
@ -1506,6 +1506,7 @@ namespace ARMeilleure.Instructions
{
bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero;
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
if (inf1 && inf2 && sign1 == sign2)
{
result = FPDefaultNaN();
@ -1527,6 +1528,7 @@ namespace ARMeilleure.Instructions
else
{
result = (value1 - value2) / 2.0f;
if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
{
context.Fpsr |= FPSR.Ufc;
@ -1555,6 +1557,7 @@ namespace ARMeilleure.Instructions
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
float product;
if ((inf1 && zero2) || (zero1 && inf2))
{
product = FPZero(false);
@ -1563,9 +1566,8 @@ namespace ARMeilleure.Instructions
{
product = FPMulFpscr(value1, value2, true);
}
float three = FPThree(false);
result = FPHalvedSub(three, product, context, fpcr);
result = FPHalvedSub(FPThree(false), product, context, fpcr);
}
return result;
@ -1708,11 +1710,9 @@ namespace ARMeilleure.Instructions
return result;
}
private static float _DefaultNaN = BitConverter.Int32BitsToSingle(0x7fc00000);
private static float FPDefaultNaN()
{
return _DefaultNaN;
return BitConverter.Int32BitsToSingle(0x7fc00000);
}
private static float FPInfinity(bool sign)
@ -2635,6 +2635,7 @@ namespace ARMeilleure.Instructions
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
double product;
if ((inf1 && zero2) || (zero1 && inf2))
{
product = FPZero(false);
@ -2819,6 +2820,7 @@ namespace ARMeilleure.Instructions
else
{
result = (value1 - value2) / 2.0;
if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
{
context.Fpsr |= FPSR.Ufc;
@ -2847,6 +2849,7 @@ namespace ARMeilleure.Instructions
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
double product;
if ((inf1 && zero2) || (zero1 && inf2))
{
product = FPZero(false);
@ -2856,8 +2859,7 @@ namespace ARMeilleure.Instructions
product = FPMulFpscr(value1, value2, true);
}
double three = FPThree(false);
result = FPHalvedSub(three, product, context, fpcr);
result = FPHalvedSub(FPThree(false), product, context, fpcr);
}
return result;
@ -3000,10 +3002,9 @@ namespace ARMeilleure.Instructions
return result;
}
private static double _DefaultNaN = BitConverter.Int64BitsToDouble(0x7ff8000000000000);
private static double FPDefaultNaN()
{
return _DefaultNaN;
return BitConverter.Int64BitsToDouble(0x7ff8000000000000);
}
private static double FPInfinity(bool sign)

View file

@ -1,13 +1,27 @@
#define Alu32
using NUnit.Framework;
using System;
namespace Ryujinx.Tests.Cpu
{
#if Alu32
[Category("Alu32")]
class CpuTestAlu32 : CpuTest32
public sealed class CpuTestAlu32 : CpuTest32
{
#if Alu32
#region "ValueSource (Opcodes)"
private static uint[] _Lsr_Lsl_Asr_Ror_()
{
return new uint[]
{
0xe1b00030u, // LSRS R0, R0, R0
0xe1b00010u, // LSLS R0, R0, R0
0xe1b00050u, // ASRS R0, R0, R0
0xe1b00070u // RORS R0, R0, R0
};
}
#endregion
private const int RndCnt = 2;
[Test, Pairwise, Description("RBIT <Rd>, <Rn>")]
@ -26,60 +40,12 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("LSRS {<Rd>,} <Rm>, <Rs>")]
public void Lsr([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
[Test, Pairwise]
public void Lsr_Lsl_Asr_Ror([ValueSource("_Lsr_Lsl_Asr_Ror_")] uint opcode,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
{
uint opcode = 0xe1b00030u; // LSRS R0, R0, R0
uint rd = 0;
uint rm = 1;
uint rs = 2;
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rs & 15) << 8);
SingleOpcode(opcode, r1: shiftValue, r2: (uint)shiftAmount);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("LSLS {<Rd>,} <Rm>, <Rs>")]
public void Lsl([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
{
uint opcode = 0xe1b00010u; // LSLS R0, R0, R0
uint rd = 0;
uint rm = 1;
uint rs = 2;
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rs & 15) << 8);
SingleOpcode(opcode, r1: shiftValue, r2: (uint)shiftAmount);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("ASRS {<Rd>,} <Rm>, <Rs>")]
public void Asr([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
{
uint opcode = 0xe1b00050u; // ASRS R0, R0, R0
uint rd = 0;
uint rm = 1;
uint rs = 2;
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rs & 15) << 8);
SingleOpcode(opcode, r1: shiftValue, r2: (uint)shiftAmount);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("RORS {<Rd>,} <Rm>, <Rs>")]
public void Ror([Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
{
uint opcode = 0xe1b00070u; // RORS R0, R0, R0
uint rd = 0;
uint rm = 1;
uint rs = 2;
@ -89,6 +55,6 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
#endif
}
#endif
}

View file

@ -4,25 +4,50 @@ using NUnit.Framework;
namespace Ryujinx.Tests.Cpu
{
[Category("AluRs")]
[Category("AluRs32")]
public sealed class CpuTestAluRs32 : CpuTest32
{
#if AluRs32
private const int RndCnt = 5;
private const int RndCntAmount = 50;
private const int RndCntLsb = 2;
[Test, Pairwise, Description("ADC <Rd>, <Rn>, <Rm>")]
public void Adc([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
#region "ValueSource (Opcodes)"
private static uint[] _Add_Adds_Rsb_Rsbs_()
{
return new uint[]
{
0xe0800000u, // ADD R0, R0, R0, LSL #0
0xe0900000u, // ADDS R0, R0, R0, LSL #0
0xe0600000u, // RSB R0, R0, R0, LSL #0
0xe0700000u // RSBS R0, R0, R0, LSL #0
};
}
private static uint[] _Adc_Adcs_Rsc_Rscs_Sbc_Sbcs_()
{
return new uint[]
{
0xe0a00000u, // ADC R0, R0, R0
0xe0b00000u, // ADCS R0, R0, R0
0xe0e00000u, // RSC R0, R0, R0
0xe0f00000u, // RSCS R0, R0, R0
0xe0c00000u, // SBC R0, R0, R0
0xe0d00000u // SBCS R0, R0, R0
};
}
#endregion
private const int RndCnt = 2;
private const int RndCntAmount = 2;
[Test, Pairwise]
public void Adc_Adcs_Rsc_Rscs_Sbc_Sbcs([ValueSource("_Adc_Adcs_Rsc_Rscs_Sbc_Sbcs_")] uint opcode,
[Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
{
uint opcode = 0xe0a00000u; // ADC R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
@ -32,38 +57,18 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("ADCS <Rd>, <Rn>, <Rm>")]
public void Adcs([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
[Test, Pairwise]
public void Add_Adds_Rsb_Rsbs([ValueSource("_Add_Adds_Rsb_Rsbs_")] uint opcode,
[Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount)
{
uint opcode = 0xe0b00000u; // ADCS R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp, carry: carryIn);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("ADD <Rd>, <Rn>, <Rm>{, <shift> #<amount>}")]
public void Add([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount)
{
uint opcode = 0xe0800000u; // ADD R0, R0, R0, LSL #0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
@ -73,152 +78,6 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("ADDS <Rd>, <Rn>, <Rm>{, <shift> #<amount>}")]
public void Adds([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount)
{
uint opcode = 0xe0900000u; // ADDS R0, R0, R0, LSL #0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("RSB <Rd>, <Rn>, <Rm>{, <shift> #<amount>}")]
public void Rsb([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount)
{
uint opcode = 0xe0600000u; // RSB R0, R0, R0, LSL #0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("RSBS <Rd>, <Rn>, <Rm>{, <shift> #<amount>}")]
public void Rsbs([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint shift, // <LSL, LSR, ASR, ROR>
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntAmount)] uint amount)
{
uint opcode = 0xe0700000u; // RSBS R0, R0, R0, LSL #0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("RSB <Rd>, <Rn>, <Rm>")]
public void Rsc([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
{
uint opcode = 0xe0e00000u; // RSC R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp, carry: carryIn);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("RSCS <Rd>, <Rn>, <Rm>")]
public void Rscs([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
{
uint opcode = 0xe0f00000u; // RSCS R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp, carry: carryIn);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("SBC <Rd>, <Rn>, <Rm>")]
public void Sbc([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
{
uint opcode = 0xe0c00000u; // SBC R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp, carry: carryIn);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("SBCS <Rd>, <Rn>, <Rm>")]
public void Sbcs([Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
[Values] bool carryIn)
{
uint opcode = 0xe0d00000u; // SBCS R0, R0, R0
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
uint sp = TestContext.CurrentContext.Random.NextUInt();
SingleOpcode(opcode, r1: wn, r2: wm, sp: sp, carry: carryIn);
CompareAgainstUnicorn();
}
#endif
}
}

View file

@ -1,14 +1,17 @@
using NUnit.Framework;
#define Bf32
using NUnit.Framework;
using System;
namespace Ryujinx.Tests.Cpu
{
[Category("Bfm")]
[Category("Bf32")]
public sealed class CpuTestBf32 : CpuTest32
{
private const int RndCnt = 10;
private const int RndCntImmr = 10;
private const int RndCntImms = 10;
#if Bf32
private const int RndCnt = 2;
private const int RndCntImmr = 2;
private const int RndCntImms = 2;
[Test, Pairwise, Description("BFC <Rd>, #<lsb>, #<width>")]
public void Bfc([Values(0u, 0xdu)] uint rd,
@ -81,7 +84,7 @@ namespace Ryujinx.Tests.Cpu
[Values(1u, 0xdu)] uint rn,
[Random(RndCnt)] uint wd,
[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 lsb,
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint widthm1)
{
@ -100,5 +103,6 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
#endif
}
}

View file

@ -1,4 +1,5 @@
#define SimdLogical32
using ARMeilleure.State;
using NUnit.Framework;
using System;
@ -6,13 +7,33 @@ using System;
namespace Ryujinx.Tests.Cpu
{
[Category("SimdLogical32")]
class CpuTestSimdLogical32 : CpuTest32
public sealed class CpuTestSimdLogical32 : CpuTest32
{
#if SimdLogical32
#region "ValueSource (Opcodes)"
private static uint[] _Vbif_Vbit_Vbsl_Vand_()
{
return new uint[]
{
0xf3300110u, // VBIF D0, D0, D0
0xf3200110u, // VBIT D0, D0, D0
0xf3100110u, // VBSL D0, D0, D0
0xf2000110u // VAND D0, D0, D0
};
}
#endregion
private const int RndCnt = 5;
private const int RndCnt = 2;
private uint GenerateVectorOpcode(uint opcode, uint rd, uint rn, uint rm, bool q)
[Test, Pairwise]
public void Vbif_Vbit_Vbsl_Vand([ValueSource("_Vbif_Vbit_Vbsl_Vand_")] uint opcode,
[Range(0u, 4u)] uint rd,
[Range(0u, 4u)] uint rn,
[Range(0u, 4u)] uint rm,
[Random(RndCnt)] ulong z,
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b,
[Values] bool q)
{
if (q)
{
@ -26,80 +47,6 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
return opcode;
}
[Test, Pairwise, Description("VBIF {<Vd>}, <Vm>, <Vn>")]
public void Vbif([Range(0u, 4u)] uint rd,
[Range(0u, 4u)] uint rn,
[Range(0u, 4u)] uint rm,
[Random(RndCnt)] ulong z,
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b,
[Values] bool q)
{
uint opcode = GenerateVectorOpcode(0xf3300110u, rd, rn, rm, q); // VBIF D0, D0, D0
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, z);
V128 v2 = MakeVectorE0E1(b, z);
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("VBIT {<Vd>}, <Vm>, <Vn>")]
public void Vbit([Range(0u, 4u)] uint rd,
[Range(0u, 4u)] uint rn,
[Range(0u, 4u)] uint rm,
[Random(RndCnt)] ulong z,
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b,
[Values] bool q)
{
uint opcode = GenerateVectorOpcode(0xf3200110u, rd, rn, rm, q); // VBIT D0, D0, D0
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, z);
V128 v2 = MakeVectorE0E1(b, z);
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("VBSL {<Vd>}, <Vm>, <Vn>")]
public void Vbsl([Range(0u, 4u)] uint rd,
[Range(0u, 4u)] uint rn,
[Range(0u, 4u)] uint rm,
[Random(RndCnt)] ulong z,
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b,
[Values] bool q)
{
uint opcode = GenerateVectorOpcode(0xf3100110u, rd, rn, rm, q); // VBSL D0, D0, D0
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, z);
V128 v2 = MakeVectorE0E1(b, z);
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("VAND {<Vd>}, <Vm>, <Vn>")]
public void Vand([Range(0u, 4u)] uint rd,
[Range(0u, 4u)] uint rn,
[Range(0u, 4u)] uint rm,
[Random(RndCnt)] ulong z,
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b,
[Values] bool q)
{
uint opcode = GenerateVectorOpcode(0xf2000110u, rd, rn, rm, q); // VAND D0, D0, D0
V128 v0 = MakeVectorE0E1(z, z);
V128 v1 = MakeVectorE0E1(a, z);
V128 v2 = MakeVectorE0E1(b, z);

View file

@ -1,4 +1,4 @@
#define SimdMem32
#define SimdMemory32
using ARMeilleure.State;
using NUnit.Framework;
@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
[Category("SimdMemory32")]
public sealed class CpuTestSimdMemory32 : CpuTest32
{
#if SimdMem32
#if SimdMemory32
private const int RndCntImm = 2;
private uint[] LDSTModes =

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Tests.Cpu
#if SimdMov32
private const int RndCntImm = 10;
[Test, Combinatorial, Description("VMOV.I<size> <Dd/Qd>, #<imm>")]
[Test, Pairwise, Description("VMOV.I<size> <Dd/Qd>, #<imm>")]
public void Movi_V([Range(0u, 10u)] uint variant,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0x0u)] [Random(1u, 0xffu, RndCntImm)] uint imm,
@ -62,7 +62,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VMOV.F<size> <Sd>, #<imm>")]
[Test, Pairwise, Description("VMOV.F<size> <Sd>, #<imm>")]
public void Movi_S([Range(2u, 3u)] uint size,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0x0u)] [Random(0u, 0xffu, RndCntImm)] uint imm)
@ -107,7 +107,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VMOV.<size> <Rt>, <Dn[x]>")]
[Test, Pairwise, Description("VMOV.<size> <Rt>, <Dn[x]>")]
public void Mov_GP_Elem([Range(0u, 7u)] uint vn,
[Values(0u, 1u, 2u, 3u)] uint rt,
[Range(0u, 2u)] uint size,
@ -206,7 +206,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VMOVN.<size> <Dt>, <Qm>")]
[Test, Pairwise, Description("VMOVN.<size> <Dt>, <Qm>")]
public void Movn_V([Range(0u, 1u, 2u)] uint size,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 2u, 4u, 8u)] uint vm)
@ -230,7 +230,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VTRN.<size> <Vd>, <Vm>")]
[Test, Pairwise, Description("VTRN.<size> <Vd>, <Vm>")]
public void Vtrn([Values(0u, 1u, 2u, 3u)] uint vm,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 1u, 2u)] uint size,
@ -263,7 +263,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VZIP.<size> <Vd>, <Vm>")]
[Test, Pairwise, Description("VZIP.<size> <Vd>, <Vm>")]
public void Vzip([Values(0u, 1u, 2u, 3u)] uint vm,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 1u, 2u)] uint size,
@ -296,7 +296,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VUZP.<size> <Vd>, <Vm>")]
[Test, Pairwise, Description("VUZP.<size> <Vd>, <Vm>")]
public void Vuzp([Values(0u, 1u, 2u, 3u)] uint vm,
[Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 1u, 2u)] uint size,
@ -329,7 +329,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VTBL.8 <Dd>, {list}, <Dm>")]
[Test, Pairwise, Description("VTBL.8 <Dd>, {list}, <Dm>")]
public void Vtbl([Range(0u, 6u)] uint vm, // Indices, include potentially invalid.
[Range(4u, 12u)] uint vn, // Selection.
[Values(0u, 1u)] uint vd, // Destinations.
@ -378,7 +378,7 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VEXT.8 {<Vd>,} <Vn>, <Vm>, #<imm>")]
[Test, Pairwise, Description("VEXT.8 {<Vd>,} <Vn>, <Vm>, #<imm>")]
public void Vext([Values(0u, 1u, 2u, 3u)] uint vm,
[Values(0u, 1u, 2u, 3u)] uint vn,
[Values(0u, 1u, 2u, 3u)] uint vd,

View file

@ -4,13 +4,12 @@ using ARMeilleure.State;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Ryujinx.Tests.Cpu
{
[Category("SimdReg32")]
public sealed class CpuTestSimdReg32 : CpuTest32 {
public sealed class CpuTestSimdReg32 : CpuTest32
{
#if SimdReg32
#region "ValueSource (Types)"
@ -224,11 +223,10 @@ namespace Ryujinx.Tests.Cpu
uint opcode = 0xf2000d00u; // VADD.F32 D0, D0, D0
if (q)
{
rm <<= 2;
rn <<= 2;
rd <<= 2;
opcode |= 1 << 6;
rm <<= 1;
rn <<= 1;
rd <<= 1;
}
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
@ -326,7 +324,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Combinatorial, Description("VPADD.f32 V0, V0, V0")]
[Explicit]
[Test, Pairwise, Description("VPADD.f32 V0, V0, V0")]
public void Vpadd_f32([Values(0u)] uint rd,
[Range(0u, 7u)] uint rn,
[Range(0u, 7u)] uint rm)