diff --git a/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/ARMeilleure/Instructions/InstEmitSimdShift32.cs index 215fe1e8a..f3c002db9 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -289,7 +289,7 @@ namespace ARMeilleure.Instructions context.BranchIfFalse(lblNoSat, context.BitwiseOr(gt, lt)); - // TODO: Set QC (to 1) on FPSCR here. + context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); context.MarkLabel(lblNoSat); diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index babdb0ca7..16c751612 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -145,6 +145,11 @@ namespace ARMeilleure.Instructions GetContext().Fpsr = (FPSR)value; } + public static void SetFpsrQc() + { + GetContext().Fpsr |= FPSR.Qc; + } + public static void SetFpscr(uint fpscr) { var context = GetContext(); diff --git a/ARMeilleure/Translation/Delegates.cs b/ARMeilleure/Translation/Delegates.cs index addb15f6f..d0d93b61d 100644 --- a/ARMeilleure/Translation/Delegates.cs +++ b/ARMeilleure/Translation/Delegates.cs @@ -131,6 +131,7 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr))); + SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall))); diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs b/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs index cd93cb16b..a8c32d586 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdShImm32.cs @@ -173,7 +173,7 @@ namespace Ryujinx.Tests.Cpu public void Vshl_Imm([Values(0u)] uint rd, [Values(2u, 0u)] uint rm, [Values(0u, 1u, 2u, 3u)] uint size, - [Random(RndCnt), Values(0u)] uint shiftImm, + [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm, [Random(RndCnt)] ulong z, [Random(RndCnt)] ulong a, [Random(RndCnt)] ulong b, @@ -207,7 +207,7 @@ namespace Ryujinx.Tests.Cpu public void Vshrn_Imm([Values(0u, 1u)] uint rd, [Values(2u, 0u)] uint rm, [Values(0u, 1u, 2u)] uint size, - [Random(RndCnt), Values(0u)] uint shiftImm, + [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm, [Random(RndCnt)] ulong z, [Random(RndCnt)] ulong a, [Random(RndCnt)] ulong b) @@ -234,7 +234,7 @@ namespace Ryujinx.Tests.Cpu public void Vqrshrn_Imm([Values(0u, 1u)] uint rd, [Values(2u, 0u)] uint rm, [Values(0u, 1u, 2u)] uint size, - [Random(RndCnt), Values(0u)] uint shiftImm, + [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm, [Random(RndCnt)] ulong z, [Random(RndCnt)] ulong a, [Random(RndCnt)] ulong b, @@ -258,16 +258,18 @@ namespace Ryujinx.Tests.Cpu V128 v1 = MakeVectorE0E1(a, z); V128 v2 = MakeVectorE0E1(b, z); - SingleOpcode(opcode, v0: v0, v1: v1, v2: v2); + int fpscr = (int)TestContext.CurrentContext.Random.NextUInt() & (int)Fpsr.Qc; - CompareAgainstUnicorn(); + SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, fpscr: fpscr); + + CompareAgainstUnicorn(fpsrMask: Fpsr.Qc); } [Test, Pairwise, Description("VQRSHRUN. , , #")] public void Vqrshrun_Imm([Values(0u, 1u)] uint rd, [Values(2u, 0u)] uint rm, [Values(0u, 1u, 2u)] uint size, - [Random(RndCnt), Values(0u)] uint shiftImm, + [Random(RndCntShiftImm)] [Values(0u)] uint shiftImm, [Random(RndCnt)] ulong z, [Random(RndCnt)] ulong a, [Random(RndCnt)] ulong b) @@ -285,9 +287,11 @@ namespace Ryujinx.Tests.Cpu V128 v1 = MakeVectorE0E1(a, z); V128 v2 = MakeVectorE0E1(b, z); - SingleOpcode(opcode, v0: v0, v1: v1, v2: v2); + int fpscr = (int)TestContext.CurrentContext.Random.NextUInt() & (int)Fpsr.Qc; - CompareAgainstUnicorn(); + SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, fpscr: fpscr); + + CompareAgainstUnicorn(fpsrMask: Fpsr.Qc); } #endif }