From 2b5ec23aa747d46e7c9142c14c636e58fa5b5910 Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Sat, 19 Oct 2019 00:47:50 +0200 Subject: [PATCH 1/4] Fix latest version of hbl/hb-menu (#795) * Fix latest version of hbl/hb-menu This implement GetSettingsItemValueSize (required by hbl) and GetInternetConnectionStatus (required by hb-menu). * Address comments --- .../Nifm/StaticService/IGeneralService.cs | 23 ++++++++++ .../Types/InternetConnectionState.cs | 11 +++++ .../Types/InternetConnectionStatus.cs | 12 +++++ .../Types/InternetConnectionType.cs | 9 ++++ .../Settings/ISystemSettingsServer.cs | 44 +++++++++++++++++++ 5 files changed, 99 insertions(+) create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs index 4a07b2986d..c1642c3f57 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -1,5 +1,7 @@ +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService; +using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types; using System; using System.Linq; using System.Net; @@ -71,6 +73,27 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService return ResultCode.Success; } + [Command(18)] + // GetInternetConnectionStatus() -> nn::nifm::detail::sf::InternetConnectionStatus + public ResultCode GetInternetConnectionStatus(ServiceCtx context) + { + if (!NetworkInterface.GetIsNetworkAvailable()) + { + return ResultCode.NoInternetConnection; + } + + InternetConnectionStatus internetConnectionStatus = new InternetConnectionStatus + { + Type = InternetConnectionType.WiFi, + WifiStrength = 3, + State = InternetConnectionState.Connected, + }; + + context.ResponseData.WriteStruct(internetConnectionStatus); + + return ResultCode.Success; + } + [Command(21)] // IsAnyInternetRequestAccepted(buffer) -> bool public ResultCode IsAnyInternetRequestAccepted(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs new file mode 100644 index 0000000000..dfb8f76cac --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionState.cs @@ -0,0 +1,11 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + enum InternetConnectionState : byte + { + ConnectingType0 = 0, + ConnectingType1 = 1, + ConnectingType2 = 2, + ConnectingType3 = 3, + Connected = 4, + } +} diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs new file mode 100644 index 0000000000..ff944eca21 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionStatus.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + [StructLayout(LayoutKind.Sequential)] + struct InternetConnectionStatus + { + public InternetConnectionType Type; + public byte WifiStrength; + public InternetConnectionState State; + } +} diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs new file mode 100644 index 0000000000..af2bcfa181 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/InternetConnectionType.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types +{ + enum InternetConnectionType : byte + { + Invalid = 0, + WiFi = 1, + Ethernet = 2, + } +} diff --git a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs index 490d0e8ef0..73f437e8bf 100644 --- a/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs +++ b/Ryujinx.HLE/HOS/Services/Settings/ISystemSettingsServer.cs @@ -103,6 +103,50 @@ namespace Ryujinx.HLE.HOS.Services.Settings return ResultCode.Success; } + [Command(37)] + // GetSettingsItemValueSize(buffer, buffer) -> u64 + public ResultCode GetSettingsItemValueSize(ServiceCtx context) + { + long classPos = context.Request.PtrBuff[0].Position; + long classSize = context.Request.PtrBuff[0].Size; + + long namePos = context.Request.PtrBuff[1].Position; + long nameSize = context.Request.PtrBuff[1].Size; + + byte[] Class = context.Memory.ReadBytes(classPos, classSize); + byte[] name = context.Memory.ReadBytes(namePos, nameSize); + + string askedSetting = Encoding.ASCII.GetString(Class).Trim('\0') + "!" + Encoding.ASCII.GetString(name).Trim('\0'); + + NxSettings.Settings.TryGetValue(askedSetting, out object nxSetting); + + if (nxSetting != null) + { + ulong settingSize; + + if (nxSetting is string stringValue) + { + settingSize = (ulong)stringValue.Length + 1; + } + else if (nxSetting is int) + { + settingSize = sizeof(int); + } + else if (nxSetting is bool) + { + settingSize = 1; + } + else + { + throw new NotImplementedException(nxSetting.GetType().Name); + } + + context.ResponseData.Write(settingSize); + } + + return ResultCode.Success; + } + [Command(38)] // GetSettingsItemValue(buffer, buffer) -> (u64, buffer) public ResultCode GetSettingsItemValue(ServiceCtx context) From 1772128ce0fc058e6280001aace3a77a7a96897b Mon Sep 17 00:00:00 2001 From: jduncanator Date: Tue, 22 Oct 2019 14:09:49 +1100 Subject: [PATCH 2/4] Resolve Visual Studio build issues Visual Studio defaults to a C# version of "latest major". Some of the new projects require C# 7.1 features. --- ARMeilleure/ARMeilleure.csproj | 1 + Ryujinx.Tests/Ryujinx.Tests.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/ARMeilleure/ARMeilleure.csproj b/ARMeilleure/ARMeilleure.csproj index 9268dcbee1..15e5c0274b 100644 --- a/ARMeilleure/ARMeilleure.csproj +++ b/ARMeilleure/ARMeilleure.csproj @@ -3,6 +3,7 @@ netcoreapp2.1 win-x64;osx-x64;linux-x64 + latest diff --git a/Ryujinx.Tests/Ryujinx.Tests.csproj b/Ryujinx.Tests/Ryujinx.Tests.csproj index 9608422e52..52832d868b 100644 --- a/Ryujinx.Tests/Ryujinx.Tests.csproj +++ b/Ryujinx.Tests/Ryujinx.Tests.csproj @@ -14,6 +14,7 @@ false + latest From 86b42f176af69b58b493396dff0a5958e073b39b Mon Sep 17 00:00:00 2001 From: jduncanator <1518948+jduncanator@users.noreply.github.com> Date: Fri, 25 Oct 2019 10:34:35 +1100 Subject: [PATCH 3/4] svc: Implement `ref` parameters (#798) Allows passing data into and out of the same registers when calling via the Kernel ABI. This allows implementing specific supervisor calls like "CallSecureMonitor", that expect their args and results in the same registers. --- Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs index 70b6db0c4e..b740253fd5 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs @@ -231,7 +231,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall if (!methodArgs[index].IsOut) { - throw new InvalidOperationException($"Method \"{svcName}\" has a invalid ref type \"{argType.Name}\"."); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldc_I4, index); + + MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.GetX)); + + generator.Emit(OpCodes.Call, info); + + ConvertToArgType(argType); + + generator.Emit(OpCodes.Stloc, local); } generator.Emit(OpCodes.Ldloca, local); From eff8379d2aa52574b6df25e469b87a142cc3863f Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Fri, 25 Oct 2019 01:37:42 +0200 Subject: [PATCH 4/4] Add Sli_S/V & Sri_S/V inst.s (fast & slow paths), with Tests. (#797) * Add Sli & Sri. * Add scalar variants. --- ARMeilleure/Decoders/OpCodeTable.cs | 4 + ARMeilleure/Instructions/InstEmitSimdShift.cs | 170 ++++++++++++++---- ARMeilleure/Instructions/InstName.cs | 3 + Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs | 83 +++++---- 4 files changed, 188 insertions(+), 72 deletions(-) diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index 55cd5cb610..2fa7702d90 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -437,6 +437,7 @@ namespace ARMeilleure.Decoders SetA64("0x101110<<100001001110xxxxxxxxxx", InstName.Shll_V, InstEmit.Shll_V, typeof(OpCodeSimd)); SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstName.Shrn_V, InstEmit.Shrn_V, typeof(OpCodeSimdShImm)); SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstName.Shsub_V, InstEmit.Shsub_V, typeof(OpCodeSimdReg)); + SetA64("0111111101xxxxxx010101xxxxxxxxxx", InstName.Sli_S, InstEmit.Sli_S, typeof(OpCodeSimdShImm)); SetA64("0x10111100>>>xxx010101xxxxxxxxxx", InstName.Sli_V, InstEmit.Sli_V, typeof(OpCodeSimdShImm)); SetA64("0110111101xxxxxx010101xxxxxxxxxx", InstName.Sli_V, InstEmit.Sli_V, typeof(OpCodeSimdShImm)); SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstName.Smax_V, InstEmit.Smax_V, typeof(OpCodeSimdReg)); @@ -485,6 +486,9 @@ namespace ARMeilleure.Decoders SetA64("01111110<<100001001010xxxxxxxxxx", InstName.Sqxtun_S, InstEmit.Sqxtun_S, typeof(OpCodeSimd)); SetA64("0x101110<<100001001010xxxxxxxxxx", InstName.Sqxtun_V, InstEmit.Sqxtun_V, typeof(OpCodeSimd)); SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstName.Srhadd_V, InstEmit.Srhadd_V, typeof(OpCodeSimdReg)); + SetA64("0111111101xxxxxx010001xxxxxxxxxx", InstName.Sri_S, InstEmit.Sri_S, typeof(OpCodeSimdShImm)); + SetA64("0x10111100>>>xxx010001xxxxxxxxxx", InstName.Sri_V, InstEmit.Sri_V, typeof(OpCodeSimdShImm)); + SetA64("0110111101xxxxxx010001xxxxxxxxxx", InstName.Sri_V, InstEmit.Sri_V, typeof(OpCodeSimdShImm)); SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstName.Srshl_V, InstEmit.Srshl_V, typeof(OpCodeSimdReg)); SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_S, InstEmit.Srshr_S, typeof(OpCodeSimdShImm)); SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstName.Srshr_V, InstEmit.Srshr_V, typeof(OpCodeSimdShImm)); diff --git a/ARMeilleure/Instructions/InstEmitSimdShift.cs b/ARMeilleure/Instructions/InstEmitSimdShift.cs index 1aae491dfd..17f43c812c 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift.cs @@ -22,6 +22,11 @@ namespace ARMeilleure.Instructions 13L << 56 | 12L << 48 | 09L << 40 | 08L << 32 | 05L << 24 | 04L << 16 | 01L << 8 | 00L << 0, 11L << 56 | 10L << 48 | 09L << 40 | 08L << 32 | 03L << 24 | 02L << 16 | 01L << 8 | 00L << 0 }; + + private static readonly long[] _masks_SliSri = new long[] // Replication masks. + { + 0x0101010101010101L, 0x0001000100010001L, 0x0000000100000001L, 0x0000000000000001L + }; #endregion public static void Rshrn_V(ArmEmitterContext context) @@ -66,7 +71,7 @@ namespace ARMeilleure.Instructions res = context.AddIntrinsic(movInst, dLow, res); - context.Copy(GetVec(op.Rd), res); + context.Copy(d, res); } else { @@ -106,7 +111,7 @@ namespace ARMeilleure.Instructions } else { - EmitVectorUnaryOpZx(context, (op1) => context.ShiftLeft(op1, Const(shift))); + EmitVectorUnaryOpZx(context, (op1) => context.ShiftLeft(op1, Const(shift))); } } @@ -149,8 +154,6 @@ namespace ARMeilleure.Instructions int shift = GetImmShr(op); - long roundConst = 1L << (shift - 1); - Operand d = GetVec(op.Rd); Operand n = GetVec(op.Rn); @@ -170,7 +173,7 @@ namespace ARMeilleure.Instructions res = context.AddIntrinsic(movInst, dLow, res); - context.Copy(GetVec(op.Rd), res); + context.Copy(d, res); } else { @@ -178,34 +181,14 @@ namespace ARMeilleure.Instructions } } + public static void Sli_S(ArmEmitterContext context) + { + EmitSli(context, scalar: true); + } + public static void Sli_V(ArmEmitterContext context) { - OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp; - - Operand res = context.VectorZero(); - - int elems = op.GetBytesCount() >> op.Size; - - int shift = GetImmShl(op); - - ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0; - - for (int index = 0; index < elems; index++) - { - Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); - - Operand neShifted = context.ShiftLeft(ne, Const(shift)); - - Operand de = EmitVectorExtractZx(context, op.Rd, index, op.Size); - - Operand deMasked = context.BitwiseAnd(de, Const(mask)); - - Operand e = context.BitwiseOr(neShifted, deMasked); - - res = EmitVectorInsert(context, res, e, index, op.Size); - } - - context.Copy(GetVec(op.Rd), res); + EmitSli(context, scalar: false); } public static void Sqrshl_V(ArmEmitterContext context) @@ -290,6 +273,16 @@ namespace ARMeilleure.Instructions EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx); } + public static void Sri_S(ArmEmitterContext context) + { + EmitSri(context, scalar: true); + } + + public static void Sri_V(ArmEmitterContext context) + { + EmitSri(context, scalar: false); + } + public static void Srshl_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -395,7 +388,7 @@ namespace ARMeilleure.Instructions res = context.VectorZeroUpper64(res); } - context.Copy(GetVec(op.Rd), res); + context.Copy(d, res); } else { @@ -690,7 +683,7 @@ namespace ARMeilleure.Instructions res = context.VectorZeroUpper64(res); } - context.Copy(GetVec(op.Rd), res); + context.Copy(d, res); } else { @@ -1053,5 +1046,116 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } + + private static void EmitSli(ArmEmitterContext context, bool scalar) + { + OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp; + + int shift = GetImmShl(op); + + ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0UL; + + if (Optimizations.UseSse2 && op.Size > 0) + { + Operand d = GetVec(op.Rd); + Operand n = GetVec(op.Rn); + + Intrinsic sllInst = X86PsllInstruction[op.Size]; + + Operand nShifted = context.AddIntrinsic(sllInst, n, Const(shift)); + + Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]); + + Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask); + + Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked); + + if ((op.RegisterSize == RegisterSize.Simd64) || scalar) + { + res = context.VectorZeroUpper64(res); + } + + context.Copy(d, res); + } + else + { + Operand res = context.VectorZero(); + + int elems = !scalar ? op.GetBytesCount() >> op.Size : 1; + + for (int index = 0; index < elems; index++) + { + Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); + + Operand neShifted = context.ShiftLeft(ne, Const(shift)); + + Operand de = EmitVectorExtractZx(context, op.Rd, index, op.Size); + + Operand deMasked = context.BitwiseAnd(de, Const(mask)); + + Operand e = context.BitwiseOr(neShifted, deMasked); + + res = EmitVectorInsert(context, res, e, index, op.Size); + } + + context.Copy(GetVec(op.Rd), res); + } + } + + private static void EmitSri(ArmEmitterContext context, bool scalar) + { + OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp; + + int shift = GetImmShr(op); + int eSize = 8 << op.Size; + + ulong mask = (ulong.MaxValue << (eSize - shift)) & (ulong.MaxValue >> (64 - eSize)); + + if (Optimizations.UseSse2 && op.Size > 0) + { + Operand d = GetVec(op.Rd); + Operand n = GetVec(op.Rn); + + Intrinsic srlInst = X86PsrlInstruction[op.Size]; + + Operand nShifted = context.AddIntrinsic(srlInst, n, Const(shift)); + + Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]); + + Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask); + + Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked); + + if ((op.RegisterSize == RegisterSize.Simd64) || scalar) + { + res = context.VectorZeroUpper64(res); + } + + context.Copy(d, res); + } + else + { + Operand res = context.VectorZero(); + + int elems = !scalar ? op.GetBytesCount() >> op.Size : 1; + + for (int index = 0; index < elems; index++) + { + Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); + + Operand neShifted = shift != 64 ? context.ShiftRightUI(ne, Const(shift)) : Const(0UL); + + Operand de = EmitVectorExtractZx(context, op.Rd, index, op.Size); + + Operand deMasked = context.BitwiseAnd(de, Const(mask)); + + Operand e = context.BitwiseOr(neShifted, deMasked); + + res = EmitVectorInsert(context, res, e, index, op.Size); + } + + context.Copy(GetVec(op.Rd), res); + } + } } } diff --git a/ARMeilleure/Instructions/InstName.cs b/ARMeilleure/Instructions/InstName.cs index e03ab6166a..c81484a6f4 100644 --- a/ARMeilleure/Instructions/InstName.cs +++ b/ARMeilleure/Instructions/InstName.cs @@ -313,6 +313,7 @@ namespace ARMeilleure.Instructions Shll_V, Shrn_V, Shsub_V, + Sli_S, Sli_V, Smax_V, Smaxp_V, @@ -354,6 +355,8 @@ namespace ARMeilleure.Instructions Sqxtun_S, Sqxtun_V, Srhadd_V, + Sri_S, + Sri_V, Srshl_V, Srshr_S, Srshr_V, diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs b/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs index fbbc9f9fbe..0f1b0dac25 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdShImm.cs @@ -218,7 +218,7 @@ namespace Ryujinx.Tests.Cpu return new uint[] { 0x5F405400u, // SHL D0, D0, #0 - //0x7F405400u // SLI D0, D0, #0 + 0x7F405400u // SLI D0, D0, #0 }; } @@ -285,10 +285,11 @@ namespace Ryujinx.Tests.Cpu }; } - private static uint[] _ShrImm_S_D_() + private static uint[] _ShrImm_Sri_S_D_() { return new uint[] { + 0x7F404400u, // SRI D0, D0, #64 0x5F402400u, // SRSHR D0, D0, #64 0x5F403400u, // SRSRA D0, D0, #64 0x5F400400u, // SSHR D0, D0, #64 @@ -300,10 +301,11 @@ namespace Ryujinx.Tests.Cpu }; } - private static uint[] _ShrImm_V_8B_16B_() + private static uint[] _ShrImm_Sri_V_8B_16B_() { return new uint[] { + 0x2F084400u, // SRI V0.8B, V0.8B, #8 0x0F082400u, // SRSHR V0.8B, V0.8B, #8 0x0F083400u, // SRSRA V0.8B, V0.8B, #8 0x0F080400u, // SSHR V0.8B, V0.8B, #8 @@ -315,10 +317,11 @@ namespace Ryujinx.Tests.Cpu }; } - private static uint[] _ShrImm_V_4H_8H_() + private static uint[] _ShrImm_Sri_V_4H_8H_() { return new uint[] { + 0x2F104400u, // SRI V0.4H, V0.4H, #16 0x0F102400u, // SRSHR V0.4H, V0.4H, #16 0x0F103400u, // SRSRA V0.4H, V0.4H, #16 0x0F100400u, // SSHR V0.4H, V0.4H, #16 @@ -330,10 +333,11 @@ namespace Ryujinx.Tests.Cpu }; } - private static uint[] _ShrImm_V_2S_4S_() + private static uint[] _ShrImm_Sri_V_2S_4S_() { return new uint[] { + 0x2F204400u, // SRI V0.2S, V0.2S, #32 0x0F202400u, // SRSHR V0.2S, V0.2S, #32 0x0F203400u, // SRSRA V0.2S, V0.2S, #32 0x0F200400u, // SSHR V0.2S, V0.2S, #32 @@ -345,10 +349,11 @@ namespace Ryujinx.Tests.Cpu }; } - private static uint[] _ShrImm_V_2D_() + private static uint[] _ShrImm_Sri_V_2D_() { return new uint[] { + 0x6F404400u, // SRI V0.2D, V0.2D, #64 0x4F402400u, // SRSHR V0.2D, V0.2D, #64 0x4F403400u, // SRSRA V0.2D, V0.2D, #64 0x4F400400u, // SSHR V0.2D, V0.2D, #64 @@ -743,12 +748,12 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise] - public void ShrImm_S_D([ValueSource("_ShrImm_S_D_")] uint opcodes, - [Values(0u)] uint rd, - [Values(1u, 0u)] uint rn, - [ValueSource("_1D_")] [Random(RndCnt)] ulong z, - [ValueSource("_1D_")] [Random(RndCnt)] ulong a, - [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift) + public void ShrImm_Sri_S_D([ValueSource("_ShrImm_Sri_S_D_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource("_1D_")] [Random(RndCnt)] ulong z, + [ValueSource("_1D_")] [Random(RndCnt)] ulong a, + [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift) { uint immHb = (128 - shift) & 0x7F; @@ -764,13 +769,13 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise] - public void ShrImm_V_8B_16B([ValueSource("_ShrImm_V_8B_16B_")] uint opcodes, - [Values(0u)] uint rd, - [Values(1u, 0u)] uint rn, - [ValueSource("_8B_")] [Random(RndCnt)] ulong z, - [ValueSource("_8B_")] [Random(RndCnt)] ulong a, - [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift, - [Values(0b0u, 0b1u)] uint q) // <8B, 16B> + public void ShrImm_Sri_V_8B_16B([ValueSource("_ShrImm_Sri_V_8B_16B_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource("_8B_")] [Random(RndCnt)] ulong z, + [ValueSource("_8B_")] [Random(RndCnt)] ulong a, + [Values(1u, 8u)] [Random(2u, 7u, RndCntShift)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <8B, 16B> { uint immHb = (16 - shift) & 0x7F; @@ -787,13 +792,13 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise] - public void ShrImm_V_4H_8H([ValueSource("_ShrImm_V_4H_8H_")] uint opcodes, - [Values(0u)] uint rd, - [Values(1u, 0u)] uint rn, - [ValueSource("_4H_")] [Random(RndCnt)] ulong z, - [ValueSource("_4H_")] [Random(RndCnt)] ulong a, - [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift, - [Values(0b0u, 0b1u)] uint q) // <4H, 8H> + public void ShrImm_Sri_V_4H_8H([ValueSource("_ShrImm_Sri_V_4H_8H_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource("_4H_")] [Random(RndCnt)] ulong z, + [ValueSource("_4H_")] [Random(RndCnt)] ulong a, + [Values(1u, 16u)] [Random(2u, 15u, RndCntShift)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <4H, 8H> { uint immHb = (32 - shift) & 0x7F; @@ -810,13 +815,13 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise] - public void ShrImm_V_2S_4S([ValueSource("_ShrImm_V_2S_4S_")] uint opcodes, - [Values(0u)] uint rd, - [Values(1u, 0u)] uint rn, - [ValueSource("_2S_")] [Random(RndCnt)] ulong z, - [ValueSource("_2S_")] [Random(RndCnt)] ulong a, - [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift, - [Values(0b0u, 0b1u)] uint q) // <2S, 4S> + public void ShrImm_Sri_V_2S_4S([ValueSource("_ShrImm_Sri_V_2S_4S_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource("_2S_")] [Random(RndCnt)] ulong z, + [ValueSource("_2S_")] [Random(RndCnt)] ulong a, + [Values(1u, 32u)] [Random(2u, 31u, RndCntShift)] uint shift, + [Values(0b0u, 0b1u)] uint q) // <2S, 4S> { uint immHb = (64 - shift) & 0x7F; @@ -833,12 +838,12 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise] - public void ShrImm_V_2D([ValueSource("_ShrImm_V_2D_")] uint opcodes, - [Values(0u)] uint rd, - [Values(1u, 0u)] uint rn, - [ValueSource("_1D_")] [Random(RndCnt)] ulong z, - [ValueSource("_1D_")] [Random(RndCnt)] ulong a, - [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift) + public void ShrImm_Sri_V_2D([ValueSource("_ShrImm_Sri_V_2D_")] uint opcodes, + [Values(0u)] uint rd, + [Values(1u, 0u)] uint rn, + [ValueSource("_1D_")] [Random(RndCnt)] ulong z, + [ValueSource("_1D_")] [Random(RndCnt)] ulong a, + [Values(1u, 64u)] [Random(2u, 63u, RndCntShift)] uint shift) { uint immHb = (128 - shift) & 0x7F;