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:
parent
f244fb26fb
commit
ea6fc47fac
11 changed files with 168 additions and 407 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -544,10 +544,11 @@ namespace ARMeilleure.Instructions
|
|||
Vldm,
|
||||
Vldr,
|
||||
Vmax,
|
||||
Vmaxnm,
|
||||
Vmin,
|
||||
Vminnm,
|
||||
Vmla,
|
||||
Vmls,
|
||||
VMMmn,
|
||||
Vmov,
|
||||
Vmovn,
|
||||
Vmrs,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue