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);
|
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)
|
private static long ShlOnes(long value, int shift)
|
||||||
{
|
{
|
||||||
if (shift != 0)
|
if (shift != 0)
|
||||||
|
|
|
@ -741,32 +741,32 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, typeof(OpCode32AluUx));
|
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, typeof(OpCode32AluUx));
|
||||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, 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("<<<<11101x110000xxxx10xx11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100111x11xx01xxxx0x110xx0xxxx", InstName.Vabs, InstEmit32.Vabs_V, typeof(OpCode32SimdReg));
|
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("<<<<11100x11xxxxxxxx101xx0x0xxxx", InstName.Vadd, InstEmit32.Vadd_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100100x00xxxxxxxx1101xxx0xxxx", InstName.Vadd, InstEmit32.Vadd_V, typeof(OpCode32SimdReg));
|
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("111100100x00xxxxxxxx0001xxx1xxxx", InstName.Vand, InstEmit32.Vand_I, typeof(OpCode32SimdBinary));
|
||||||
|
|
||||||
SetA32("111100110x11xxxxxxxx0001xxx1xxxx", InstName.Vbif, InstEmit32.Vbif, 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("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("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("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("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));
|
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("<<<<11101x11010xxxxx101x01x0xxxx", InstName.Vcmp, InstEmit32.Vcmp, typeof(OpCode32SimdS));
|
||||||
SetA32("<<<<11101x11010xxxxx101x11x0xxxx", InstName.Vcmpe, InstEmit32.Vcmpe, 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("<<<<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("<<<<11101x11110xxxxx10xx11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // FP32 to int.
|
||||||
SetA32("<<<<11101x111000xxxx10xxx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // Int to FP32.
|
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("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("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdDupGP));
|
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdDupGP));
|
||||||
|
@ -812,19 +812,20 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
SetA32("<<<<1101xx01xxxxxxxx101xxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
|
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("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("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>>x0x0xxxx", InstName.Vmaxnm, InstEmit32.VmaxNm_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.VMMmn, InstEmit32.VminNm_S, typeof(OpCode32SimdRegS));
|
SetA32("111100110x0xxxxxxxxx1111xxx1xxxx", InstName.Vmaxnm, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
|
||||||
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, 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("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100100x00xxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, typeof(OpCode32SimdReg));
|
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("1111001x1x<<xxxxxxxx000xx1x0xxxx", InstName.Vmla, InstEmit32.Vmla_1, typeof(OpCode32SimdRegElem));
|
||||||
|
|
||||||
SetA32("<<<<11100x00xxxxxxxx101xx1x0xxxx", InstName.Vmls, InstEmit32.Vmls_S, typeof(OpCode32SimdRegS));
|
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("<<<<11101111xxxxxxxx101000010000", InstName.Vmrs, InstEmit32.Vmrs, typeof(OpCode32SimdSpecial));
|
||||||
SetA32("<<<<11101110xxxxxxxx101000010000", InstName.Vmsr, InstEmit32.Vmsr, 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("<<<<11100x10xxxxxxxx101xx0x0xxxx", InstName.Vmul, InstEmit32.Vmul_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100110x00xxxxxxxx1101xxx1xxxx", InstName.Vmul, InstEmit32.Vmul_V, typeof(OpCode32SimdReg));
|
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("1111001x1x000xxxxxxx0xx00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm)); // D/Q vector I32.
|
||||||
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm));
|
SetA32("1111001x1x000xxxxxxx10x00x11xxxx", InstName.Vmvn, InstEmit32.Vmvn_I, typeof(OpCode32SimdImm));
|
||||||
SetA32("1111001x1x000xxxxxxx110x0x11xxxx", 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("<<<<11101x110001xxxx101x01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, typeof(OpCode32SimdS));
|
||||||
|
SetA32("111100111x11xx01xxxx0x111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, typeof(OpCode32Simd));
|
||||||
SetA32("<<<<11100x10xxxxxxxx101xx1x0xxxx", InstName.Vnmul, InstEmit32.Vnmul_S, typeof(OpCode32SimdRegS));
|
|
||||||
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, typeof(OpCode32SimdRegS));
|
SetA32("<<<<11100x01xxxxxxxx101xx1x0xxxx", InstName.Vnmla, InstEmit32.Vnmla_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("<<<<11100x01xxxxxxxx101xx0x0xxxx", InstName.Vnmls, InstEmit32.Vnmls_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("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("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("111100111x11xx00xxxx000<<xx0xxxx", InstName.Vrev, InstEmit32.Vrev, typeof(OpCode32SimdRev));
|
||||||
SetA32("111111101x1110xxxxxx101x01x0xxxx", InstName.Vrint, InstEmit32.Vrint_RM, typeof(OpCode32SimdCvtFI));
|
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("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("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("1111001x1x>>>xxxxxxx0000>xx1xxxx", InstName.Vshr, InstEmit32.Vshr, typeof(OpCode32SimdShImm));
|
||||||
SetA32("111100101x>>>xxxxxxx100000x1xxx0", InstName.Vshrn, InstEmit32.Vshrn, 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("<<<<11001x10xxxxxxxx1010xxxxxxxx", InstName.Vstm, InstEmit32.Vstm, typeof(OpCode32SimdMemMult));
|
||||||
SetA32("<<<<11010x10xxxxxxxx1010xxxxxxxx", 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("111100111x111011xxxx010x0xx0xxxx", InstName.Vrecpe, InstEmit32.Vrecpe, typeof(OpCode32SimdSqrte));
|
||||||
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, typeof(OpCode32SimdReg));
|
SetA32("111100100x00xxxxxxxx1111xxx1xxxx", InstName.Vrecps, InstEmit32.Vrecps, typeof(OpCode32SimdReg));
|
||||||
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, typeof(OpCode32SimdSqrte));
|
SetA32("111100111x111011xxxx010x1xx0xxxx", InstName.Vrsqrte, InstEmit32.Vrsqrte, typeof(OpCode32SimdSqrte));
|
||||||
SetA32("111100100x10xxxxxxxx1111xxx1xxxx", InstName.Vrsqrts, InstEmit32.Vrsqrts, typeof(OpCode32SimdReg));
|
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("<<<<11100x11xxxxxxxx101xx1x0xxxx", InstName.Vsub, InstEmit32.Vsub_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100100x10xxxxxxxx1101xxx0xxxx", InstName.Vsub, InstEmit32.Vsub_V, typeof(OpCode32SimdReg));
|
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("111100111x11xxxxxxxx10xxxxx0xxxx", InstName.Vtbl, InstEmit32.Vtbl, typeof(OpCode32SimdTbl));
|
||||||
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, typeof(OpCode32SimdCmpZ));
|
SetA32("111100111x11<<10xxxx00001xx0xxxx", InstName.Vtrn, InstEmit32.Vtrn, typeof(OpCode32SimdCmpZ));
|
||||||
SetA32("111100111x11<<10xxxx00010xx0xxxx", InstName.Vuzp, InstEmit32.Vuzp, typeof(OpCode32SimdCmpZ));
|
SetA32("111100111x11<<10xxxx00010xx0xxxx", InstName.Vuzp, InstEmit32.Vuzp, typeof(OpCode32SimdCmpZ));
|
||||||
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, typeof(OpCode32SimdCmpZ));
|
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, typeof(OpCode32SimdCmpZ));
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
FillFastLookupTable(_instA32FastLookup, _allInstA32);
|
FillFastLookupTable(_instA32FastLookup, _allInstA32);
|
||||||
FillFastLookupTable(_instT32FastLookup, _allInstT32);
|
FillFastLookupTable(_instT32FastLookup, _allInstT32);
|
||||||
|
|
|
@ -544,10 +544,11 @@ namespace ARMeilleure.Instructions
|
||||||
Vldm,
|
Vldm,
|
||||||
Vldr,
|
Vldr,
|
||||||
Vmax,
|
Vmax,
|
||||||
|
Vmaxnm,
|
||||||
Vmin,
|
Vmin,
|
||||||
|
Vminnm,
|
||||||
Vmla,
|
Vmla,
|
||||||
Vmls,
|
Vmls,
|
||||||
VMMmn,
|
|
||||||
Vmov,
|
Vmov,
|
||||||
Vmovn,
|
Vmovn,
|
||||||
Vmrs,
|
Vmrs,
|
||||||
|
|
|
@ -119,10 +119,9 @@ namespace ARMeilleure.Instructions
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float _DefaultNaN = BitConverter.Int32BitsToSingle(0x7fc00000);
|
|
||||||
private static float FPDefaultNaN()
|
private static float FPDefaultNaN()
|
||||||
{
|
{
|
||||||
return _DefaultNaN;
|
return BitConverter.Int32BitsToSingle(0x7fc00000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float FPInfinity(bool sign)
|
private static float FPInfinity(bool sign)
|
||||||
|
@ -1343,6 +1342,7 @@ namespace ARMeilleure.Instructions
|
||||||
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
||||||
|
|
||||||
float product;
|
float product;
|
||||||
|
|
||||||
if ((inf1 && zero2) || (zero1 && inf2))
|
if ((inf1 && zero2) || (zero1 && inf2))
|
||||||
{
|
{
|
||||||
product = FPZero(false);
|
product = FPZero(false);
|
||||||
|
@ -1506,6 +1506,7 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero;
|
bool inf1 = type1 == FPType.Infinity; bool zero1 = type1 == FPType.Zero;
|
||||||
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
||||||
|
|
||||||
if (inf1 && inf2 && sign1 == sign2)
|
if (inf1 && inf2 && sign1 == sign2)
|
||||||
{
|
{
|
||||||
result = FPDefaultNaN();
|
result = FPDefaultNaN();
|
||||||
|
@ -1527,6 +1528,7 @@ namespace ARMeilleure.Instructions
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = (value1 - value2) / 2.0f;
|
result = (value1 - value2) / 2.0f;
|
||||||
|
|
||||||
if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
|
if ((fpcr & FPCR.Fz) != 0 && float.IsSubnormal(result))
|
||||||
{
|
{
|
||||||
context.Fpsr |= FPSR.Ufc;
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
@ -1555,6 +1557,7 @@ namespace ARMeilleure.Instructions
|
||||||
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
||||||
|
|
||||||
float product;
|
float product;
|
||||||
|
|
||||||
if ((inf1 && zero2) || (zero1 && inf2))
|
if ((inf1 && zero2) || (zero1 && inf2))
|
||||||
{
|
{
|
||||||
product = FPZero(false);
|
product = FPZero(false);
|
||||||
|
@ -1563,9 +1566,8 @@ namespace ARMeilleure.Instructions
|
||||||
{
|
{
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscr(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
float three = FPThree(false);
|
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||||
result = FPHalvedSub(three, product, context, fpcr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1708,11 +1710,9 @@ namespace ARMeilleure.Instructions
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float _DefaultNaN = BitConverter.Int32BitsToSingle(0x7fc00000);
|
|
||||||
|
|
||||||
private static float FPDefaultNaN()
|
private static float FPDefaultNaN()
|
||||||
{
|
{
|
||||||
return _DefaultNaN;
|
return BitConverter.Int32BitsToSingle(0x7fc00000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float FPInfinity(bool sign)
|
private static float FPInfinity(bool sign)
|
||||||
|
@ -2635,6 +2635,7 @@ namespace ARMeilleure.Instructions
|
||||||
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
||||||
|
|
||||||
double product;
|
double product;
|
||||||
|
|
||||||
if ((inf1 && zero2) || (zero1 && inf2))
|
if ((inf1 && zero2) || (zero1 && inf2))
|
||||||
{
|
{
|
||||||
product = FPZero(false);
|
product = FPZero(false);
|
||||||
|
@ -2819,6 +2820,7 @@ namespace ARMeilleure.Instructions
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = (value1 - value2) / 2.0;
|
result = (value1 - value2) / 2.0;
|
||||||
|
|
||||||
if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
|
if ((fpcr & FPCR.Fz) != 0 && double.IsSubnormal(result))
|
||||||
{
|
{
|
||||||
context.Fpsr |= FPSR.Ufc;
|
context.Fpsr |= FPSR.Ufc;
|
||||||
|
@ -2847,6 +2849,7 @@ namespace ARMeilleure.Instructions
|
||||||
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
bool inf2 = type2 == FPType.Infinity; bool zero2 = type2 == FPType.Zero;
|
||||||
|
|
||||||
double product;
|
double product;
|
||||||
|
|
||||||
if ((inf1 && zero2) || (zero1 && inf2))
|
if ((inf1 && zero2) || (zero1 && inf2))
|
||||||
{
|
{
|
||||||
product = FPZero(false);
|
product = FPZero(false);
|
||||||
|
@ -2856,8 +2859,7 @@ namespace ARMeilleure.Instructions
|
||||||
product = FPMulFpscr(value1, value2, true);
|
product = FPMulFpscr(value1, value2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
double three = FPThree(false);
|
result = FPHalvedSub(FPThree(false), product, context, fpcr);
|
||||||
result = FPHalvedSub(three, product, context, fpcr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -3000,10 +3002,9 @@ namespace ARMeilleure.Instructions
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double _DefaultNaN = BitConverter.Int64BitsToDouble(0x7ff8000000000000);
|
|
||||||
private static double FPDefaultNaN()
|
private static double FPDefaultNaN()
|
||||||
{
|
{
|
||||||
return _DefaultNaN;
|
return BitConverter.Int64BitsToDouble(0x7ff8000000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double FPInfinity(bool sign)
|
private static double FPInfinity(bool sign)
|
||||||
|
|
|
@ -1,13 +1,27 @@
|
||||||
#define Alu32
|
#define Alu32
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
#if Alu32
|
|
||||||
[Category("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;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("RBIT <Rd>, <Rn>")]
|
[Test, Pairwise, Description("RBIT <Rd>, <Rn>")]
|
||||||
|
@ -26,60 +40,12 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("LSRS {<Rd>,} <Rm>, <Rs>")]
|
[Test, Pairwise]
|
||||||
public void Lsr([Values(0x00000000u, 0x7FFFFFFFu,
|
public void Lsr_Lsl_Asr_Ror([ValueSource("_Lsr_Lsl_Asr_Ror_")] uint opcode,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint shiftValue,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
[Range(0, 31)] [Values(32, 256, 768, -1, -23)] int shiftAmount)
|
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 rd = 0;
|
||||||
uint rm = 1;
|
uint rm = 1;
|
||||||
uint rs = 2;
|
uint rs = 2;
|
||||||
|
@ -89,6 +55,6 @@ namespace Ryujinx.Tests.Cpu
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,25 +4,50 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("AluRs")]
|
[Category("AluRs32")]
|
||||||
public sealed class CpuTestAluRs32 : CpuTest32
|
public sealed class CpuTestAluRs32 : CpuTest32
|
||||||
{
|
{
|
||||||
#if AluRs32
|
#if AluRs32
|
||||||
private const int RndCnt = 5;
|
#region "ValueSource (Opcodes)"
|
||||||
private const int RndCntAmount = 50;
|
private static uint[] _Add_Adds_Rsb_Rsbs_()
|
||||||
private const int RndCntLsb = 2;
|
{
|
||||||
|
return new uint[]
|
||||||
[Test, Pairwise, Description("ADC <Rd>, <Rn>, <Rm>")]
|
{
|
||||||
public void Adc([Values(0u, 13u)] uint rd,
|
0xe0800000u, // ADD R0, R0, R0, LSL #0
|
||||||
[Values(1u, 13u)] uint rn,
|
0xe0900000u, // ADDS R0, R0, R0, LSL #0
|
||||||
[Values(2u, 13u)] uint rm,
|
0xe0600000u, // RSB R0, R0, R0, LSL #0
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
0xe0700000u // RSBS R0, R0, R0, LSL #0
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
};
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
}
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
|
||||||
[Values] bool carryIn)
|
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);
|
opcode |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
|
||||||
|
|
||||||
uint sp = TestContext.CurrentContext.Random.NextUInt();
|
uint sp = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
@ -32,38 +57,18 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test, Pairwise, Description("ADCS <Rd>, <Rn>, <Rm>")]
|
[Test, Pairwise]
|
||||||
public void Adcs([Values(0u, 13u)] uint rd,
|
public void Add_Adds_Rsb_Rsbs([ValueSource("_Add_Adds_Rsb_Rsbs_")] uint opcode,
|
||||||
[Values(1u, 13u)] uint rn,
|
[Values(0u, 13u)] uint rd,
|
||||||
[Values(2u, 13u)] uint rm,
|
[Values(1u, 13u)] uint rn,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
[Values(2u, 13u)] uint rm,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
[Values(0x00000000u, 0x7FFFFFFFu,
|
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wn,
|
||||||
0x80000000u, 0xFFFFFFFFu)] [Random(RndCnt)] uint wm,
|
[Values(0x00000000u, 0x7FFFFFFFu,
|
||||||
[Values] bool carryIn)
|
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 |= ((rm & 15) << 0) | ((rn & 15) << 16) | ((rd & 15) << 12);
|
||||||
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
|
opcode |= ((shift & 3) << 5) | ((amount & 31) << 7);
|
||||||
|
|
||||||
|
@ -73,152 +78,6 @@ namespace Ryujinx.Tests.Cpu
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
using NUnit.Framework;
|
#define Bf32
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("Bfm")]
|
[Category("Bf32")]
|
||||||
public sealed class CpuTestBf32 : CpuTest32
|
public sealed class CpuTestBf32 : CpuTest32
|
||||||
{
|
{
|
||||||
private const int RndCnt = 10;
|
#if Bf32
|
||||||
private const int RndCntImmr = 10;
|
private const int RndCnt = 2;
|
||||||
private const int RndCntImms = 10;
|
private const int RndCntImmr = 2;
|
||||||
|
private const int RndCntImms = 2;
|
||||||
|
|
||||||
[Test, Pairwise, Description("BFC <Rd>, #<lsb>, #<width>")]
|
[Test, Pairwise, Description("BFC <Rd>, #<lsb>, #<width>")]
|
||||||
public void Bfc([Values(0u, 0xdu)] uint rd,
|
public void Bfc([Values(0u, 0xdu)] uint rd,
|
||||||
|
@ -81,7 +84,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[Values(1u, 0xdu)] uint rn,
|
[Values(1u, 0xdu)] 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 lsb,
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint lsb,
|
||||||
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint widthm1)
|
[Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint widthm1)
|
||||||
{
|
{
|
||||||
|
@ -100,5 +103,6 @@ namespace Ryujinx.Tests.Cpu
|
||||||
|
|
||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#define SimdLogical32
|
#define SimdLogical32
|
||||||
|
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
@ -6,13 +7,33 @@ using System;
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdLogical32")]
|
[Category("SimdLogical32")]
|
||||||
class CpuTestSimdLogical32 : CpuTest32
|
public sealed class CpuTestSimdLogical32 : CpuTest32
|
||||||
{
|
{
|
||||||
#if SimdLogical32
|
#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)
|
if (q)
|
||||||
{
|
{
|
||||||
|
@ -26,80 +47,6 @@ namespace Ryujinx.Tests.Cpu
|
||||||
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
|
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
|
||||||
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
|
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 v0 = MakeVectorE0E1(z, z);
|
||||||
V128 v1 = MakeVectorE0E1(a, z);
|
V128 v1 = MakeVectorE0E1(a, z);
|
||||||
V128 v2 = MakeVectorE0E1(b, z);
|
V128 v2 = MakeVectorE0E1(b, z);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#define SimdMem32
|
#define SimdMemory32
|
||||||
|
|
||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[Category("SimdMemory32")]
|
[Category("SimdMemory32")]
|
||||||
public sealed class CpuTestSimdMemory32 : CpuTest32
|
public sealed class CpuTestSimdMemory32 : CpuTest32
|
||||||
{
|
{
|
||||||
#if SimdMem32
|
#if SimdMemory32
|
||||||
private const int RndCntImm = 2;
|
private const int RndCntImm = 2;
|
||||||
|
|
||||||
private uint[] LDSTModes =
|
private uint[] LDSTModes =
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
#if SimdMov32
|
#if SimdMov32
|
||||||
private const int RndCntImm = 10;
|
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,
|
public void Movi_V([Range(0u, 10u)] uint variant,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0x0u)] [Random(1u, 0xffu, RndCntImm)] uint imm,
|
[Values(0x0u)] [Random(1u, 0xffu, RndCntImm)] uint imm,
|
||||||
|
@ -62,7 +62,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Movi_S([Range(2u, 3u)] uint size,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0x0u)] [Random(0u, 0xffu, RndCntImm)] uint imm)
|
[Values(0x0u)] [Random(0u, 0xffu, RndCntImm)] uint imm)
|
||||||
|
@ -107,7 +107,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Mov_GP_Elem([Range(0u, 7u)] uint vn,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint rt,
|
[Values(0u, 1u, 2u, 3u)] uint rt,
|
||||||
[Range(0u, 2u)] uint size,
|
[Range(0u, 2u)] uint size,
|
||||||
|
@ -206,7 +206,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Movn_V([Range(0u, 1u, 2u)] uint size,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0u, 2u, 4u, 8u)] uint vm)
|
[Values(0u, 2u, 4u, 8u)] uint vm)
|
||||||
|
@ -230,7 +230,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Vtrn([Values(0u, 1u, 2u, 3u)] uint vm,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0u, 1u, 2u)] uint size,
|
[Values(0u, 1u, 2u)] uint size,
|
||||||
|
@ -263,7 +263,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Vzip([Values(0u, 1u, 2u, 3u)] uint vm,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0u, 1u, 2u)] uint size,
|
[Values(0u, 1u, 2u)] uint size,
|
||||||
|
@ -296,7 +296,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Vuzp([Values(0u, 1u, 2u, 3u)] uint vm,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
[Values(0u, 1u, 2u)] uint size,
|
[Values(0u, 1u, 2u)] uint size,
|
||||||
|
@ -329,7 +329,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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.
|
public void Vtbl([Range(0u, 6u)] uint vm, // Indices, include potentially invalid.
|
||||||
[Range(4u, 12u)] uint vn, // Selection.
|
[Range(4u, 12u)] uint vn, // Selection.
|
||||||
[Values(0u, 1u)] uint vd, // Destinations.
|
[Values(0u, 1u)] uint vd, // Destinations.
|
||||||
|
@ -378,7 +378,7 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Vext([Values(0u, 1u, 2u, 3u)] uint vm,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vn,
|
[Values(0u, 1u, 2u, 3u)] uint vn,
|
||||||
[Values(0u, 1u, 2u, 3u)] uint vd,
|
[Values(0u, 1u, 2u, 3u)] uint vd,
|
||||||
|
|
|
@ -4,13 +4,12 @@ using ARMeilleure.State;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
{
|
{
|
||||||
[Category("SimdReg32")]
|
[Category("SimdReg32")]
|
||||||
public sealed class CpuTestSimdReg32 : CpuTest32 {
|
public sealed class CpuTestSimdReg32 : CpuTest32
|
||||||
|
{
|
||||||
#if SimdReg32
|
#if SimdReg32
|
||||||
|
|
||||||
#region "ValueSource (Types)"
|
#region "ValueSource (Types)"
|
||||||
|
@ -224,11 +223,10 @@ namespace Ryujinx.Tests.Cpu
|
||||||
uint opcode = 0xf2000d00u; // VADD.F32 D0, D0, D0
|
uint opcode = 0xf2000d00u; // VADD.F32 D0, D0, D0
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
rm <<= 2;
|
|
||||||
rn <<= 2;
|
|
||||||
rd <<= 2;
|
|
||||||
|
|
||||||
opcode |= 1 << 6;
|
opcode |= 1 << 6;
|
||||||
|
rm <<= 1;
|
||||||
|
rn <<= 1;
|
||||||
|
rd <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
|
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
|
||||||
|
@ -326,7 +324,8 @@ namespace Ryujinx.Tests.Cpu
|
||||||
CompareAgainstUnicorn();
|
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,
|
public void Vpadd_f32([Values(0u)] uint rd,
|
||||||
[Range(0u, 7u)] uint rn,
|
[Range(0u, 7u)] uint rn,
|
||||||
[Range(0u, 7u)] uint rm)
|
[Range(0u, 7u)] uint rm)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue